Merge branch 'develop' into release/0.9.0

This commit is contained in:
jwu-fisker
2023-05-18 14:55:17 -07:00
12 changed files with 571 additions and 23 deletions

View File

@@ -497,17 +497,17 @@ exports[`App Route / authenticated 1`] = `
North America
</option>
<option
value="{ \\"center\\": [33.8463, -118.0461], \\"zoom\\": 10 }"
value="{ \\"center\\": [33.8623, -118.0295], \\"zoom\\": 14 }"
>
- La Palma
</option>
<option
value="{ \\"center\\": [33.8847, -118.4109], \\"zoom\\": 10 }"
value="{ \\"center\\": [33.9021, -118.3792], \\"zoom\\": 14 }"
>
- Manhattan Beach
</option>
<option
value="{ \\"center\\": [37.7749, -122.4194], \\"zoom\\": 10 }"
value="{ \\"center\\": [37.7637, -122.4197], \\"zoom\\": 14 }"
>
- San Francisco
</option>
@@ -517,7 +517,7 @@ exports[`App Route / authenticated 1`] = `
Europe
</option>
<option
value="{ \\"center\\": [47.0707, 15.4395], \\"zoom\\": 10 }"
value="{ \\"center\\": [47.0221, 15.4774], \\"zoom\\": 14 }"
>
- Graz
</option>
@@ -1894,17 +1894,17 @@ exports[`App Route /home authenticated 1`] = `
North America
</option>
<option
value="{ \\"center\\": [33.8463, -118.0461], \\"zoom\\": 10 }"
value="{ \\"center\\": [33.8623, -118.0295], \\"zoom\\": 14 }"
>
- La Palma
</option>
<option
value="{ \\"center\\": [33.8847, -118.4109], \\"zoom\\": 10 }"
value="{ \\"center\\": [33.9021, -118.3792], \\"zoom\\": 14 }"
>
- Manhattan Beach
</option>
<option
value="{ \\"center\\": [37.7749, -122.4194], \\"zoom\\": 10 }"
value="{ \\"center\\": [37.7637, -122.4197], \\"zoom\\": 14 }"
>
- San Francisco
</option>
@@ -1914,7 +1914,7 @@ exports[`App Route /home authenticated 1`] = `
Europe
</option>
<option
value="{ \\"center\\": [47.0707, 15.4395], \\"zoom\\": 10 }"
value="{ \\"center\\": [47.0221, 15.4774], \\"zoom\\": 14 }"
>
- Graz
</option>
@@ -5411,6 +5411,114 @@ exports[`App Route /package-status authenticated 1`] = `
</a>
</td>
</tr>
<tr
class="MuiTableRow-root"
>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
2
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
style="vertical-align: top;"
>
<a
href="/vehicle-status/1G1FP87S3GN100062"
>
1G1FP87S3GN100062
</a>
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
downloaded
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
7/1/2021 10:40:07 PM
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
7/12/2021 6:22:13 PM
</td>
<td
class="MuiTableCell-root MuiTableCell-body"
>
<a
class=""
href="/package-status/1"
title="Send cancel for 1G1FP87S3GN100062"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"
/>
</svg>
</a>
</td>
</tr>
<tr
class="MuiTableRow-root"
>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
3
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
style="vertical-align: top;"
>
<a
href="/vehicle-status/1G1FP87S3GN100062"
>
1G1FP87S3GN100062
</a>
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
downloaded
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
7/1/2021 10:40:07 PM
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
7/12/2021 6:22:13 PM
</td>
<td
class="MuiTableCell-root MuiTableCell-body"
>
<a
class=""
href="/package-status/1"
title="Send cancel for 1G1FP87S3GN100062"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"
/>
</svg>
</a>
</td>
</tr>
</tbody>
<tfoot
class="MuiTableFooter-root"
@@ -5481,7 +5589,7 @@ exports[`App Route /package-status authenticated 1`] = `
<p
class="MuiTypography-root MuiTablePagination-caption MuiTypography-body2 MuiTypography-colorInherit"
>
1-1 of 1
1-2 of 2
</p>
<div
class="MuiTablePagination-actions"

View File

@@ -219,6 +219,17 @@ exports[`DigitalTwinTab Render 1`] = `
d439abd3662dd20099f49dd8f43f7b145202e961caa2b5aba2c6154c8096348b
</p>
</div>
<div
class="makeStyles-popupSection-0"
>
<p>
<b>
Vehicle Speed
</b>
:
77.7
</p>
</div>
</div>
<div
style="width: 100vh;"

View File

@@ -23,8 +23,46 @@ let carUpdates = [
updated: "2021-08-20T18:37:50.007853Z",
},
},
{
id: 2,
vin: "1G1FP87S3GN100062",
manifest_id: 285,
status: "downloaded",
msg: "downloaded",
created: "2021-07-01T22:40:07.778509Z",
updated: "2021-07-12T18:22:13.736755Z",
updatemanifest: {
id: 285,
name: "TEST UPDATE",
version: "1000",
description: "UPDATE DESCRIPTION",
release_notes: "https://releasenotes.com",
ecu_list: "AGS 1.0.0,AMP 1.0.0",
created: "2021-08-20T18:37:41.960397Z",
updated: "2021-08-20T18:37:50.007853Z",
},
},
{
id: 3,
vin: "1G1FP87S3GN100062",
manifest_id: 286,
status: "downloaded",
msg: "downloaded",
created: "2021-07-01T22:40:07.778509Z",
updated: "2021-07-12T18:22:13.736755Z",
updatemanifest: {
id: 286,
name: "TEST UPDATE",
version: "1000",
description: "UPDATE DESCRIPTION",
release_notes: "https://releasenotes.com",
ecu_list: "AGS 1.0.0,AMP 1.0.0",
created: "2021-08-20T18:37:41.960397Z",
updated: "2021-08-20T18:37:50.007853Z",
},
},
];
let totalCarUpdates = 1;
let totalCarUpdates = 2;
let carUpdateLog = {
data: [
{
@@ -56,6 +94,26 @@ let carUpdateLog = {
created: "2021-08-23T17:06:38.030052Z",
updated: "2021-08-23T17:06:38.030052Z",
},
{
id: 87,
carupdate_id: 285,
username: "test username 2",
status: "install_scheduled",
error_code: 0,
info: "TEST",
created: "2021-08-23T17:06:38.030052Z",
updated: "2021-08-23T17:06:38.030052Z",
},
{
id: 86,
carupdate_id: 286,
username: "test username 2",
status: "requirements_failed",
error_code: 0,
info: "TEST",
created: "2021-08-23T17:06:38.030052Z",
updated: "2021-08-23T17:06:38.030052Z",
},
],
total: 3,
};

View File

@@ -73,6 +73,9 @@ let vehicleState = {
dbc_version: "d439abd3662dd20099f49dd8f43f7b145202e961caa2b5aba2c6154c8096348b",
ip: "172.20.0.17:49850",
updated: "2022-07-26T00:26:38.880381Z",
vehicle_speed: {
speed: 77.7,
},
},
};
@@ -144,7 +147,7 @@ export const useVehicleContext = () => ({
getModels: jest.fn(() => {
models = ["Ocean", "PEAR"];
}),
getState: jest.fn(() => vehicleState),
getState: jest.fn().mockResolvedValue(vehicleState),
getYears: jest.fn(() => {
years = [2023, 2024];
}),

View File

@@ -13,7 +13,7 @@ const TestWrapper = ({ status }) => {
const renderCarUpdateStatusProgress = async (status) => {
const { container } = render(<TestWrapper status={status} />);
await waitFor(() => {});
await waitFor(() => { });
return container;
};
@@ -144,6 +144,28 @@ describe("CarUpdateStatusProgress", () => {
err: 0,
},
},
{
name: "install_scheduled",
status: {
car_update_id: 1,
ecu: "TEST",
installed: 5,
total_files: 10,
msg: s.InstallSucceeded,
err: 0,
},
},
{
name: "requirements_failed",
status: {
car_update_id: 1,
ecu: "TEST",
installed: 5,
total_files: 10,
msg: s.InstallFailed,
err: 0,
},
},
];
for (let i = 0, len = tests.length; i < len; i++) {
const test = tests[i];

View File

@@ -34,6 +34,8 @@ const Statuses = {
PackageDownloadCompleted: "package_download_complete",
PackageInstallStarted: "package_install_start",
PackageInstallCompleted: "package_install_complete",
RequirementsFailed: "requirements_failed",
InstallScheduled: "install_scheduled",
};
export default Statuses;

View File

@@ -994,6 +994,148 @@ exports[`CarUpdateStatusProgress Render install_error 1`] = `
</div>
`;
exports[`CarUpdateStatusProgress Render install_scheduled 1`] = `
<div>
<div
style="width: 100%; display: flex; justify-content: space-between; flex-wrap: wrap;"
>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Pending
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Received
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Precondition
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Download
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Approved
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Install
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Updated
</p>
</div>
</div>
</div>
`;
exports[`CarUpdateStatusProgress Render installing 1`] = `
<div>
<div
@@ -1561,3 +1703,145 @@ exports[`CarUpdateStatusProgress Render package_download_complete 1`] = `
</div>
</div>
`;
exports[`CarUpdateStatusProgress Render requirements_failed 1`] = `
<div>
<div
style="width: 100%; display: flex; justify-content: space-between; flex-wrap: wrap;"
>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Pending
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Received
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Precondition
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Download
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressSuccess-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Approved
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0 makeStyles-progressError-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Install
</p>
</div>
<div
class="makeStyles-textCenterAlign-0"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root makeStyles-progressIcon-0"
focusable="false"
viewBox="0 0 24 24"
>
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
/>
</svg>
<p
class="MuiTypography-root MuiTypography-body1"
>
Updated
</p>
</div>
</div>
</div>
`;

View File

@@ -56,9 +56,11 @@ const PHASES = [
s.Installing,
s.InstallSucceeded,
s.InstallFailed,
s.RequirementsFailed,
s.InstallScheduled,
],
progress: (msg, progress) => {
if (msg === s.InstallFailed) return ErrorStatus;
if (msg === s.InstallFailed || msg === s.RequirementsFailed) return ErrorStatus;
if (msg === s.PackageInstallCompleted) return CompleteStatus;
return progress;
},

View File

@@ -175,6 +175,50 @@ exports[`CarUpdateStatusTable Render 1`] = `
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
/>
</tr>
<tr
class="MuiTableRow-root"
>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
8/23/2021 5:06:38 PM
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
install_scheduled
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
TEST
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
/>
</tr>
<tr
class="MuiTableRow-root"
>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
8/23/2021 5:06:38 PM
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
requirements_failed
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
>
TEST
</td>
<td
class="MuiTableCell-root MuiTableCell-body MuiTableCell-alignCenter"
/>
</tr>
</tbody>
<tfoot
class="MuiTableFooter-root"

View File

@@ -27,7 +27,7 @@ const windowState = (value) => {
const DigitalTwin = (props) => {
const classes = useStyles();
const { battery, doors, location, trex_version, ip, updated, windows, misc_windows, sunroof, dbc_version, door_locks, vcu0x260, charging_metrics, max_range } = props;
const { battery, doors, location, trex_version, ip, updated, windows, misc_windows, sunroof, dbc_version, door_locks, vcu0x260, charging_metrics, max_range, vehicle_speed } = props;
return (
<div>
@@ -122,6 +122,11 @@ const DigitalTwin = (props) => {
{keyValueTemplate("DBC Version", dbc_version)}
</div>
)}
{vehicle_speed && (
<div className={classes.popupSection}>
{keyValueTemplate("Vehicle Speed", vehicle_speed.speed)}
</div>
)}
</div>
);
};

View File

@@ -12,6 +12,7 @@ import { ValidateLocationData } from "../../utils/locations";
import { useUserContext } from "../Contexts/UserContext";
import { useVehicleContext, VehicleProvider } from "../Contexts/VehicleContext";
import { VehiclePopUp } from "./popup";
import { useLocalStorage } from "../useLocalStorage";
import zoomLocations from './zoomLocations.json';
const Component = () => {
@@ -29,6 +30,7 @@ const Component = () => {
const [zoom, setZoom] = useState(2);
const [markers, setMarkers] = useState([]);
const [connections, setConnections] = useState({});
const [lastMapCenter, setLastMapCenter] = useLocalStorage("MAP_CENTER", "");
useEffect(() => {
if (!token) return;
@@ -62,10 +64,16 @@ const Component = () => {
};
const centerAroundMarkers = (points) => {
let defaultLocationJSON = process.env.REACT_APP_HOME_MAP_DEFAULT_LOCATION;
let defaultLocation = JSON.parse(defaultLocationJSON)
setCenter([defaultLocation.lat, defaultLocation.lng]);
setZoom(defaultLocation.zoom);
if (lastMapCenter) {
let zoomLocation = JSON.parse(lastMapCenter)
setCenter(zoomLocation.center);
setZoom(zoomLocation.zoom)
} else {
let defaultLocationJSON = process.env.REACT_APP_HOME_MAP_DEFAULT_LOCATION;
let defaultLocation = JSON.parse(defaultLocationJSON)
setCenter([defaultLocation.lat, defaultLocation.lng]);
setZoom(defaultLocation.zoom);
}
};
useEffect(() => {
@@ -105,6 +113,7 @@ const Component = () => {
};
const focusMap = (e) => {
setLastMapCenter(e.target.value)
let zoomLocation = JSON.parse(e.target.value)
setCenter(zoomLocation.center);
setZoom(zoomLocation.zoom)
@@ -145,7 +154,7 @@ const Component = () => {
return (
<>
<DropDownList label="Zoom To" data={zoomLocations} classes={classes} onChange={focusMap} />
<DropDownList label="Zoom To" data={zoomLocations} classes={classes} onChange={focusMap} value={lastMapCenter} />
<MapContainer
center={center}
zoom={zoom}

View File

@@ -4,15 +4,15 @@
"label": "North America"
},
{
"value": "{ \"center\": [33.8463, -118.0461], \"zoom\": 10 }",
"value": "{ \"center\": [33.8623, -118.0295], \"zoom\": 14 }",
"label": "- La Palma"
},
{
"value": "{ \"center\": [33.8847, -118.4109], \"zoom\": 10 }",
"value": "{ \"center\": [33.9021, -118.3792], \"zoom\": 14 }",
"label": "- Manhattan Beach"
},
{
"value": "{ \"center\": [37.7749, -122.4194], \"zoom\": 10 }",
"value": "{ \"center\": [37.7637, -122.4197], \"zoom\": 14 }",
"label": "- San Francisco"
},
{
@@ -20,7 +20,7 @@
"label": "Europe"
},
{
"value": "{ \"center\": [47.0707, 15.4395], \"zoom\": 10 }",
"value": "{ \"center\": [47.0221, 15.4774], \"zoom\": 14 }",
"label": "- Graz"
}
]