@luomus/laji-form 15.1.13 → 15.1.14

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.
@@ -102,6 +102,7 @@ export declare function MediaArrayField<LFC extends Constructor<React.Component<
102
102
  }) => void;
103
103
  getMetadataPromise: () => Promise<MediaMetadataSchema>;
104
104
  getMaxFileSizeAsString: () => string;
105
+ getAllowedMediaFormatsTranslationKey: () => "AllowedFileFormat" | "AllowedFileFormats";
105
106
  getAllowedMediaFormatsAsString: () => string;
106
107
  context: any;
107
108
  setState<K extends keyof MediaArrayState>(state: MediaArrayState | ((prevState: Readonly<MediaArrayState>, props: Readonly<FieldProps>) => MediaArrayState | Pick<MediaArrayState, K> | null) | Pick<MediaArrayState, K> | null, callback?: (() => void) | undefined): void;
@@ -421,6 +421,9 @@ function MediaArrayField(ComposedComponent) {
421
421
  let maxSize = this.MAX_FILE_SIZE.toString().substring(0, this.MAX_FILE_SIZE.toString().length - 6);
422
422
  return maxSize + " " + `${this.props.formContext.translations.Mb}`;
423
423
  };
424
+ this.getAllowedMediaFormatsTranslationKey = () => {
425
+ return this.ALLOWED_FILE_TYPES.length === 1 ? "AllowedFileFormat" : "AllowedFileFormats";
426
+ };
424
427
  this.getAllowedMediaFormatsAsString = () => {
425
428
  let formats = "";
426
429
  for (let i = 0; i < this.ALLOWED_FILE_TYPES.length; i++) {
@@ -492,7 +495,7 @@ function MediaArrayField(ComposedComponent) {
492
495
  translations.DropOrSelectFiles,
493
496
  ". "),
494
497
  React.createElement("span", null,
495
- translations.AllowedFileFormats,
498
+ translations[this.getAllowedMediaFormatsTranslationKey()],
496
499
  " ",
497
500
  this.getAllowedMediaFormatsAsString(),
498
501
  " ",
@@ -561,7 +564,7 @@ function MediaArrayField(ComposedComponent) {
561
564
  return body;
562
565
  }, new FormData());
563
566
  if (noValidData && invalidFile) {
564
- fail("AllowedFileFormats", this.getAllowedMediaFormatsAsString() + ".");
567
+ fail(this.getAllowedMediaFormatsTranslationKey(), this.getAllowedMediaFormatsAsString() + ".");
565
568
  return;
566
569
  }
567
570
  else if (noValidData && fileTooLarge) {
@@ -35,6 +35,7 @@ const NestField_1 = require("./NestField");
35
35
  const ArrayFieldTemplate_1 = require("../templates/ArrayFieldTemplate");
36
36
  const ArrayField_1 = require("./ArrayField");
37
37
  const utils_3 = require("@rjsf/utils");
38
+ const utils_4 = require("@luomus/laji-map/lib/utils");
38
39
  function parseGeometries(geometry) {
39
40
  return ((geometry && geometry.type === "GeometryCollection") ? geometry.geometries : [geometry])
40
41
  .filter(geometry => geometry)
@@ -594,6 +595,7 @@ let LineTransectMapArrayField = class LineTransectMapArrayField extends React.Co
594
595
  });
595
596
  const afterState = () => {
596
597
  if (formDataChanged) {
598
+ formData = syncLineTransectStartEnd(formData);
597
599
  this.props.onChange(addOrDelete ? ArrayField_1.onArrayFieldChange(formData, this.props) : formData);
598
600
  }
599
601
  if ("activeIdx" in state) {
@@ -635,6 +637,7 @@ let LineTransectMapArrayField = class LineTransectMapArrayField extends React.Co
635
637
  });
636
638
  };
637
639
  this.state = { showLTTools: false };
640
+ this.props.onChange(syncLineTransectStartEnd(this.props.formData));
638
641
  }
639
642
  getOptions() {
640
643
  const { formData, disabled, readonly } = this.props;
@@ -1781,3 +1784,20 @@ const getFeatureStyleWithHighlight = style => {
1781
1784
  return Object.assign(Object.assign({}, style), { color, fillOpacity: saneOpacityRange(style.fillOpacity || 0.4 + 0.4) });
1782
1785
  };
1783
1786
  exports.getFeatureStyleWithHighlight = getFeatureStyleWithHighlight;
1787
+ const syncLineTransectStartEnd = (formData) => {
1788
+ const lineTransectFeature = Object.keys((formData || [])[0].geometry || {}).length
1789
+ ? { type: "Feature", properties: {}, geometry: { type: "MultiLineString", coordinates: formData.map(item => item.geometry.coordinates) } }
1790
+ : undefined;
1791
+ if (lineTransectFeature) {
1792
+ return formData.map((item, idx) => {
1793
+ const [start, end] = utils_4.getLineTransectStartEndDistancesForIdx(lineTransectFeature, idx, 10);
1794
+ if (!item.gatheringFact) {
1795
+ item.gatheringFact = {};
1796
+ }
1797
+ item.gatheringFact.lineTransectSegmentMetersStart = start;
1798
+ item.gatheringFact.lineTransectSegmentMetersEnd = end;
1799
+ return Object.assign(Object.assign({}, item), { gatheringFact: Object.assign(Object.assign({}, (item.gatheringFact || {})), { lineTransectSegmentMetersStart: start, lineTransectSegmentMetersEnd: end }) });
1800
+ });
1801
+ }
1802
+ return formData;
1803
+ };
@@ -29,8 +29,7 @@ const ArrayField_1 = require("./ArrayField");
29
29
  const Context_1 = require("../../Context");
30
30
  const ReactContext_1 = require("../../ReactContext");
31
31
  const BaseComponent_1 = require("../BaseComponent");
32
- const utils_3 = require("@luomus/laji-map/lib/utils");
33
- const utils_4 = require("@rjsf/utils");
32
+ const utils_3 = require("@rjsf/utils");
34
33
  const memoize = require("memoizee");
35
34
  const ArrayField_2 = require("./ArrayField");
36
35
  const popupMappers = {
@@ -504,8 +503,8 @@ let UncontrolledArrayFieldTemplate = class UncontrolledArrayFieldTemplate extend
504
503
  const that = this.props.formContext.this;
505
504
  const arrayTemplateFieldProps = this.props;
506
505
  const activeIdx = that.state.activeIdx;
507
- const TitleFieldTemplate = utils_4.getTemplate("TitleFieldTemplate", this.props.registry, utils_1.getUiOptions(this.props.uiSchema));
508
- const DescriptionFieldTemplate = utils_4.getTemplate("DescriptionFieldTemplate", this.props.registry, utils_1.getUiOptions(this.props.uiSchema));
506
+ const TitleFieldTemplate = utils_3.getTemplate("TitleFieldTemplate", this.props.registry, utils_1.getUiOptions(this.props.uiSchema));
507
+ const DescriptionFieldTemplate = utils_3.getTemplate("DescriptionFieldTemplate", this.props.registry, utils_1.getUiOptions(this.props.uiSchema));
509
508
  const { Label } = this.props.formContext;
510
509
  const Title = utils_1.getUiOptions(that.props.uiSchema).renderTitleAsLabel ? Label : TitleFieldTemplate;
511
510
  const title = utils_1.getTitle(this.props, activeIdx);
@@ -700,8 +699,8 @@ let TableArrayFieldTemplate = class TableArrayFieldTemplate extends React.Compon
700
699
  return React.createElement(ArrayFieldTemplate_1.default, Object.assign({}, this.props));
701
700
  }
702
701
  const { schema, uiSchema = {}, formData = [], items, disabled, readonly } = this.props;
703
- const TitleFieldTemplate = utils_4.getTemplate("TitleFieldTemplate", this.props.registry, utils_1.getUiOptions(uiSchema));
704
- const DescriptionFieldTemplate = utils_4.getTemplate("DescriptionFieldTemplate", this.props.registry, utils_1.getUiOptions(uiSchema));
702
+ const TitleFieldTemplate = utils_3.getTemplate("TitleFieldTemplate", this.props.registry, utils_1.getUiOptions(uiSchema));
703
+ const DescriptionFieldTemplate = utils_3.getTemplate("DescriptionFieldTemplate", this.props.registry, utils_1.getUiOptions(uiSchema));
705
704
  const { renderTitleAsLabel, formatters = {}, shownColumns = [], removable = true } = utils_1.getUiOptions(uiSchema);
706
705
  const { Label } = this.props.formContext;
707
706
  const Title = renderTitleAsLabel ? Label : TitleFieldTemplate;
@@ -874,12 +873,8 @@ const headerFormatters = {
874
873
  },
875
874
  lineTransect: {
876
875
  component: (props) => {
877
- let start, end;
878
- const lineTransectFeature = Object.keys((props.that.props.formData || [])[0].geometry || {}).length
879
- ? { type: "Feature", properties: {}, geometry: { type: "MultiLineString", coordinates: props.that.props.formData.map(item => item.geometry.coordinates) } }
880
- : undefined;
881
- if (lineTransectFeature)
882
- [start, end] = utils_3.getLineTransectStartEndDistancesForIdx(lineTransectFeature, props.idx, 10);
876
+ const item = props.that.props.formData[props.idx];
877
+ const [start, end] = [item.gatheringFact.lineTransectSegmentMetersStart, item.gatheringFact.lineTransectSegmentMetersEnd];
883
878
  return props.idx !== undefined && end ? React.createElement("span", { className: "text-muted" }, `${start}-${end}m`) : null;
884
879
  }
885
880
  },
@@ -4,6 +4,12 @@ export default class TagArrayField extends React.Component<any, any, any> {
4
4
  "ui:options": PropTypes.Requireable<PropTypes.InferProps<{
5
5
  separatorKeys: PropTypes.Requireable<(string | null | undefined)[]>;
6
6
  showDeleteButton: PropTypes.Requireable<boolean>;
7
+ showAsLink: PropTypes.Requireable<boolean>;
8
+ linkPrefix: PropTypes.Requireable<string>;
9
+ replacements: PropTypes.Requireable<(PropTypes.InferProps<{
10
+ searchRegexp: PropTypes.Validator<string>;
11
+ replaceValue: PropTypes.Validator<string>;
12
+ }> | null | undefined)[]>;
7
13
  }>>;
8
14
  }>>;
9
15
  schema: PropTypes.Validator<PropTypes.InferProps<{
@@ -31,7 +37,7 @@ export class TagInputComponent extends React.Component<any, any, any> {
31
37
  onClick: () => void;
32
38
  onInputChange: (e: any) => void;
33
39
  onTagClick: ((idx: any) => (e: any) => void) & memoize.Memoized<(idx: any) => (e: any) => void>;
34
- getTrimmedValue(): any;
40
+ processValue(value: any): any;
35
41
  }
36
42
  import * as React from "react";
37
43
  import * as PropTypes from "prop-types";
@@ -25,7 +25,13 @@ TagArrayField.propTypes = {
25
25
  uiSchema: PropTypes.shape({
26
26
  "ui:options": PropTypes.shape({
27
27
  separatorKeys: PropTypes.arrayOf(PropTypes.string),
28
- showDeleteButton: PropTypes.bool
28
+ showDeleteButton: PropTypes.bool,
29
+ showAsLink: PropTypes.bool,
30
+ linkPrefix: PropTypes.string,
31
+ replacements: PropTypes.arrayOf(PropTypes.shape({
32
+ searchRegexp: PropTypes.string.isRequired,
33
+ replaceValue: PropTypes.string.isRequired
34
+ }))
29
35
  })
30
36
  }),
31
37
  schema: PropTypes.shape({
@@ -48,7 +54,7 @@ class TagInputComponent extends React.Component {
48
54
  return separatorKeys;
49
55
  };
50
56
  this.onKeyDown = (e) => {
51
- const value = this.getTrimmedValue();
57
+ const value = this.processValue(this.state.value);
52
58
  const { tags = [] } = this.props;
53
59
  const separatorKeys = this.getSeparatorKeys(this.props.uiSchema);
54
60
  if (separatorKeys.includes(e.key) && !utils_1.isEmptyString(value)) {
@@ -74,7 +80,7 @@ class TagInputComponent extends React.Component {
74
80
  this.onBlur = (e) => {
75
81
  this.setState({ focused: false });
76
82
  utils_1.triggerParentComponent("onBlur", e, this.props);
77
- const value = this.getTrimmedValue();
83
+ const value = this.processValue(this.state.value);
78
84
  if (!utils_1.isEmptyString(value)) {
79
85
  this.props.onChange([...(this.props.tags || []), value], "blur");
80
86
  }
@@ -90,7 +96,7 @@ class TagInputComponent extends React.Component {
90
96
  onInputChange && e.persist();
91
97
  const { target: { value } } = e;
92
98
  const separatorKeys = this.getSeparatorKeys(this.props.uiSchema);
93
- const splitted = separatorKeys.reduce((splitted, separator) => splitted.reduce((_splitted, i) => ([..._splitted, ...i.split(separator)]), []), [value]).map(s => s.trim()).filter(s => !utils_1.isEmptyString(s));
99
+ const splitted = separatorKeys.reduce((splitted, separator) => splitted.reduce((_splitted, i) => ([..._splitted, ...i.split(separator)]), []), [value]).map(s => this.processValue(s)).filter(s => !utils_1.isEmptyString(s));
94
100
  this.setState({ value }, () => {
95
101
  onInputChange && this.props.onInputChange(e);
96
102
  if (splitted.length > 1) {
@@ -107,9 +113,16 @@ class TagInputComponent extends React.Component {
107
113
  UNSAFE_componentWillReceiveProps(props) {
108
114
  this.setState(this.getStateFromProps(props));
109
115
  }
110
- getTrimmedValue() {
111
- const { value } = this.state;
112
- return value === null || value === void 0 ? void 0 : value.trim();
116
+ processValue(value) {
117
+ if (!value) {
118
+ return value;
119
+ }
120
+ value = value.trim();
121
+ const { replacements = [] } = utils_1.getUiOptions(this.props.uiSchema);
122
+ replacements.forEach(replacement => {
123
+ value = value.replace(new RegExp(replacement.searchRegexp), replacement.replaceValue);
124
+ });
125
+ return value;
113
126
  }
114
127
  render() {
115
128
  let { tags = [], InputComponent, readonly, disabled, uiSchema } = this.props;
package/lib/themes/bs5.js CHANGED
@@ -62,6 +62,12 @@ _Dropdown.Toggle = React.forwardRef((_a, ref) => {
62
62
  var { variant } = _a, props = __rest(_a, ["variant"]);
63
63
  return (React.createElement(react_bootstrap_5_1.Dropdown.Toggle, Object.assign({ variant: mapVariant(variant) }, props, { ref: ref })));
64
64
  });
65
+ const _Popover = React.forwardRef((_a, ref) => {
66
+ var { children } = _a, props = __rest(_a, ["children"]);
67
+ return (React.createElement(react_bootstrap_5_1.Popover, Object.assign({}, props, { ref: ref }),
68
+ props.title ? React.createElement(react_bootstrap_5_1.Popover.Header, null, props.title) : null,
69
+ React.createElement(react_bootstrap_5_1.Popover.Body, null, children)));
70
+ });
65
71
  const theme = {
66
72
  Panel,
67
73
  Table: react_bootstrap_5_1.Table,
@@ -74,7 +80,7 @@ const theme = {
74
80
  ButtonToolbar: react_bootstrap_5_1.ButtonToolbar,
75
81
  Overlay: React.forwardRef((props, ref) => React.createElement(react_bootstrap_5_1.Overlay, Object.assign({}, props, { ref: ref }))),
76
82
  OverlayTrigger: (props) => React.createElement(react_bootstrap_5_1.OverlayTrigger, Object.assign({}, props)),
77
- Popover: react_bootstrap_5_1.Popover,
83
+ Popover: _Popover,
78
84
  Tooltip: react_bootstrap_5_1.Tooltip,
79
85
  Glyphicon,
80
86
  Modal: _Modal,
@@ -225,29 +225,34 @@
225
225
  "sv": "Mb"
226
226
  },
227
227
  "allowedFileFormats": {
228
- "fi": "Sallitut kuvaformaatit ovat",
229
- "en": "Allowed image formats are",
230
- "sv": "Tillåtna filformat för bilderna är"
228
+ "fi": "Sallitut tiedostoformaatit ovat",
229
+ "en": "Allowed file formats are",
230
+ "sv": "Tillåtna filformat är"
231
+ },
232
+ "allowedFileFormat": {
233
+ "fi": "Sallittu tiedostoformaatti on",
234
+ "en": "Allowed file format is",
235
+ "sv": "Tillåtet filformat är"
231
236
  },
232
237
  "allowedFileSize": {
233
- "fi": "Kuvan suurin sallittu koko on",
238
+ "fi": "Tiedoston suurin sallittu koko on",
234
239
  "en": "The maximum allowed file size is",
235
- "sv": "Den största tillåtna storleken på en bild är"
240
+ "sv": "Den största tillåtna filstorleken är"
236
241
  },
237
242
  "invalidFile": {
238
- "fi": "Kuvatiedosto oli virheellinen.",
243
+ "fi": "Tiedosto oli virheellinen.",
239
244
  "en": "The file was invalid.",
240
245
  "sv": "Filen var ogiltig."
241
246
  },
242
247
  "insufficientSpace": {
243
- "fi": "Kuvapalvelin ei pysty käsittelemään latauspyyntöä riittämättömän levytilan vuoksi.",
244
- "en": "The image server can't process the upload request because of insufficient space.",
245
- "sv": "Bildservern kan inte bearbeta uppladdnings begäran på grund av otillräckligt utrymme."
248
+ "fi": "Mediapalvelin ei pysty käsittelemään latauspyyntöä riittämättömän levytilan vuoksi.",
249
+ "en": "The media server can't process the upload request because of insufficient space.",
250
+ "sv": "Mediaservern kan inte bearbeta uppladdnings begäran på grund av otillräckligt utrymme."
246
251
  },
247
252
  "filesLengthDiffer": {
248
- "fi": "Kaikki kuvat eivät tallentuneet. Tarkista kuvat.",
249
- "en": "All the images weren't saved. Please verify the images.",
250
- "sv": "Alla bilder sparades inte. Vänligen kontrollera bilderna."
253
+ "fi": "Kaikki tiedostot eivät tallentuneet. Tarkista tiedostot.",
254
+ "en": "All the files weren't saved. Please verify the files.",
255
+ "sv": "Alla filer sparades inte. Vänligen kontrollera filerna."
251
256
  },
252
257
  "error": {
253
258
  "fi": "Virhe",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luomus/laji-form",
3
- "version": "15.1.13",
3
+ "version": "15.1.14",
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",