@luomus/laji-form 15.1.65 → 15.1.67
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/laji-form.js +1 -1
- package/lib/ApiClient.d.ts +64 -21
- package/lib/ApiClient.js +172 -68
- package/lib/components/LajiForm.js +1 -1
- package/lib/components/components/DeleteButton.d.ts +1 -0
- package/lib/components/components/DeleteButton.js +6 -1
- package/lib/components/fields/AnnotationField.js +26 -22
- package/lib/components/fields/AudioArrayField.js +18 -5
- package/lib/components/fields/AutosuggestField.d.ts +2 -2
- package/lib/components/fields/AutosuggestField.js +4 -4
- package/lib/components/fields/EnumRangeArrayField.js +1 -1
- package/lib/components/fields/GeocoderField.js +2 -9
- package/lib/components/fields/ImageArrayField.d.ts +3 -2
- package/lib/components/fields/ImageArrayField.js +85 -113
- package/lib/components/fields/MapArrayField.js +13 -5
- package/lib/components/fields/MapField.d.ts +1 -1
- package/lib/components/fields/MapField.js +13 -5
- package/lib/components/fields/NamedPlaceChooserField/NamedPlaceChooser.d.ts +2 -1
- package/lib/components/fields/NamedPlaceChooserField/NamedPlaceChooserField.d.ts +9 -4
- package/lib/components/fields/NamedPlaceChooserField/NamedPlaceChooserField.js +52 -51
- package/lib/components/fields/NamedPlaceChooserField/Popup.d.ts +2 -1
- package/lib/components/fields/NamedPlaceSaverField.js +22 -18
- package/lib/components/fields/ScopeField.js +1 -1
- package/lib/components/fields/SingleActiveArrayField.js +2 -2
- package/lib/components/fields/SortArrayField.js +1 -1
- package/lib/components/fields/UnitCountShorthandField.js +1 -1
- package/lib/components/fields/UnitListShorthandArrayField.js +2 -2
- package/lib/components/fields/UnitShorthandField.js +4 -4
- package/lib/components/widgets/AutosuggestWidget.js +79 -66
- package/lib/components/widgets/InformalTaxonGroupChooserWidget.js +1 -1
- package/lib/components/widgets/InputWithDefaultValueButtonWidget.js +1 -2
- package/lib/validation.js +1 -1
- package/package.json +5 -3
|
@@ -99,7 +99,7 @@ export declare function MediaArrayField<LFC extends Constructor<React.Component<
|
|
|
99
99
|
processFile: (file: File) => Promise<ProcessedFile>;
|
|
100
100
|
onMediaMetadataUpdate: ({ formData }: {
|
|
101
101
|
formData: any;
|
|
102
|
-
}) => void
|
|
102
|
+
}) => Promise<void>;
|
|
103
103
|
getMetadataPromise: () => Promise<MediaMetadataSchema>;
|
|
104
104
|
getMaxFileSizeAsString: () => string;
|
|
105
105
|
getAllowedMediaFormatsTranslationKey: () => "AllowedFileFormat" | "AllowedFileFormats";
|
|
@@ -139,6 +139,7 @@ export declare function MediaArrayField<LFC extends Constructor<React.Component<
|
|
|
139
139
|
autoOpenMetadataModal: PropTypes.Requireable<boolean>;
|
|
140
140
|
sideEffects: PropTypes.Requireable<object>;
|
|
141
141
|
exifParsers: PropTypes.Requireable<(object | null | undefined)[]>;
|
|
142
|
+
metadataFormId: PropTypes.Requireable<string>;
|
|
142
143
|
}>>;
|
|
143
144
|
}>>;
|
|
144
145
|
schema: PropTypes.Validator<NonNullable<PropTypes.InferProps<{
|
|
@@ -169,7 +170,7 @@ export declare class Thumbnail extends React.PureComponent<ThumbnailProps, Thumb
|
|
|
169
170
|
componentDidMount(): void;
|
|
170
171
|
componentWillUnmount(): void;
|
|
171
172
|
UNSAFE_componentWillReceiveProps(props: ThumbnailProps): void;
|
|
172
|
-
updateURL: ({ id, apiClient, apiEndpoint }: ThumbnailProps) => void
|
|
173
|
+
updateURL: ({ id, apiClient, apiEndpoint }: ThumbnailProps) => Promise<void>;
|
|
173
174
|
render(): JSX.Element | null;
|
|
174
175
|
}
|
|
175
176
|
export {};
|
|
@@ -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)
|
|
@@ -162,7 +171,7 @@ function MediaArrayField(ComposedComponent) {
|
|
|
162
171
|
const item = this.props.formData[i];
|
|
163
172
|
this.setState({ metadataModalOpen: i });
|
|
164
173
|
this.fetching = item;
|
|
165
|
-
this.apiClient.
|
|
174
|
+
this.apiClient.get(`/${this.ENDPOINT}/{id}`, { path: { id: item } }).then((response) => {
|
|
166
175
|
if (response.id !== this.fetching)
|
|
167
176
|
return;
|
|
168
177
|
this._context.metadatas[item] = response;
|
|
@@ -172,10 +181,11 @@ function MediaArrayField(ComposedComponent) {
|
|
|
172
181
|
this.onMediaRmClick = (i) => () => {
|
|
173
182
|
const id = this.props.formData[i];
|
|
174
183
|
this.props.onChange((0, immutability_helper_1.default)(this.props.formData, { $splice: [[i, 1]] }));
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
184
|
+
try {
|
|
185
|
+
this.apiClient.delete(`/${this.ENDPOINT}/{id}`, { path: { id } });
|
|
186
|
+
}
|
|
187
|
+
catch (e) {
|
|
188
|
+
}
|
|
179
189
|
};
|
|
180
190
|
this.hideMetadataModal = () => this.setState({ metadataModalOpen: false, metadataSaveSuccess: undefined });
|
|
181
191
|
this.onMetadataFormChange = (formData) => this.setState({ modalMetadata: formData });
|
|
@@ -184,7 +194,8 @@ function MediaArrayField(ComposedComponent) {
|
|
|
184
194
|
const { lang, translations } = this.props.registry.formContext;
|
|
185
195
|
const metadataForm = this.state.metadataForm || {};
|
|
186
196
|
if (typeof metadataModalOpen === "number" && !this.state.metadataForm) {
|
|
187
|
-
|
|
197
|
+
const { metadataFormId = this.METADATA_FORM_ID } = (0, utils_1.getUiOptions)(this.props.uiSchema);
|
|
198
|
+
this.apiClient.get("/forms/{id}", { path: { id: metadataFormId }, query: { lang, format: "schema" } })
|
|
188
199
|
.then(metadataForm => {
|
|
189
200
|
if (this.mounted) {
|
|
190
201
|
this.setState({ metadataForm });
|
|
@@ -421,16 +432,10 @@ function MediaArrayField(ComposedComponent) {
|
|
|
421
432
|
reader.readAsDataURL(file);
|
|
422
433
|
});
|
|
423
434
|
};
|
|
424
|
-
this.onMediaMetadataUpdate = ({ formData })
|
|
435
|
+
this.onMediaMetadataUpdate = (_a) => __awaiter(this, [_a], void 0, function* ({ formData }) {
|
|
425
436
|
this.props.formContext.services.blocker.push();
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
headers: {
|
|
429
|
-
"accept": "application/json",
|
|
430
|
-
"content-type": "application/json"
|
|
431
|
-
},
|
|
432
|
-
body: JSON.stringify(formData)
|
|
433
|
-
}).then(() => {
|
|
437
|
+
try {
|
|
438
|
+
yield this.apiClient.put(`/${this.ENDPOINT}/{id}`, { path: { id: formData.id } }, formData);
|
|
434
439
|
this.props.formContext.services.blocker.pop();
|
|
435
440
|
const notify = () => this.props.formContext.notifier.success(this.props.formContext.translations.SaveSuccess);
|
|
436
441
|
if (this.mounted) {
|
|
@@ -439,11 +444,12 @@ function MediaArrayField(ComposedComponent) {
|
|
|
439
444
|
else {
|
|
440
445
|
notify();
|
|
441
446
|
}
|
|
442
|
-
}
|
|
447
|
+
}
|
|
448
|
+
catch (e) {
|
|
443
449
|
this.props.formContext.services.blocker.pop();
|
|
444
450
|
this.mounted && this.setState({ metadataSaveSuccess: false });
|
|
445
|
-
}
|
|
446
|
-
};
|
|
451
|
+
}
|
|
452
|
+
});
|
|
447
453
|
this.getMetadataPromise = () => {
|
|
448
454
|
let mediaMetadata = this.props.formContext.mediaMetadata
|
|
449
455
|
|| { intellectualRights: "MZ.intellectualRightsARR" };
|
|
@@ -451,7 +457,7 @@ function MediaArrayField(ComposedComponent) {
|
|
|
451
457
|
return ("capturerVerbatim" in mediaMetadata)
|
|
452
458
|
? Promise.resolve(Object.assign(Object.assign({}, mediaMetadata), { capturerVerbatim: [mediaMetadata.capturerVerbatim] }))
|
|
453
459
|
: MACode
|
|
454
|
-
? this.apiClient.
|
|
460
|
+
? this.apiClient.get("/person/by-id/{personId}", { path: { personId: MACode } }).then(({ fullName = MACode }) => (Object.assign(Object.assign({ capturerVerbatim: Array.isArray(fullName) ? fullName : [fullName] }, mediaMetadata), { intellectualOwner: fullName }))).catch(() => Promise.resolve(mediaMetadata))
|
|
455
461
|
: mediaMetadata;
|
|
456
462
|
};
|
|
457
463
|
this.getMaxFileSizeAsString = () => {
|
|
@@ -566,105 +572,67 @@ function MediaArrayField(ComposedComponent) {
|
|
|
566
572
|
this.renderMediaAddModal()))));
|
|
567
573
|
}
|
|
568
574
|
saveMedias(files) {
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
.
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
mediaUuid++;
|
|
586
|
-
this._context.tmpMedias[containerId][mediaUuid] = f.dataURL;
|
|
587
|
-
return mediaUuid;
|
|
588
|
-
});
|
|
589
|
-
this.mounted && this.setState({ tmpMedias: [...(this.state.tmpMedias || []), ...tmpMedias] });
|
|
590
|
-
const formDataBody = files.reduce((body, file) => {
|
|
591
|
-
if (!this.ALLOWED_FILE_TYPES.includes(file.type)) {
|
|
592
|
-
invalidFile = true;
|
|
575
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
576
|
+
const containerId = this.getContainerId();
|
|
577
|
+
let tmpMedias = [];
|
|
578
|
+
const fail = (translationKey, additionalInfo = "") => {
|
|
579
|
+
const translation = (Array.isArray(translationKey) ? translationKey : [translationKey])
|
|
580
|
+
.map((key) => this.props.formContext.translations[key])
|
|
581
|
+
.join(". ");
|
|
582
|
+
throw `${translation} ${additionalInfo}`;
|
|
583
|
+
};
|
|
584
|
+
try {
|
|
585
|
+
const processedFiles = yield this.processFiles(files);
|
|
586
|
+
let invalidFile = (files.length <= 0);
|
|
587
|
+
let fileTooLarge = false;
|
|
588
|
+
let noValidData = true;
|
|
589
|
+
if (!this._context.tmpMedias[containerId]) {
|
|
590
|
+
this._context.tmpMedias[containerId] = {};
|
|
593
591
|
}
|
|
594
|
-
|
|
595
|
-
|
|
592
|
+
tmpMedias = processedFiles.map(f => {
|
|
593
|
+
mediaUuid++;
|
|
594
|
+
this._context.tmpMedias[containerId][mediaUuid] = f.dataURL;
|
|
595
|
+
return mediaUuid;
|
|
596
|
+
});
|
|
597
|
+
this.mounted && this.setState({ tmpMedias: [...(this.state.tmpMedias || []), ...tmpMedias] });
|
|
598
|
+
const formData = files.reduce((body, file) => {
|
|
599
|
+
if (!this.ALLOWED_FILE_TYPES.includes(file.type)) {
|
|
600
|
+
invalidFile = true;
|
|
601
|
+
}
|
|
602
|
+
else if (file.size > this.MAX_FILE_SIZE) {
|
|
603
|
+
fileTooLarge = true;
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
body.append("data", file);
|
|
607
|
+
noValidData = false;
|
|
608
|
+
}
|
|
609
|
+
return body;
|
|
610
|
+
}, new FormData());
|
|
611
|
+
if (noValidData && invalidFile) {
|
|
612
|
+
fail(this.getAllowedMediaFormatsTranslationKey(), this.getAllowedMediaFormatsAsString() + ".");
|
|
613
|
+
return;
|
|
596
614
|
}
|
|
597
|
-
else {
|
|
598
|
-
|
|
599
|
-
|
|
615
|
+
else if (noValidData && fileTooLarge) {
|
|
616
|
+
fail("AllowedFileSize", this.getMaxFileSizeAsString() + ".");
|
|
617
|
+
return;
|
|
600
618
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
else if (noValidData && fileTooLarge) {
|
|
608
|
-
fail("AllowedFileSize", this.getMaxFileSizeAsString() + ".");
|
|
609
|
-
return;
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
return this.apiClient.fetchRaw(`/${this.ENDPOINT}`, undefined, {
|
|
613
|
-
method: "POST",
|
|
614
|
-
body: formDataBody
|
|
619
|
+
const tmpMediaEntities = yield this.apiClient.post(`/${this.ENDPOINT}`, undefined, formData);
|
|
620
|
+
const mediaMetadata = yield this.getMetadataPromise();
|
|
621
|
+
const mediaEntities = yield Promise.all(tmpMediaEntities.map((item) => this.apiClient.post(`/${this.ENDPOINT}/{id}`, { path: { id: item.id } }, mediaMetadata)));
|
|
622
|
+
const ids = mediaEntities.map((item) => item ? item.id : undefined).filter(item => item !== undefined);
|
|
623
|
+
tmpMedias.forEach(id => {
|
|
624
|
+
delete this._context.tmpMedias[containerId][id];
|
|
615
625
|
});
|
|
626
|
+
this.mounted && this.setState({ tmpMedias: this.state.tmpMedias.filter(id => !tmpMedias.includes(id)) });
|
|
627
|
+
return ids;
|
|
616
628
|
}
|
|
617
|
-
|
|
618
|
-
if (!response)
|
|
619
|
-
return;
|
|
620
|
-
if (response.status < 400) {
|
|
621
|
-
return response.json();
|
|
622
|
-
}
|
|
623
|
-
else if (response.status === 400) {
|
|
624
|
-
fail("InvalidFile");
|
|
625
|
-
}
|
|
626
|
-
else if (response.status === 503) {
|
|
627
|
-
fail("InsufficientSpace");
|
|
628
|
-
}
|
|
629
|
-
else {
|
|
630
|
-
fail(["SomethingWentWrong", "TryAgainLater"]);
|
|
631
|
-
}
|
|
632
|
-
}).then(response => {
|
|
633
|
-
if (!response)
|
|
634
|
-
return;
|
|
635
|
-
return this.getMetadataPromise().then(mediaMetadata => {
|
|
636
|
-
return Promise.all(response.map((item) => {
|
|
637
|
-
return this.apiClient.fetchRaw(`/${this.ENDPOINT}/${item.id}`, undefined, {
|
|
638
|
-
method: "POST",
|
|
639
|
-
headers: {
|
|
640
|
-
"accept": "application/json",
|
|
641
|
-
"content-type": "application/json"
|
|
642
|
-
},
|
|
643
|
-
body: JSON.stringify(mediaMetadata)
|
|
644
|
-
}).then(response => {
|
|
645
|
-
if (response.status < 400) {
|
|
646
|
-
return response.json();
|
|
647
|
-
}
|
|
648
|
-
});
|
|
649
|
-
}));
|
|
650
|
-
});
|
|
651
|
-
}).then(response => {
|
|
652
|
-
if (!response)
|
|
653
|
-
return;
|
|
654
|
-
const ids = response.map((item) => item ? item.id : undefined).filter(item => item !== undefined);
|
|
655
|
-
tmpMedias.forEach(id => {
|
|
656
|
-
delete this._context.tmpMedias[containerId][id];
|
|
657
|
-
});
|
|
658
|
-
this.mounted && this.setState({ tmpMedias: this.state.tmpMedias.filter(id => !tmpMedias.includes(id)) });
|
|
659
|
-
return ids;
|
|
660
|
-
}).catch((e) => {
|
|
661
|
-
if (tmpMedias) {
|
|
629
|
+
catch (e) {
|
|
662
630
|
tmpMedias.forEach(id => {
|
|
663
631
|
delete this._context.tmpMedias[containerId][id];
|
|
664
632
|
});
|
|
665
633
|
this.mounted && this.setState({ tmpMedias: this.state.tmpMedias.filter(id => !tmpMedias.includes(id)) });
|
|
634
|
+
throw e;
|
|
666
635
|
}
|
|
667
|
-
throw e;
|
|
668
636
|
});
|
|
669
637
|
}
|
|
670
638
|
};
|
|
@@ -684,7 +652,8 @@ function MediaArrayField(ComposedComponent) {
|
|
|
684
652
|
autoOpenAddModal: PropTypes.bool,
|
|
685
653
|
autoOpenMetadataModal: PropTypes.bool,
|
|
686
654
|
sideEffects: PropTypes.object,
|
|
687
|
-
exifParsers: PropTypes.arrayOf(PropTypes.object)
|
|
655
|
+
exifParsers: PropTypes.arrayOf(PropTypes.object),
|
|
656
|
+
metadataFormId: PropTypes.string
|
|
688
657
|
})
|
|
689
658
|
}),
|
|
690
659
|
schema: PropTypes.shape({
|
|
@@ -704,15 +673,18 @@ function MediaArrayField(ComposedComponent) {
|
|
|
704
673
|
class Thumbnail extends React.PureComponent {
|
|
705
674
|
constructor(props) {
|
|
706
675
|
super(props);
|
|
707
|
-
this.updateURL = ({ id, apiClient, apiEndpoint = "images" })
|
|
676
|
+
this.updateURL = (_a) => __awaiter(this, [_a], void 0, function* ({ id, apiClient, apiEndpoint = "images" }) {
|
|
708
677
|
if (!id)
|
|
709
678
|
return;
|
|
710
|
-
|
|
679
|
+
try {
|
|
680
|
+
const response = yield apiClient.get(`/${apiEndpoint}/{id}`, { path: { id } });
|
|
711
681
|
if (!this.mounted)
|
|
712
682
|
return;
|
|
713
683
|
this.setState({ url: response.squareThumbnailURL, linkUrl: response.originalURL });
|
|
714
|
-
}
|
|
715
|
-
|
|
684
|
+
}
|
|
685
|
+
catch (e) {
|
|
686
|
+
}
|
|
687
|
+
});
|
|
716
688
|
this.state = {};
|
|
717
689
|
this.updateURL(props);
|
|
718
690
|
}
|
|
@@ -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)
|
|
@@ -1053,7 +1062,7 @@ function _MapArrayField(ComposedComponent) {
|
|
|
1053
1062
|
constructor(props) {
|
|
1054
1063
|
super(props);
|
|
1055
1064
|
this.stretchContainerRef = React.createRef();
|
|
1056
|
-
this.geocode = () => {
|
|
1065
|
+
this.geocode = () => __awaiter(this, void 0, void 0, function* () {
|
|
1057
1066
|
// Zoom map to area. Area ID is accessed from schema field defined in options.areaField
|
|
1058
1067
|
const item = (this.props.formData || [])[this.state.activeIdx];
|
|
1059
1068
|
const { areaField } = (0, utils_2.getUiOptions)(this.props.uiSchema);
|
|
@@ -1066,11 +1075,10 @@ function _MapArrayField(ComposedComponent) {
|
|
|
1066
1075
|
}
|
|
1067
1076
|
const geometries = this.getGeometries();
|
|
1068
1077
|
if (geometries.length === 0 && area && area.length > 0) {
|
|
1069
|
-
this.props.formContext.apiClient.
|
|
1070
|
-
|
|
1071
|
-
});
|
|
1078
|
+
const { name } = yield this.props.formContext.apiClient.get(`/areas/${area}`);
|
|
1079
|
+
this.map.geocode(name, undefined, 8);
|
|
1072
1080
|
}
|
|
1073
|
-
};
|
|
1081
|
+
});
|
|
1074
1082
|
this.computeArea = () => {
|
|
1075
1083
|
const { activeIdx } = this.state;
|
|
1076
1084
|
if (activeIdx === undefined)
|
|
@@ -36,7 +36,7 @@ export default class MapField extends React.Component<any, any, any> {
|
|
|
36
36
|
componentDidUpdate(prevProps: any): void;
|
|
37
37
|
_lastFormData: any;
|
|
38
38
|
_zoomToDataOnNextTick: boolean | undefined;
|
|
39
|
-
geocode: (prevProps: any) => void
|
|
39
|
+
geocode: (prevProps: any) => Promise<void>;
|
|
40
40
|
zoomIfExternalEdit: (props: any) => void;
|
|
41
41
|
setMapRef: (mapComponent: any) => void;
|
|
42
42
|
map: any;
|
|
@@ -32,6 +32,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
35
44
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
36
45
|
var t = {};
|
|
37
46
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -107,7 +116,7 @@ class MapField extends React.Component {
|
|
|
107
116
|
this.setState({ locateOn: true });
|
|
108
117
|
}
|
|
109
118
|
};
|
|
110
|
-
this.geocode = (prevProps) => {
|
|
119
|
+
this.geocode = (prevProps) => __awaiter(this, void 0, void 0, function* () {
|
|
111
120
|
let { area } = (0, utils_1.getUiOptions)(this.props.uiSchema);
|
|
112
121
|
if (area instanceof Array) {
|
|
113
122
|
area = area[0];
|
|
@@ -120,11 +129,10 @@ class MapField extends React.Component {
|
|
|
120
129
|
|| (geoData.type === "FeatureCollection" && geoData.features.length === 0);
|
|
121
130
|
});
|
|
122
131
|
if (isEmptyAndWasEmpty && area && area.length > 0) {
|
|
123
|
-
this.props.formContext.apiClient.
|
|
124
|
-
|
|
125
|
-
});
|
|
132
|
+
const { name } = yield this.props.formContext.apiClient.get(`/areas/${area}`);
|
|
133
|
+
this.map.geocode(name, undefined, 8);
|
|
126
134
|
}
|
|
127
|
-
};
|
|
135
|
+
});
|
|
128
136
|
this.zoomIfExternalEdit = (props) => {
|
|
129
137
|
if (!equals(this._lastFormData, props.formData)) {
|
|
130
138
|
this.map.zoomToData();
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { ByLang, FormContext } from "../../LajiForm";
|
|
3
|
-
import { NamedPlace } from "@luomus/laji-schema";
|
|
4
3
|
import memoize from "memoizee";
|
|
4
|
+
import type { components } from "generated/api.d";
|
|
5
|
+
type NamedPlace = components["schemas"]["namedPlace"];
|
|
5
6
|
type Props = {
|
|
6
7
|
places: NamedPlace[];
|
|
7
8
|
failed?: boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { FieldProps, JSONSchemaArray, JSONSchemaObject } from "../../../types";
|
|
3
|
-
import {
|
|
3
|
+
import type { components } from "generated/api.d";
|
|
4
|
+
type NamedPlace = components["schemas"]["namedPlace"];
|
|
4
5
|
type Props = FieldProps<NamedPlace, JSONSchemaObject | JSONSchemaArray<JSONSchemaObject>>;
|
|
5
6
|
type State = {
|
|
6
7
|
show?: boolean;
|
|
@@ -11,7 +12,6 @@ type State = {
|
|
|
11
12
|
/** Compatible only with gatherings array and gathering object */
|
|
12
13
|
export default class NamedPlaceChooserField extends React.Component<Props, State> {
|
|
13
14
|
static contextType: React.Context<import("../../../ReactContext").ContextProps>;
|
|
14
|
-
removeIds: Record<string, boolean>;
|
|
15
15
|
mounted: boolean;
|
|
16
16
|
state: State;
|
|
17
17
|
getUiSchema: (props: Props, buttonDefinition: any) => import("../../../types").UiSchema<any> | {
|
|
@@ -60,9 +60,14 @@ export default class NamedPlaceChooserField extends React.Component<Props, State
|
|
|
60
60
|
};
|
|
61
61
|
isGatheringsArray: (schema: JSONSchemaObject | JSONSchemaArray<JSONSchemaObject>) => schema is JSONSchemaArray<JSONSchemaObject>;
|
|
62
62
|
onPlaceSelected: (place: NamedPlace) => void;
|
|
63
|
-
onPlaceDeleted: (place: NamedPlace
|
|
63
|
+
onPlaceDeleted: (place: NamedPlace & {
|
|
64
|
+
id: string;
|
|
65
|
+
}, end: () => void) => Promise<void>;
|
|
64
66
|
onButtonClick: () => () => void;
|
|
65
|
-
updatePlaces: (
|
|
67
|
+
updatePlaces: (response: {
|
|
68
|
+
results: NamedPlace[];
|
|
69
|
+
}) => void;
|
|
70
|
+
getNamedPlacesUnsubscribe: () => void;
|
|
66
71
|
componentDidMount(): void;
|
|
67
72
|
componentWillUnmount(): void;
|
|
68
73
|
onHide: () => void;
|
|
@@ -32,6 +32,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
35
44
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
45
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
46
|
};
|
|
@@ -39,6 +48,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
48
|
const React = __importStar(require("react"));
|
|
40
49
|
const ReactContext_1 = __importDefault(require("../../../ReactContext"));
|
|
41
50
|
const utils_1 = require("../../../utils");
|
|
51
|
+
// import { NamedPlace } from "@luomus/laji-schema";
|
|
42
52
|
const Context_1 = __importDefault(require("../../../Context"));
|
|
43
53
|
const NamedPlaceChooser_1 = require("./NamedPlaceChooser");
|
|
44
54
|
const PLACE_WHITELIST = [
|
|
@@ -59,7 +69,6 @@ const PLACE_DELETE_FAIL = "PLACE_DELETE_FAIL";
|
|
|
59
69
|
class NamedPlaceChooserField extends React.Component {
|
|
60
70
|
constructor() {
|
|
61
71
|
super(...arguments);
|
|
62
|
-
this.removeIds = {};
|
|
63
72
|
this.mounted = false;
|
|
64
73
|
this.state = {};
|
|
65
74
|
this.getUiSchema = (props, buttonDefinition) => {
|
|
@@ -122,69 +131,61 @@ class NamedPlaceChooserField extends React.Component {
|
|
|
122
131
|
this.setState({ failed: PLACE_USE_FAIL });
|
|
123
132
|
}
|
|
124
133
|
};
|
|
125
|
-
this.onPlaceDeleted = (place,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
setTimeout(() => this.props.formContext.apiClient.invalidateCachePath("/named-places"), 2000);
|
|
132
|
-
success();
|
|
133
|
-
}
|
|
134
|
-
}).catch(() => {
|
|
134
|
+
this.onPlaceDeleted = (place, end) => __awaiter(this, void 0, void 0, function* () {
|
|
135
|
+
try {
|
|
136
|
+
yield this.props.formContext.apiClient.delete("/named-places/{id}", { path: { id: place.id } });
|
|
137
|
+
end();
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
135
140
|
this.setState({ failed: PLACE_DELETE_FAIL });
|
|
136
141
|
this.props.formContext.notifier.error(this.props.formContext.translations.PlaceRemovalFailed);
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
end();
|
|
143
|
+
}
|
|
144
|
+
});
|
|
139
145
|
this.onButtonClick = () => () => {
|
|
140
146
|
this.setState({ show: true });
|
|
141
147
|
};
|
|
142
|
-
this.updatePlaces = () => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.setState(state);
|
|
174
|
-
}).catch(() => {
|
|
175
|
-
this.setState({ failed: PLACES_FETCH_FAIL });
|
|
176
|
-
});
|
|
148
|
+
this.updatePlaces = (response) => {
|
|
149
|
+
var _a;
|
|
150
|
+
if (!this.mounted)
|
|
151
|
+
return;
|
|
152
|
+
const state = { places: response.results.sort((a, b) => {
|
|
153
|
+
if (a.name < b.name)
|
|
154
|
+
return -1;
|
|
155
|
+
if (a.name > b.name)
|
|
156
|
+
return 1;
|
|
157
|
+
return 0;
|
|
158
|
+
}) };
|
|
159
|
+
if (!((_a = response.results) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const buttonDefinition = {
|
|
163
|
+
fn: this.onButtonClick,
|
|
164
|
+
fnName: "addNamedPlace",
|
|
165
|
+
glyph: "map-marker",
|
|
166
|
+
label: this.props.formContext.translations.ChooseFromNamedPlace,
|
|
167
|
+
id: this.props.idSchema.$id,
|
|
168
|
+
changesFormData: true,
|
|
169
|
+
variant: "primary"
|
|
170
|
+
};
|
|
171
|
+
if (this.isGatheringsArray(this.props.schema)) {
|
|
172
|
+
buttonDefinition.rules = { canAdd: true };
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
buttonDefinition.position = "top";
|
|
176
|
+
}
|
|
177
|
+
state.buttonDefinition = buttonDefinition;
|
|
178
|
+
this.setState(state);
|
|
177
179
|
};
|
|
178
180
|
this.onHide = () => this.setState({ show: false });
|
|
179
181
|
}
|
|
180
182
|
componentDidMount() {
|
|
181
183
|
this.mounted = true;
|
|
182
|
-
this.updatePlaces();
|
|
183
|
-
this.props.formContext.apiClient.onCachePathInvalidation("/named-places", this.updatePlaces);
|
|
184
|
+
this.getNamedPlacesUnsubscribe = this.props.formContext.apiClient.subscribe("/named-places", { query: { includePublic: false, pageSize: 100000 } }, this.updatePlaces, () => this.setState({ failed: PLACES_FETCH_FAIL }), 1000);
|
|
184
185
|
}
|
|
185
186
|
componentWillUnmount() {
|
|
186
187
|
this.mounted = false;
|
|
187
|
-
this.
|
|
188
|
+
this.getNamedPlacesUnsubscribe();
|
|
188
189
|
}
|
|
189
190
|
render() {
|
|
190
191
|
const { registry: { fields: { SchemaField } }, formContext } = this.props;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { NamedPlace } from "@luomus/laji-schema";
|
|
3
2
|
import { FormContext } from "src/components/LajiForm";
|
|
3
|
+
import type { components } from "generated/api.d";
|
|
4
|
+
type NamedPlace = components["schemas"]["namedPlace"];
|
|
4
5
|
type Props = {
|
|
5
6
|
onPlaceSelected: (place: NamedPlace) => void;
|
|
6
7
|
onPlaceDeleted: (place: NamedPlace) => void;
|