@luomus/laji-form 15.1.69 → 15.1.71
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/dist/styles.css +2 -2
- package/lib/ApiClient.d.ts +66 -21
- package/lib/ApiClient.js +174 -68
- package/lib/components/LajiForm.d.ts +10 -2
- package/lib/components/LajiForm.js +1 -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/CondensedObjectField.js +3 -5
- package/lib/components/fields/EnumRangeArrayField.js +1 -1
- package/lib/components/fields/GeocoderField.js +67 -79
- package/lib/components/fields/ImageArrayField.d.ts +9 -5
- package/lib/components/fields/ImageArrayField.js +103 -122
- 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 +51 -51
- package/lib/components/fields/NamedPlaceChooserField/Popup.d.ts +2 -1
- package/lib/components/fields/NamedPlaceSaverField.js +22 -18
- package/lib/components/fields/PrefixArrayField.js +3 -3
- package/lib/components/fields/ScopeField.js +1 -1
- package/lib/components/fields/SectionArrayField.js +1 -1
- package/lib/components/fields/SingleActiveArrayField.js +7 -7
- package/lib/components/fields/SortArrayField.js +1 -1
- package/lib/components/fields/TableField.js +2 -2
- package/lib/components/fields/UnitCountShorthandField.js +1 -1
- package/lib/components/fields/UnitListShorthandArrayField.js +2 -2
- package/lib/components/fields/UnitShorthandField.js +14 -18
- package/lib/components/templates/ArrayFieldTemplate.js +2 -2
- package/lib/components/widgets/AutosuggestWidget.js +77 -66
- package/lib/components/widgets/InformalTaxonGroupChooserWidget.js +1 -1
- package/lib/components/widgets/InputWithDefaultValueButtonWidget.js +1 -2
- package/lib/themes/bs5.js +10 -2
- package/lib/validation.js +1 -1
- package/package.json +5 -3
|
@@ -134,10 +134,9 @@ class CondensedObjectField extends React.Component {
|
|
|
134
134
|
return Math.max(...oldIndexes, -1) + 1;
|
|
135
135
|
}
|
|
136
136
|
render() {
|
|
137
|
-
var _a;
|
|
138
137
|
const SchemaField = this.props.registry.fields.SchemaField;
|
|
139
|
-
const { schema, uiSchema, idSchema, errorSchema, formData = {}, required, formContext: { Label, translations } } = this.props;
|
|
140
|
-
const
|
|
138
|
+
const { schema, uiSchema, idSchema, errorSchema, formData = {}, required, disabled, readonly, formContext: { Label, translations, uiSchemaContext } } = this.props;
|
|
139
|
+
const { addFieldPlaceholder = `${translations.AddField}`, confirmDelete = uiSchemaContext.confirmDelete } = (0, utils_1.getUiOptions)(uiSchema);
|
|
141
140
|
const childProps = this.state.selectedFields.map(field => {
|
|
142
141
|
let childSchema = schema.properties[field.name];
|
|
143
142
|
let childUiSchema = uiSchema[field.name] || {};
|
|
@@ -162,14 +161,13 @@ class CondensedObjectField extends React.Component {
|
|
|
162
161
|
value: prop,
|
|
163
162
|
label: schema.properties[prop].title || prop,
|
|
164
163
|
}));
|
|
165
|
-
const addFieldPlaceholder = (_a = uiOptions.addFieldPlaceholder) !== null && _a !== void 0 ? _a : `${translations.AddField}`;
|
|
166
164
|
return (React.createElement(React.Fragment, null,
|
|
167
165
|
React.createElement(Label, { label: this.props.schema.title, required: required || uiSchema["ui:required"], id: this.props.idSchema.$id, uiSchema: this.props.uiSchema }),
|
|
168
166
|
childProps.map((props, idx) => React.createElement("div", { key: idx, className: "laji-form-field-template-item condensed-object-field-item" },
|
|
169
167
|
React.createElement("div", { className: "laji-form-field-template-schema" },
|
|
170
168
|
React.createElement(SchemaField, Object.assign({}, this.props, props, { key: idx, onChange: this.onFieldChange(idx) }))),
|
|
171
169
|
React.createElement("div", { className: "laji-form-field-template-buttons" },
|
|
172
|
-
React.createElement(components_1.DeleteButton, { id: props.idSchema.$id, onClick: this.onFieldDelete(idx), translations: translations })))),
|
|
170
|
+
React.createElement(components_1.DeleteButton, { id: props.idSchema.$id, onClick: this.onFieldDelete(idx), translations: translations, confirm: confirmDelete, disabled: disabled || readonly })))),
|
|
173
171
|
React.createElement(SelectWidget_1.default, { key: childProps.length, options: { enumOptions: selectableFieldEnums, placeholder: addFieldPlaceholder }, onChange: this.onSelectFieldChange, includeEmpty: true, schema: {}, id: `${idSchema.$id}_field_select`, formContext: this.props.formContext, disabled: this.props.disabled, readonly: this.props.readonly })));
|
|
174
172
|
}
|
|
175
173
|
}
|
|
@@ -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.
|
|
63
|
+
const enums = yield props.formContext.apiClient.get(`/metadata/ranges/${range}`);
|
|
64
64
|
return enums.map(({ value }) => ({ value, label: value }));
|
|
65
65
|
}), [props.formContext.apiClient, range]);
|
|
66
66
|
const { Label } = props.formContext;
|
|
@@ -195,78 +195,73 @@ let GeocoderField = class GeocoderField extends React.Component {
|
|
|
195
195
|
responseField: "long_name"
|
|
196
196
|
}
|
|
197
197
|
};
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return found[field] && found[field][typeIdx];
|
|
214
|
-
});
|
|
198
|
+
const found = {};
|
|
199
|
+
Object.keys(parsers).forEach(field => {
|
|
200
|
+
const parser = parsers[field];
|
|
201
|
+
parser.type.some((type, typeIdx) => {
|
|
202
|
+
response.results.forEach(result => result.address_components.forEach(addressComponent => {
|
|
203
|
+
if (addressComponent.types.includes(type)) {
|
|
204
|
+
if (!found[field])
|
|
205
|
+
found[field] = {};
|
|
206
|
+
if (!found[field][typeIdx])
|
|
207
|
+
found[field][typeIdx] = {};
|
|
208
|
+
const responseField = addressComponent[parser.responseField] ? parser.responseField : "short_name";
|
|
209
|
+
found[field][typeIdx][addressComponent[responseField]] = true;
|
|
210
|
+
}
|
|
211
|
+
}));
|
|
212
|
+
return found[field] && found[field][typeIdx];
|
|
215
213
|
});
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
changes[field] = join(changes[field], value);
|
|
214
|
+
});
|
|
215
|
+
Object.keys(parsers).forEach(field => {
|
|
216
|
+
if (!fieldByKeys[field] || !this.props.schema.properties[field]) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (found[field]) {
|
|
220
|
+
const keys = Object.keys(found[field]);
|
|
221
|
+
const responseForField = found[field][keys[0]];
|
|
222
|
+
Object.keys(responseForField).forEach(value => {
|
|
223
|
+
// If target field is array.
|
|
224
|
+
if (this.props.schema.properties[field].type === "array") {
|
|
225
|
+
const temp = Array.from((this.props.formData || {})[field] || []);
|
|
226
|
+
// Find correct enum from fieldOptions.
|
|
227
|
+
const fieldOptions = this.props.uiSchema["ui:options"].fieldOptions;
|
|
228
|
+
const enumField = fieldOptions[fieldOptions.findIndex(element => {
|
|
229
|
+
return element.field === field;
|
|
230
|
+
})].enum;
|
|
231
|
+
// Find enum value from key (eg. municipalityName --> municipalityId).
|
|
232
|
+
const _enum = this.props.formContext.uiSchemaContext[enumField].oneOf;
|
|
233
|
+
const enumValue = _enum.find(item => item.title === value).const;
|
|
234
|
+
// Push enum value to changes.
|
|
235
|
+
if (enumValue !== undefined) {
|
|
236
|
+
!temp.includes(enumValue) && temp.push(enumValue);
|
|
237
|
+
changes[field] = temp;
|
|
243
238
|
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
changes
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
changes[field] = join(changes[field], value);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
changes[field] = (0, utils_1.getDefaultFormState)(this.props.schema.properties[field]);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
if (country && this.props.schema.properties.country && fieldByKeys.country)
|
|
250
|
+
changes.country = country;
|
|
251
|
+
success(() => {
|
|
252
|
+
if (timestamp !== this.promiseTimestamp)
|
|
253
|
+
return;
|
|
254
|
+
if (this.mounted) {
|
|
255
|
+
this.props.onChange(Object.assign(Object.assign({}, (this.props.formData || {})), changes));
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
const pointer = this.props.formContext.services.ids.getJSONPointerFromLajiFormIdAndFormDataAndIdSchemaId(this.props.idSchema.$id, (0, utils_1.getFieldUUID)(this.props));
|
|
259
|
+
const newFormData = Object.assign(Object.assign({}, (0, utils_1.parseJSONPointer)(lajiFormInstance.getFormData(), pointer)), changes);
|
|
260
|
+
lajiFormInstance.onChange((0, utils_1.updateSafelyWithJSONPointer)(lajiFormInstance.getFormData(), newFormData, pointer));
|
|
261
|
+
}
|
|
262
|
+
if (callback)
|
|
263
|
+
callback();
|
|
264
|
+
});
|
|
270
265
|
};
|
|
271
266
|
const fetchForeign = () => {
|
|
272
267
|
if (!props.formContext.googleApiKey)
|
|
@@ -292,15 +287,8 @@ let GeocoderField = class GeocoderField extends React.Component {
|
|
|
292
287
|
}, 30 * 1000);
|
|
293
288
|
!bounds.overlaps(globals_1.FINLAND_BOUNDS)
|
|
294
289
|
? fetchForeign()
|
|
295
|
-
: this.props.formContext.apiClient.
|
|
296
|
-
|
|
297
|
-
headers: {
|
|
298
|
-
"accept": "application/json",
|
|
299
|
-
"content-type": "application/json"
|
|
300
|
-
},
|
|
301
|
-
body: JSON.stringify(geometry)
|
|
302
|
-
}).then(response => response.json()).then(handleResponse(props.formContext.translations.Finland, "municipality", "biologicalProvince", "biogeographicalProvince")).catch((e) => {
|
|
303
|
-
fail(e.message);
|
|
290
|
+
: this.props.formContext.apiClient.post("/coordinates/location", undefined, geometry).then().then(handleResponse(props.formContext.translations.Finland, "municipality", "biologicalProvince", "biogeographicalProvince")).catch((e) => {
|
|
291
|
+
fail(typeof e === "string" ? e : e.message);
|
|
304
292
|
});
|
|
305
293
|
}));
|
|
306
294
|
};
|
|
@@ -16,6 +16,10 @@ interface MediaMetadataSchema {
|
|
|
16
16
|
intellectualOwner?: string;
|
|
17
17
|
intellectualRights?: string;
|
|
18
18
|
}
|
|
19
|
+
interface ProcessedExifData {
|
|
20
|
+
formData?: any;
|
|
21
|
+
defaultMediaMetadata?: any;
|
|
22
|
+
}
|
|
19
23
|
export default class ImageArrayField extends React.Component<FieldProps<any, JSONSchemaArray<JSONSchemaObject>>, ImageArrayFieldState> {
|
|
20
24
|
ALLOWED_FILE_TYPES: string[];
|
|
21
25
|
ACCEPT_FILE_TYPES: string[];
|
|
@@ -89,18 +93,18 @@ export declare function MediaArrayField<LFC extends Constructor<React.Component<
|
|
|
89
93
|
onHideMediaAddModal: () => void;
|
|
90
94
|
renderMediaAddModal: () => JSX.Element | null;
|
|
91
95
|
onAlertOk: () => void;
|
|
92
|
-
parseExif: (files: File[]) =>
|
|
96
|
+
parseExif: (files: File[]) => Promise<ProcessedExifData>;
|
|
93
97
|
sideEffects: (formData: any) => void;
|
|
94
98
|
onFileFormChange: (files: File[]) => void;
|
|
95
99
|
getContainerId: () => number | "root";
|
|
96
|
-
saveMedias(files: File[]): Promise<any[] | undefined>;
|
|
100
|
+
saveMedias(files: File[], exifDataPromise: Promise<ProcessedExifData>): Promise<any[] | undefined>;
|
|
97
101
|
addNameToDataURL: (dataURL: string, name: string) => string;
|
|
98
102
|
processFiles: (files: File[]) => Promise<ProcessedFile[]>;
|
|
99
103
|
processFile: (file: File) => Promise<ProcessedFile>;
|
|
100
104
|
onMediaMetadataUpdate: ({ formData }: {
|
|
101
105
|
formData: any;
|
|
102
|
-
}) => void
|
|
103
|
-
getMetadataPromise: () => Promise<MediaMetadataSchema>;
|
|
106
|
+
}) => Promise<void>;
|
|
107
|
+
getMetadataPromise: (exifDataPromise: Promise<ProcessedExifData>) => Promise<MediaMetadataSchema>;
|
|
104
108
|
getMaxFileSizeAsString: () => string;
|
|
105
109
|
getAllowedMediaFormatsTranslationKey: () => "AllowedFileFormat" | "AllowedFileFormats";
|
|
106
110
|
getAllowedMediaFormatsAsString: () => string;
|
|
@@ -170,7 +174,7 @@ export declare class Thumbnail extends React.PureComponent<ThumbnailProps, Thumb
|
|
|
170
174
|
componentDidMount(): void;
|
|
171
175
|
componentWillUnmount(): void;
|
|
172
176
|
UNSAFE_componentWillReceiveProps(props: ThumbnailProps): void;
|
|
173
|
-
updateURL: ({ id, apiClient, apiEndpoint }: ThumbnailProps) => void
|
|
177
|
+
updateURL: ({ id, apiClient, apiEndpoint }: ThumbnailProps) => Promise<void>;
|
|
174
178
|
render(): JSX.Element | null;
|
|
175
179
|
}
|
|
176
180
|
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 });
|
|
@@ -185,7 +195,7 @@ function MediaArrayField(ComposedComponent) {
|
|
|
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);
|
|
188
|
-
this.apiClient.
|
|
198
|
+
this.apiClient.get("/forms/{id}", { path: { id: metadataFormId }, query: { lang, format: "schema" } })
|
|
189
199
|
.then(metadataForm => {
|
|
190
200
|
if (this.mounted) {
|
|
191
201
|
this.setState({ metadataForm });
|
|
@@ -250,7 +260,7 @@ function MediaArrayField(ComposedComponent) {
|
|
|
250
260
|
this.parseExif = (files) => {
|
|
251
261
|
const { exifParsers = [] } = (0, utils_1.getUiOptions)(this.props.uiSchema);
|
|
252
262
|
if (!exifParsers)
|
|
253
|
-
return;
|
|
263
|
+
return Promise.resolve({});
|
|
254
264
|
const found = exifParsers.reduce((found, { parse }) => {
|
|
255
265
|
found[parse] = false;
|
|
256
266
|
return found;
|
|
@@ -316,15 +326,19 @@ function MediaArrayField(ComposedComponent) {
|
|
|
316
326
|
const lajiFormInstance = this.props.formContext.services.rootInstance;
|
|
317
327
|
const schema = lajiFormInstance.getSchema();
|
|
318
328
|
let formData = lajiFormInstance.getFormData();
|
|
329
|
+
let defaultMediaMetadata = {};
|
|
319
330
|
exifParsers.filter((f) => f.type === "event" || found[f.parse]).forEach(({ field, parse, type, eventName }) => {
|
|
320
331
|
if (type === "mutate") {
|
|
321
332
|
formData = (0, utils_1.updateFormDataWithJSONPointer)({ formData, schema, registry }, found[parse], field);
|
|
322
333
|
}
|
|
334
|
+
if (type === "mutateMetadata") {
|
|
335
|
+
defaultMediaMetadata = (0, utils_1.updateSafelyWithJSONPointer)(defaultMediaMetadata, found[parse], field);
|
|
336
|
+
}
|
|
323
337
|
if (type === "event") {
|
|
324
338
|
this.props.formContext.services.customEvents.send(`root_${(0, utils_1.JSONPointerToId)(field)}`, eventName, found[parse], undefined, { bubble: false });
|
|
325
339
|
}
|
|
326
340
|
});
|
|
327
|
-
return formData;
|
|
341
|
+
return { formData, defaultMediaMetadata };
|
|
328
342
|
});
|
|
329
343
|
};
|
|
330
344
|
this.sideEffects = (formData) => {
|
|
@@ -354,14 +368,18 @@ function MediaArrayField(ComposedComponent) {
|
|
|
354
368
|
}
|
|
355
369
|
};
|
|
356
370
|
this.onFileFormChange = (files) => {
|
|
357
|
-
var _a;
|
|
358
371
|
if (this.state.addModal) {
|
|
359
372
|
this.setState({ addModal: undefined });
|
|
360
373
|
}
|
|
361
|
-
|
|
374
|
+
const exifDataPromise = this.parseExif(files);
|
|
375
|
+
exifDataPromise.then(data => {
|
|
376
|
+
if (data.formData) {
|
|
377
|
+
this.sideEffects(data.formData);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
362
380
|
const id = this.getContainerId();
|
|
363
381
|
const lajiFormInstance = this.props.formContext.services.rootInstance;
|
|
364
|
-
const saveAndOnChange = () => this.saveMedias(files).then(mediaIds => {
|
|
382
|
+
const saveAndOnChange = () => this.saveMedias(files, exifDataPromise).then(mediaIds => {
|
|
365
383
|
if (!lajiFormInstance.isMounted() || !mediaIds) {
|
|
366
384
|
return;
|
|
367
385
|
}
|
|
@@ -422,16 +440,10 @@ function MediaArrayField(ComposedComponent) {
|
|
|
422
440
|
reader.readAsDataURL(file);
|
|
423
441
|
});
|
|
424
442
|
};
|
|
425
|
-
this.onMediaMetadataUpdate = ({ formData })
|
|
443
|
+
this.onMediaMetadataUpdate = (_a) => __awaiter(this, [_a], void 0, function* ({ formData }) {
|
|
426
444
|
this.props.formContext.services.blocker.push();
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
headers: {
|
|
430
|
-
"accept": "application/json",
|
|
431
|
-
"content-type": "application/json"
|
|
432
|
-
},
|
|
433
|
-
body: JSON.stringify(formData)
|
|
434
|
-
}).then(() => {
|
|
445
|
+
try {
|
|
446
|
+
yield this.apiClient.put(`/${this.ENDPOINT}/{id}`, { path: { id: formData.id } }, formData);
|
|
435
447
|
this.props.formContext.services.blocker.pop();
|
|
436
448
|
const notify = () => this.props.formContext.notifier.success(this.props.formContext.translations.SaveSuccess);
|
|
437
449
|
if (this.mounted) {
|
|
@@ -440,20 +452,24 @@ function MediaArrayField(ComposedComponent) {
|
|
|
440
452
|
else {
|
|
441
453
|
notify();
|
|
442
454
|
}
|
|
443
|
-
}
|
|
455
|
+
}
|
|
456
|
+
catch (e) {
|
|
444
457
|
this.props.formContext.services.blocker.pop();
|
|
445
458
|
this.mounted && this.setState({ metadataSaveSuccess: false });
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
this.getMetadataPromise = () => {
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
this.getMetadataPromise = (exifDataPromise) => {
|
|
449
462
|
let mediaMetadata = this.props.formContext.mediaMetadata
|
|
450
463
|
|| { intellectualRights: "MZ.intellectualRightsARR" };
|
|
451
464
|
const MACode = this.props.formContext.uiSchemaContext.creator;
|
|
452
|
-
|
|
453
|
-
? Promise.resolve(Object.assign(Object.assign({}, mediaMetadata), { capturerVerbatim: [mediaMetadata.capturerVerbatim] }))
|
|
465
|
+
const metadataPromise = ("capturerVerbatim" in mediaMetadata)
|
|
466
|
+
? Promise.resolve(Object.assign(Object.assign({}, mediaMetadata), { capturerVerbatim: Array.isArray(mediaMetadata.capturerVerbatim) ? mediaMetadata.capturerVerbatim : [mediaMetadata.capturerVerbatim] }))
|
|
454
467
|
: MACode
|
|
455
|
-
? this.apiClient.
|
|
456
|
-
: mediaMetadata;
|
|
468
|
+
? 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))
|
|
469
|
+
: Promise.resolve(mediaMetadata);
|
|
470
|
+
return Promise.all([exifDataPromise, metadataPromise]).then(([exifData, metadata]) => {
|
|
471
|
+
return Object.assign(Object.assign({}, exifData.defaultMediaMetadata), metadata);
|
|
472
|
+
});
|
|
457
473
|
};
|
|
458
474
|
this.getMaxFileSizeAsString = () => {
|
|
459
475
|
let maxSize = this.MAX_FILE_SIZE.toString().substring(0, this.MAX_FILE_SIZE.toString().length - 6);
|
|
@@ -566,106 +582,68 @@ function MediaArrayField(ComposedComponent) {
|
|
|
566
582
|
this.renderMetadataModal(),
|
|
567
583
|
this.renderMediaAddModal()))));
|
|
568
584
|
}
|
|
569
|
-
saveMedias(files) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
const
|
|
574
|
-
.
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
mediaUuid++;
|
|
587
|
-
this._context.tmpMedias[containerId][mediaUuid] = f.dataURL;
|
|
588
|
-
return mediaUuid;
|
|
589
|
-
});
|
|
590
|
-
this.mounted && this.setState({ tmpMedias: [...(this.state.tmpMedias || []), ...tmpMedias] });
|
|
591
|
-
const formDataBody = files.reduce((body, file) => {
|
|
592
|
-
if (!this.ALLOWED_FILE_TYPES.includes(file.type)) {
|
|
593
|
-
invalidFile = true;
|
|
585
|
+
saveMedias(files, exifDataPromise) {
|
|
586
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
587
|
+
const containerId = this.getContainerId();
|
|
588
|
+
let tmpMedias = [];
|
|
589
|
+
const fail = (translationKey, additionalInfo = "") => {
|
|
590
|
+
const translation = (Array.isArray(translationKey) ? translationKey : [translationKey])
|
|
591
|
+
.map((key) => this.props.formContext.translations[key])
|
|
592
|
+
.join(". ");
|
|
593
|
+
throw `${translation} ${additionalInfo}`;
|
|
594
|
+
};
|
|
595
|
+
try {
|
|
596
|
+
const processedFiles = yield this.processFiles(files);
|
|
597
|
+
let invalidFile = (files.length <= 0);
|
|
598
|
+
let fileTooLarge = false;
|
|
599
|
+
let noValidData = true;
|
|
600
|
+
if (!this._context.tmpMedias[containerId]) {
|
|
601
|
+
this._context.tmpMedias[containerId] = {};
|
|
594
602
|
}
|
|
595
|
-
|
|
596
|
-
|
|
603
|
+
tmpMedias = processedFiles.map(f => {
|
|
604
|
+
mediaUuid++;
|
|
605
|
+
this._context.tmpMedias[containerId][mediaUuid] = f.dataURL;
|
|
606
|
+
return mediaUuid;
|
|
607
|
+
});
|
|
608
|
+
this.mounted && this.setState({ tmpMedias: [...(this.state.tmpMedias || []), ...tmpMedias] });
|
|
609
|
+
const formData = files.reduce((body, file) => {
|
|
610
|
+
if (!this.ALLOWED_FILE_TYPES.includes(file.type)) {
|
|
611
|
+
invalidFile = true;
|
|
612
|
+
}
|
|
613
|
+
else if (file.size > this.MAX_FILE_SIZE) {
|
|
614
|
+
fileTooLarge = true;
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
body.append("data", file);
|
|
618
|
+
noValidData = false;
|
|
619
|
+
}
|
|
620
|
+
return body;
|
|
621
|
+
}, new FormData());
|
|
622
|
+
if (noValidData && invalidFile) {
|
|
623
|
+
fail(this.getAllowedMediaFormatsTranslationKey(), this.getAllowedMediaFormatsAsString() + ".");
|
|
624
|
+
return;
|
|
597
625
|
}
|
|
598
|
-
else {
|
|
599
|
-
|
|
600
|
-
|
|
626
|
+
else if (noValidData && fileTooLarge) {
|
|
627
|
+
fail("AllowedFileSize", this.getMaxFileSizeAsString() + ".");
|
|
628
|
+
return;
|
|
601
629
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
else if (noValidData && fileTooLarge) {
|
|
609
|
-
fail("AllowedFileSize", this.getMaxFileSizeAsString() + ".");
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
return this.apiClient.fetchRaw(`/${this.ENDPOINT}`, undefined, {
|
|
614
|
-
method: "POST",
|
|
615
|
-
body: formDataBody
|
|
630
|
+
const tmpMediaEntities = yield this.apiClient.post(`/${this.ENDPOINT}`, undefined, formData);
|
|
631
|
+
const mediaMetadata = yield this.getMetadataPromise(exifDataPromise);
|
|
632
|
+
const mediaEntities = yield Promise.all(tmpMediaEntities.map((item) => this.apiClient.post(`/${this.ENDPOINT}/{id}`, { path: { id: item.id } }, mediaMetadata)));
|
|
633
|
+
const ids = mediaEntities.map((item) => item ? item.id : undefined).filter(item => item !== undefined);
|
|
634
|
+
tmpMedias.forEach(id => {
|
|
635
|
+
delete this._context.tmpMedias[containerId][id];
|
|
616
636
|
});
|
|
637
|
+
this.mounted && this.setState({ tmpMedias: this.state.tmpMedias.filter(id => !tmpMedias.includes(id)) });
|
|
638
|
+
return ids;
|
|
617
639
|
}
|
|
618
|
-
|
|
619
|
-
if (!response)
|
|
620
|
-
return;
|
|
621
|
-
if (response.status < 400) {
|
|
622
|
-
return response.json();
|
|
623
|
-
}
|
|
624
|
-
else if (response.status === 400) {
|
|
625
|
-
fail("InvalidFile");
|
|
626
|
-
}
|
|
627
|
-
else if (response.status === 503) {
|
|
628
|
-
fail("InsufficientSpace");
|
|
629
|
-
}
|
|
630
|
-
else {
|
|
631
|
-
fail(["SomethingWentWrong", "TryAgainLater"]);
|
|
632
|
-
}
|
|
633
|
-
}).then(response => {
|
|
634
|
-
if (!response)
|
|
635
|
-
return;
|
|
636
|
-
return this.getMetadataPromise().then(mediaMetadata => {
|
|
637
|
-
return Promise.all(response.map((item) => {
|
|
638
|
-
return this.apiClient.fetchRaw(`/${this.ENDPOINT}/${item.id}`, undefined, {
|
|
639
|
-
method: "POST",
|
|
640
|
-
headers: {
|
|
641
|
-
"accept": "application/json",
|
|
642
|
-
"content-type": "application/json"
|
|
643
|
-
},
|
|
644
|
-
body: JSON.stringify(mediaMetadata)
|
|
645
|
-
}).then(response => {
|
|
646
|
-
if (response.status < 400) {
|
|
647
|
-
return response.json();
|
|
648
|
-
}
|
|
649
|
-
});
|
|
650
|
-
}));
|
|
651
|
-
});
|
|
652
|
-
}).then(response => {
|
|
653
|
-
if (!response)
|
|
654
|
-
return;
|
|
655
|
-
const ids = response.map((item) => item ? item.id : undefined).filter(item => item !== undefined);
|
|
656
|
-
tmpMedias.forEach(id => {
|
|
657
|
-
delete this._context.tmpMedias[containerId][id];
|
|
658
|
-
});
|
|
659
|
-
this.mounted && this.setState({ tmpMedias: this.state.tmpMedias.filter(id => !tmpMedias.includes(id)) });
|
|
660
|
-
return ids;
|
|
661
|
-
}).catch((e) => {
|
|
662
|
-
if (tmpMedias) {
|
|
640
|
+
catch (e) {
|
|
663
641
|
tmpMedias.forEach(id => {
|
|
664
642
|
delete this._context.tmpMedias[containerId][id];
|
|
665
643
|
});
|
|
666
644
|
this.mounted && this.setState({ tmpMedias: this.state.tmpMedias.filter(id => !tmpMedias.includes(id)) });
|
|
645
|
+
throw e;
|
|
667
646
|
}
|
|
668
|
-
throw e;
|
|
669
647
|
});
|
|
670
648
|
}
|
|
671
649
|
};
|
|
@@ -706,15 +684,18 @@ function MediaArrayField(ComposedComponent) {
|
|
|
706
684
|
class Thumbnail extends React.PureComponent {
|
|
707
685
|
constructor(props) {
|
|
708
686
|
super(props);
|
|
709
|
-
this.updateURL = ({ id, apiClient, apiEndpoint = "images" })
|
|
687
|
+
this.updateURL = (_a) => __awaiter(this, [_a], void 0, function* ({ id, apiClient, apiEndpoint = "images" }) {
|
|
710
688
|
if (!id)
|
|
711
689
|
return;
|
|
712
|
-
|
|
690
|
+
try {
|
|
691
|
+
const response = yield apiClient.get(`/${apiEndpoint}/{id}`, { path: { id } });
|
|
713
692
|
if (!this.mounted)
|
|
714
693
|
return;
|
|
715
694
|
this.setState({ url: response.squareThumbnailURL, linkUrl: response.originalURL });
|
|
716
|
-
}
|
|
717
|
-
|
|
695
|
+
}
|
|
696
|
+
catch (e) {
|
|
697
|
+
}
|
|
698
|
+
});
|
|
718
699
|
this.state = {};
|
|
719
700
|
this.updateURL(props);
|
|
720
701
|
}
|
|
@@ -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)
|