@masterportal/masterportalapi 2.13.0 → 2.14.0
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/.eslintrc +2 -1
- package/CHANGELOG.md +10 -7
- package/example/config/portal.json +8 -1
- package/example/config/services.json +10 -0
- package/example/index.js +34 -2
- package/jest.config.js +1 -1
- package/jest.setup.js +9 -1
- package/package.json +4 -3
- package/src/lib/attributeMapper.js +231 -0
- package/src/lib/getValueFromObjectByPath.js +73 -0
- package/src/lib/thousandsSeparator.js +23 -0
- package/src/vectorStyle/createStyle.js +259 -0
- package/src/vectorStyle/lib/colorConvertions.js +97 -0
- package/src/vectorStyle/lib/createLegendInfo.js +28 -0
- package/src/vectorStyle/lib/getGeometryTypeFromService.js +153 -0
- package/src/vectorStyle/lib/getRuleForIndex.js +62 -0
- package/src/vectorStyle/lib/valueOperations.js +172 -0
- package/src/vectorStyle/styleList.js +281 -0
- package/src/vectorStyle/styles/defaultStyles.js +177 -0
- package/src/vectorStyle/styles/point/stylePoint.js +108 -0
- package/src/vectorStyle/styles/point/stylePointCircle.js +29 -0
- package/src/vectorStyle/styles/point/stylePointIcon.js +79 -0
- package/src/vectorStyle/styles/point/stylePointInterval.js +124 -0
- package/src/vectorStyle/styles/point/stylePointNominal.js +232 -0
- package/src/vectorStyle/styles/point/stylePointRegularShape.js +39 -0
- package/src/vectorStyle/styles/polygon/polygonStyleHatch.js +160 -0
- package/src/vectorStyle/styles/polygon/stylePolygon.js +125 -0
- package/src/vectorStyle/styles/style.js +161 -0
- package/src/vectorStyle/styles/styleCesium.js +106 -0
- package/src/vectorStyle/styles/styleLine.js +51 -0
- package/src/vectorStyle/styles/styleText.js +143 -0
- package/test/lib/attributeMapper.test.js +290 -0
- package/test/lib/getValueFromObjectByPath.test.js +61 -0
- package/test/lib/thousandsSeparator.test.js +58 -0
- package/test/vectorStyle/createStyle.test.js +335 -0
- package/test/vectorStyle/lib/colorConvertions.test.js +42 -0
- package/test/vectorStyle/lib/getRuleForIndex.test.js +132 -0
- package/test/vectorStyle/lib/valueOperations.test.js +191 -0
- package/test/vectorStyle/styles/point/stylePoint.test.js +28 -0
- package/test/vectorStyle/styles/point/stylePointCircle.test.js +30 -0
- package/test/vectorStyle/styles/point/stylePointIcon.test.js +83 -0
- package/test/vectorStyle/styles/point/stylePointInterval.test.js +57 -0
- package/test/vectorStyle/styles/point/stylePointNominal.test.js +84 -0
- package/test/vectorStyle/styles/point/stylePointRegularShape.test.js +24 -0
- package/test/vectorStyle/styles/polygon/polygonStyleHatch.test.js +95 -0
- package/test/vectorStyle/styles/polygon/stylePolygon.test.js +61 -0
- package/test/vectorStyle/styles/styleLine.test.js +29 -0
- package/test/vectorStyle/styles/styleText.test.js +49 -0
package/.eslintrc
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -3,23 +3,26 @@
|
|
|
3
3
|
|
|
4
4
|
The [Semantic Versioning](https://semver.org/spec/v2.0.0.html) is used.
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 2.14.0 - 2023-02-22
|
|
7
7
|
### Added
|
|
8
|
+
- VectorStyle is now part of the masterportalApi.
|
|
9
|
+
- The following packages have been installed:
|
|
10
|
+
- use-resize-observer: 9.1.0
|
|
11
|
+
|
|
8
12
|
### Changed
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
### Fixed
|
|
13
|
+
- The following packages have been updated:
|
|
14
|
+
- dependencies:
|
|
15
|
+
- ol: 7.1.0 to 7.2.2
|
|
13
16
|
|
|
14
17
|
---
|
|
15
18
|
|
|
16
|
-
## 2.13.0 -
|
|
19
|
+
## 2.13.0 - 2023-02-16
|
|
17
20
|
### Changed
|
|
18
21
|
- GeoJSON now also register a featuresloadend function if the source is a cluster.
|
|
19
22
|
|
|
20
23
|
---
|
|
21
24
|
|
|
22
|
-
## 2.12.0 -
|
|
25
|
+
## 2.12.0 - 2023-01-24
|
|
23
26
|
### Added
|
|
24
27
|
- Added support for Node LTS version 18.
|
|
25
28
|
- Add possibility to specify additional layerparams for a wmts layer, like opacity for example.
|
|
@@ -29,7 +29,14 @@
|
|
|
29
29
|
"layers": [
|
|
30
30
|
{
|
|
31
31
|
"id": "1001"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "8712",
|
|
35
|
+
"name": "Schulinfosystem",
|
|
36
|
+
"styleId": "8712",
|
|
37
|
+
"typ": "WFS"
|
|
32
38
|
}
|
|
33
39
|
],
|
|
34
|
-
"cesiumLib":"https://geoportal-hamburg.de/mastercode/cesium/1_99/Cesium.js"
|
|
40
|
+
"cesiumLib":"https://geoportal-hamburg.de/mastercode/cesium/1_99/Cesium.js",
|
|
41
|
+
"wfsImgPath": "https://geodienste.hamburg.de/lgv-config/img/"
|
|
35
42
|
}
|
|
@@ -113,6 +113,16 @@
|
|
|
113
113
|
"anzahl_schueler": ">1000"
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
|
+
{
|
|
117
|
+
"id": "8712",
|
|
118
|
+
"name": "de.hh.up:staatliche schulen",
|
|
119
|
+
"url": "https://geodienste.hamburg.de/HH_WFS_Schulen",
|
|
120
|
+
"typ": "WFS",
|
|
121
|
+
"featureType": "staatliche_schulen",
|
|
122
|
+
"outputFormat": "XML",
|
|
123
|
+
"version": "1.1.0",
|
|
124
|
+
"featureNS": "https://registry.gdi-de.org/id/de.hh.up"
|
|
125
|
+
},
|
|
116
126
|
{
|
|
117
127
|
"id": "6001",
|
|
118
128
|
"name": "ADV (EPSG:25832)",
|
package/example/index.js
CHANGED
|
@@ -5,6 +5,8 @@ import {Style, Stroke, Fill, Icon} from "ol/style.js";
|
|
|
5
5
|
import * as mpapi from "../src";
|
|
6
6
|
import mapsAPI from "../src/maps/api.js";
|
|
7
7
|
import rawLayerList from "../src/rawLayerList";
|
|
8
|
+
import styleList from "../src/vectorStyle/styleList";
|
|
9
|
+
import createStyle from "../src/vectorStyle/createStyle";
|
|
8
10
|
|
|
9
11
|
import services from "./config/services.json";
|
|
10
12
|
import portalConfig from "./config/portal.json";
|
|
@@ -31,7 +33,25 @@ const hamburgServicesUrl = "https://geodienste.hamburg.de/services-internet.json
|
|
|
31
33
|
},
|
|
32
34
|
config = {
|
|
33
35
|
...portalConfig,
|
|
34
|
-
layerConf: services
|
|
36
|
+
layerConf: services,
|
|
37
|
+
styleConf: "https://geodienste.hamburg.de/lgv-config/style_v3.json"
|
|
38
|
+
},
|
|
39
|
+
// eslint-disable-next-line func-style
|
|
40
|
+
getWfsStyleFunction = function () {
|
|
41
|
+
const styleId = "8712",
|
|
42
|
+
olLayer = window.mpapi.map.getLayers().getArray().find((element) => element.get("id") === "8712"),
|
|
43
|
+
source = olLayer.getSource(),
|
|
44
|
+
styleObject = styleList.returnStyleObject(styleId);
|
|
45
|
+
let isClusterFeature = false;
|
|
46
|
+
|
|
47
|
+
if (styleObject !== undefined) {
|
|
48
|
+
source.on("featuresloadend", event => {
|
|
49
|
+
event.features.forEach(element => {
|
|
50
|
+
isClusterFeature = false;
|
|
51
|
+
element.setStyle(createStyle.createStyle(styleObject, element, isClusterFeature, config.wfsImgPath));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
}
|
|
35
55
|
};
|
|
36
56
|
let map2D = null;
|
|
37
57
|
|
|
@@ -237,4 +257,16 @@ map2D.getLayers().forEach(layer => {
|
|
|
237
257
|
window.mpapi.map.addLayer("7001");
|
|
238
258
|
window.mpapi.map.addLayer("7002");
|
|
239
259
|
window.mpapi.map.addLayer("7003");
|
|
240
|
-
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
/* VectorStyle example */
|
|
263
|
+
// Example for using the vectorStyle that is now implemented in the masterportalAPI.
|
|
264
|
+
// Hardcoded to show the school layer "8712" as a wfs.
|
|
265
|
+
// For better visibility adding of the other layers, especially "5001", should be commented out.
|
|
266
|
+
styleList.initializeStyleList({}, config, config.layers, undefined, (initializedStyleList, error) => {
|
|
267
|
+
if (error) {
|
|
268
|
+
console.error("Die Datei " + config.styleConf + " konnte nicht geladen werden!");
|
|
269
|
+
}
|
|
270
|
+
return initializedStyleList;
|
|
271
|
+
});
|
|
272
|
+
getWfsStyleFunction();
|
package/jest.config.js
CHANGED
|
@@ -3,7 +3,7 @@ module.exports = {
|
|
|
3
3
|
/** ol prints errors without HTMLCanvasElement being available in test environment */
|
|
4
4
|
"setupFiles": ["jest-canvas-mock"],
|
|
5
5
|
/** node_modules are usually ignored by babel-jest, but ol is published in ES6 */
|
|
6
|
-
"transformIgnorePatterns": ["/node_modules/(?!(ol|olcs|ol-mapbox-style|geotiff)/).*/"],
|
|
6
|
+
"transformIgnorePatterns": ["/node_modules/(?!(ol|olcs|ol-mapbox-style|geotiff|quick-lru)/).*/"],
|
|
7
7
|
/** only consider files in src/ for coverage */
|
|
8
8
|
"collectCoverageFrom": ["src/**/*.js"],
|
|
9
9
|
/** coverage reporters */
|
package/jest.setup.js
CHANGED
|
@@ -2,4 +2,12 @@ import "regenerator-runtime/runtime";
|
|
|
2
2
|
|
|
3
3
|
window.URL.createObjectURL = function () {
|
|
4
4
|
// empty
|
|
5
|
-
};
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
window.ResizeObserver =
|
|
8
|
+
window.ResizeObserver ||
|
|
9
|
+
jest.fn().mockImplementation(() => ({
|
|
10
|
+
disconnect: jest.fn(),
|
|
11
|
+
observe: jest.fn(),
|
|
12
|
+
unobserve: jest.fn()
|
|
13
|
+
}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masterportal/masterportalapi",
|
|
3
3
|
"author": "Implementierungspartnerschaft Masterportal <info@masterportal.org> (https://www.masterportal.org)",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.14.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Basic functions of the Masterportal as api",
|
|
7
7
|
"repository": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"core-js": "^3.27.1",
|
|
23
|
-
"ol": "7.
|
|
23
|
+
"ol": "7.2.2",
|
|
24
24
|
"olcs": "^2.13.1",
|
|
25
25
|
"proj4": "^2.8.1",
|
|
26
26
|
"xml2js": "^0.4.23"
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"process": "^0.11.10",
|
|
43
43
|
"sass": "^1.57.1",
|
|
44
44
|
"stream-browserify": "^3.0.0",
|
|
45
|
-
"timers-browserify": "^2.0.12"
|
|
45
|
+
"timers-browserify": "^2.0.12",
|
|
46
|
+
"use-resize-observer": "^9.1.0"
|
|
46
47
|
},
|
|
47
48
|
"peerDependencies": {
|
|
48
49
|
"cesium": "^1.95.0"
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import {getValueFromObjectByPath} from "./getValueFromObjectByPath.js";
|
|
2
|
+
import thousandsSeparator from "./thousandsSeparator";
|
|
3
|
+
/**
|
|
4
|
+
* checks if value starts with special prefix to determine if value is a object path
|
|
5
|
+
* @param {string} value string to check
|
|
6
|
+
* @returns {Boolean} true is value is an object path
|
|
7
|
+
*/
|
|
8
|
+
function isObjectPath (value) {
|
|
9
|
+
return typeof value === "string" && value.startsWith("@");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Returns the value of the given key. Also considers, that the key may be an object path.
|
|
13
|
+
* @param {Object} properties properties.
|
|
14
|
+
* @param {String} key Key to derive value from.
|
|
15
|
+
* @returns {*} - Value from key.
|
|
16
|
+
*/
|
|
17
|
+
function prepareValue (properties, key) {
|
|
18
|
+
const isPath = isObjectPath(key);
|
|
19
|
+
let value = properties[Object.keys(properties).find(propertiesKey => propertiesKey.toLowerCase() === key.toLowerCase())];
|
|
20
|
+
|
|
21
|
+
if (isPath) {
|
|
22
|
+
value = getValueFromObjectByPath(properties, key);
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Parsing the boolean value
|
|
29
|
+
* @param {String} value default value
|
|
30
|
+
* @param {String|Object} format the format of boolean value
|
|
31
|
+
* @returns {String} - original value or parsed value
|
|
32
|
+
*/
|
|
33
|
+
function getBooleanValue (value, format) {
|
|
34
|
+
let parsedValue = String(value);
|
|
35
|
+
|
|
36
|
+
if (Object.prototype.hasOwnProperty.call(format, value)) {
|
|
37
|
+
// TODO: check if true -> translation is dismissed because i18next does not exist in masterportalApi
|
|
38
|
+
parsedValue = format[value];
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
return parsedValue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Appends a suffix if available.
|
|
46
|
+
* @param {*} value Value to append suffix.
|
|
47
|
+
* @param {String} suffix Suffix
|
|
48
|
+
* @returns {String} - Value with suffix.
|
|
49
|
+
*/
|
|
50
|
+
function appendSuffix (value, suffix) {
|
|
51
|
+
let valueWithSuffix = value;
|
|
52
|
+
|
|
53
|
+
if (suffix) {
|
|
54
|
+
valueWithSuffix = String(valueWithSuffix) + " " + suffix;
|
|
55
|
+
}
|
|
56
|
+
return valueWithSuffix;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Prepend a prefix if available.
|
|
61
|
+
* @param {*} value Value to prepend prefix.
|
|
62
|
+
* @param {String} prefix Prefix
|
|
63
|
+
* @returns {String} - Value with prefix.
|
|
64
|
+
*/
|
|
65
|
+
function prependPrefix (value, prefix) {
|
|
66
|
+
let valueWithPrefix = value;
|
|
67
|
+
|
|
68
|
+
if (prefix) {
|
|
69
|
+
valueWithPrefix = prefix + String(valueWithPrefix);
|
|
70
|
+
}
|
|
71
|
+
return valueWithPrefix;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Derives the value from the given condition.
|
|
76
|
+
* @param {String} key Key.
|
|
77
|
+
* @param {String} condition Condition to filter.
|
|
78
|
+
* @param {Object} properties Properties.
|
|
79
|
+
* @returns {*} - Value that matches the given condition.
|
|
80
|
+
*/
|
|
81
|
+
function getValueFromCondition (key, condition, properties) {
|
|
82
|
+
let valueFromCondition,
|
|
83
|
+
match;
|
|
84
|
+
|
|
85
|
+
if (condition === "contains") {
|
|
86
|
+
match = Object.keys(properties).filter(key2 => {
|
|
87
|
+
return key2.includes(key);
|
|
88
|
+
})[0];
|
|
89
|
+
valueFromCondition = properties[match];
|
|
90
|
+
}
|
|
91
|
+
else if (condition === "startsWith") {
|
|
92
|
+
match = Object.keys(properties).filter(key2 => {
|
|
93
|
+
return key2.startsWith(key);
|
|
94
|
+
})[0];
|
|
95
|
+
valueFromCondition = properties[match];
|
|
96
|
+
}
|
|
97
|
+
else if (condition === "endsWith") {
|
|
98
|
+
match = Object.keys(properties).filter(key2 => {
|
|
99
|
+
return key2.endsWith(key);
|
|
100
|
+
})[0];
|
|
101
|
+
valueFromCondition = properties[match];
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
valueFromCondition = properties[key];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return valueFromCondition;
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Derives the gfi value if the value is an object.
|
|
113
|
+
* @param {*} key Key of Attribute.
|
|
114
|
+
* @param {Object} mappingObj Value of attribute.
|
|
115
|
+
* @param {Object} properties object.
|
|
116
|
+
* @returns {*} - Prepared Value
|
|
117
|
+
*/
|
|
118
|
+
function prepareValueFromObject (key, mappingObj, properties) {
|
|
119
|
+
const type = mappingObj?.type ? mappingObj.type : "string",
|
|
120
|
+
condition = mappingObj?.condition ? mappingObj.condition : null;
|
|
121
|
+
let preparedValue = prepareValue(properties, key),
|
|
122
|
+
format = mappingObj?.format ? mappingObj.format : "YYYY-MM-DDTHH:mm:ss.SSSZ",
|
|
123
|
+
date;
|
|
124
|
+
|
|
125
|
+
if (condition) {
|
|
126
|
+
preparedValue = getValueFromCondition(key, condition, properties);
|
|
127
|
+
}
|
|
128
|
+
switch (type) {
|
|
129
|
+
case "date": {
|
|
130
|
+
date = new Date(String(preparedValue));
|
|
131
|
+
if (!isNaN(date.getTime())) {
|
|
132
|
+
const year = date.getFullYear(),
|
|
133
|
+
month = ("0" + (date.getMonth() + 1)).slice(-2),
|
|
134
|
+
day = ("0" + date.getDate()).slice(-2);
|
|
135
|
+
|
|
136
|
+
if (format === "YYYY-MM-DDTHH:mm:ss.SSSZ") {
|
|
137
|
+
const offset = date.getTimezoneOffset();
|
|
138
|
+
|
|
139
|
+
let offsetHours = (offset / 60) % 24,
|
|
140
|
+
offsetMinutes = offset % 60;
|
|
141
|
+
|
|
142
|
+
offsetHours = offsetHours < 0 ? "+" + ("0" + Math.abs(offsetHours)).slice(-2) : "-" + ("0" + Math.abs(offsetHours)).slice(-2);
|
|
143
|
+
offsetMinutes = offsetMinutes < 0 ? ":" + ("0" + Math.abs(offsetMinutes)).slice(-2) : ":" + ("0" + offsetMinutes).slice(-2);
|
|
144
|
+
preparedValue = date.toISOString().slice(0, -1) + offsetHours + offsetMinutes;
|
|
145
|
+
}
|
|
146
|
+
else if (format === "YYYY-MM-DD") {
|
|
147
|
+
preparedValue = year + "-" + month + "-" + day;
|
|
148
|
+
}
|
|
149
|
+
else if (format === "DD-MM-YYYY") {
|
|
150
|
+
preparedValue = day + "-" + month + "-" + year;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.error("The format must be 'YYYY-MM-DD' or 'DD-MM-YYYY', if the attribute is missing, ISO 8601 is used.");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case "number": {
|
|
159
|
+
preparedValue = thousandsSeparator(preparedValue);
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "linechart": {
|
|
163
|
+
preparedValue = Object.assign({
|
|
164
|
+
name: key,
|
|
165
|
+
staObject: preparedValue
|
|
166
|
+
}, mappingObj);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case "boolean": {
|
|
170
|
+
format = format === "DD.MM.YYYY HH:mm:ss" ? {true: "true", false: "false"} : format;
|
|
171
|
+
preparedValue = getBooleanValue(preparedValue, format);
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
// default equals to mappingObj.type === "string"
|
|
175
|
+
default: {
|
|
176
|
+
preparedValue = String(preparedValue);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (preparedValue && mappingObj.suffix && preparedValue !== "undefined") {
|
|
180
|
+
preparedValue = appendSuffix(preparedValue, mappingObj.suffix);
|
|
181
|
+
}
|
|
182
|
+
if (preparedValue && mappingObj.prefix && preparedValue !== "undefined") {
|
|
183
|
+
preparedValue = prependPrefix(preparedValue, mappingObj.prefix);
|
|
184
|
+
}
|
|
185
|
+
return preparedValue;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Maps the feature properties by the given object.
|
|
190
|
+
* @param {Object} properties The feature properties.
|
|
191
|
+
* @param {Object} mappingObject Object to me mapped.
|
|
192
|
+
* @param {Boolean} [isNested=true] Flag if Object is nested, like "gfiAttributes".
|
|
193
|
+
* @returns {Object} The mapped properties.
|
|
194
|
+
*/
|
|
195
|
+
function mapAttributes (properties, mappingObject, isNested = true) {
|
|
196
|
+
let mappedProperties;
|
|
197
|
+
|
|
198
|
+
if (!mappingObject) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
if (!isNested) {
|
|
202
|
+
if (typeof mappingObject === "string") {
|
|
203
|
+
mappedProperties = prepareValue(properties, mappingObject);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
mappedProperties = prepareValueFromObject(mappingObject.name, mappingObject, properties);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
mappedProperties = {};
|
|
211
|
+
Object.keys(mappingObject).forEach(key => {
|
|
212
|
+
let newKey = mappingObject[key],
|
|
213
|
+
value = prepareValue(properties, key);
|
|
214
|
+
|
|
215
|
+
if (typeof newKey === "object") {
|
|
216
|
+
value = prepareValueFromObject(key, newKey, properties);
|
|
217
|
+
newKey = newKey.name;
|
|
218
|
+
}
|
|
219
|
+
if (value && value !== "undefined") {
|
|
220
|
+
mappedProperties[newKey] = value;
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return mappedProperties;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export {
|
|
228
|
+
mapAttributes,
|
|
229
|
+
isObjectPath,
|
|
230
|
+
prepareValue
|
|
231
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gets the parts of the given path splitted by ".", ignoring escaped "."
|
|
3
|
+
* @param {String} path the path to split
|
|
4
|
+
* @param {String} [delimitor="."] the delimitor to use
|
|
5
|
+
* @returns {String[]} the resulting parts of the path
|
|
6
|
+
*/
|
|
7
|
+
function getPathPartsFromPath (path, delimitor = ".") {
|
|
8
|
+
const len = path.length,
|
|
9
|
+
result = [];
|
|
10
|
+
let letter = "",
|
|
11
|
+
word = "";
|
|
12
|
+
|
|
13
|
+
for (let i = 0; i < len; i++) {
|
|
14
|
+
letter = path[i];
|
|
15
|
+
|
|
16
|
+
if (letter === "\\") {
|
|
17
|
+
i++;
|
|
18
|
+
letter = path[i];
|
|
19
|
+
}
|
|
20
|
+
else if (letter === delimitor) {
|
|
21
|
+
result.push(word);
|
|
22
|
+
word = "";
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
word += letter;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (word) {
|
|
29
|
+
result.push(word);
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* uses the given path to go into the given object and returns the value found at the end
|
|
35
|
+
* @info arrays can be accessed by using a number as index (e.g. "@Test.0.test")
|
|
36
|
+
* @param {Object} obj an object or array to search through
|
|
37
|
+
* @param {String} path the path to follow through the given object
|
|
38
|
+
* @param {String} [prefix="@"] the prefix to use to recognize the string as path to follow
|
|
39
|
+
* @param {String} [delimitor="."] the delimitor to use
|
|
40
|
+
* @param {Number} [depthBarrier=20] the depth barrier to avoid infinit recurtions
|
|
41
|
+
* @returns {*} any value found at the end or undefined if nothing was found
|
|
42
|
+
*/
|
|
43
|
+
function getValueFromObjectByPath (obj, path, prefix = "@", delimitor = ".", depthBarrier = 20) {
|
|
44
|
+
if (
|
|
45
|
+
typeof obj !== "object"
|
|
46
|
+
|| obj === null
|
|
47
|
+
|| typeof path !== "string"
|
|
48
|
+
|| (
|
|
49
|
+
typeof prefix === "string"
|
|
50
|
+
&& path.substr(0, prefix.length) !== prefix
|
|
51
|
+
)
|
|
52
|
+
) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const pathParts = getPathPartsFromPath(typeof prefix === "string" ? path.substring(prefix.length) : path, delimitor),
|
|
56
|
+
len = pathParts.length;
|
|
57
|
+
let value = obj,
|
|
58
|
+
depth = 0;
|
|
59
|
+
|
|
60
|
+
for (let i = 0; i < len; i++) {
|
|
61
|
+
if (typeof value !== "object" || value === null) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
value = value[pathParts[i]];
|
|
65
|
+
depth++;
|
|
66
|
+
if (typeof value === "undefined" || depth > depthBarrier) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {getValueFromObjectByPath, getPathPartsFromPath};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* adds thousands seperators into a number and changes the decimal point
|
|
4
|
+
* @param {(Number|String)} num the number as number or string
|
|
5
|
+
* @param {String} [delimAbs="."] the letter(s) to use as thousand point
|
|
6
|
+
* @param {String} [delimDec=","] the letter(s) to use as decimal point
|
|
7
|
+
* @returns {String} the given number with thousands seperators or an empty string if any invalid num was given
|
|
8
|
+
*/
|
|
9
|
+
function thousandsSeparator (num, delimAbs = ".", delimDec = ",") {
|
|
10
|
+
if (typeof num !== "number" && typeof num !== "string") {
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const value = typeof num !== "string" ? num.toString() : num,
|
|
15
|
+
decPointPos = value.indexOf("."),
|
|
16
|
+
abs = decPointPos > -1 ? value.substring(0, decPointPos) : value,
|
|
17
|
+
result = abs.replace(/\B(?=(\d{3})+(?!\d),?.*)/g, delimAbs),
|
|
18
|
+
dec = decPointPos > -1 ? value.substring(decPointPos + 1) : false;
|
|
19
|
+
|
|
20
|
+
return dec ? result + delimDec + dec : result;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default thousandsSeparator;
|