MAPG-103 save map metadata
This commit is contained in:
parent
46ef7f3b3b
commit
fbab712496
@ -1,3 +1,17 @@
|
|||||||
|
#metadata {
|
||||||
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
left: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border: solid 1px #555555;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
opacity: 0.95;
|
||||||
|
z-index: 2;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
#map {
|
#map {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100% - 40px);
|
height: calc(100% - 40px);
|
||||||
@ -28,12 +42,15 @@
|
|||||||
|
|
||||||
#control {
|
#control {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 50px;
|
||||||
|
right: 10px;
|
||||||
width: 125px;
|
width: 125px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#placeControl {
|
#placeControl {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@ -44,6 +61,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 999px) and (min-height: 600px) {
|
@media screen and (max-width: 999px) and (min-height: 600px) {
|
||||||
|
#metadata {
|
||||||
|
width: calc(100% - 155px);
|
||||||
|
}
|
||||||
#map.selected {
|
#map.selected {
|
||||||
height: calc(50% - 20px);
|
height: calc(50% - 20px);
|
||||||
}
|
}
|
||||||
@ -53,17 +73,18 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
height: calc(50% - 20px);
|
height: calc(50% - 20px);
|
||||||
}
|
}
|
||||||
#control {
|
|
||||||
right: 10px;
|
|
||||||
top: 50px;
|
|
||||||
}
|
|
||||||
#placeControl {
|
#placeControl {
|
||||||
right: 10px;
|
|
||||||
top: calc(50% + 30px);
|
top: calc(50% + 30px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1000px), (max-height: 599px) {
|
@media screen and (min-width: 1000px), (max-height: 599px) {
|
||||||
|
#metadata {
|
||||||
|
width: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
#metadata.selected {
|
||||||
|
top: 95px;
|
||||||
|
}
|
||||||
#map.selected {
|
#map.selected {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
@ -73,12 +94,13 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
#control, #placeControl {
|
#placeControl {
|
||||||
right: 10px;
|
|
||||||
top: 50px;
|
top: 50px;
|
||||||
}
|
}
|
||||||
|
#modified.selected {
|
||||||
|
right: calc(50% + 10px);
|
||||||
|
}
|
||||||
#control.selected {
|
#control.selected {
|
||||||
right: calc(50% + 10px);
|
right: calc(50% + 10px);
|
||||||
top: 50px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var MapEditor = {
|
var MapEditor = {
|
||||||
|
metadata: {
|
||||||
|
name: null,
|
||||||
|
description: null
|
||||||
|
},
|
||||||
map: null,
|
map: null,
|
||||||
panorama: null,
|
panorama: null,
|
||||||
selectedMarker: null,
|
selectedMarker: null,
|
||||||
@ -9,6 +13,19 @@
|
|||||||
edited: {},
|
edited: {},
|
||||||
deleted: {},
|
deleted: {},
|
||||||
|
|
||||||
|
editMetadata: function () {
|
||||||
|
var form = document.getElementById('metadataForm');
|
||||||
|
|
||||||
|
MapEditor.metadata.name = form.elements.name.value;
|
||||||
|
MapEditor.metadata.description = form.elements.description.value;
|
||||||
|
|
||||||
|
document.getElementById('mapName').innerHTML = form.elements.name.value ? form.elements.name.value : '[unnamed map]';
|
||||||
|
|
||||||
|
document.getElementById('metadata').style.visibility = 'hidden';
|
||||||
|
|
||||||
|
document.getElementById('saveButton').disabled = false;
|
||||||
|
},
|
||||||
|
|
||||||
getPlace: function (placeId, marker) {
|
getPlace: function (placeId, marker) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.responseType = 'json';
|
xhr.responseType = 'json';
|
||||||
@ -92,9 +109,11 @@
|
|||||||
|
|
||||||
select: function (marker) {
|
select: function (marker) {
|
||||||
if (MapEditor.selectedMarker === marker) {
|
if (MapEditor.selectedMarker === marker) {
|
||||||
|
MapEditor.closePlace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('metadata').classList.add('selected');
|
||||||
document.getElementById('map').classList.add('selected');
|
document.getElementById('map').classList.add('selected');
|
||||||
document.getElementById('control').classList.add('selected');
|
document.getElementById('control').classList.add('selected');
|
||||||
document.getElementById('noPano').style.visibility = 'hidden';
|
document.getElementById('noPano').style.visibility = 'hidden';
|
||||||
@ -141,14 +160,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
resetSelected: function () {
|
resetSelected: function (del) {
|
||||||
if (!MapEditor.selectedMarker) {
|
if (!MapEditor.selectedMarker) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var placeId = MapEditor.selectedMarker.placeId
|
var placeId = MapEditor.selectedMarker.placeId
|
||||||
|
|
||||||
if (places[placeId].id) {
|
if (places[placeId].id && !del) {
|
||||||
MapEditor.selectedMarker.setIcon(places[placeId].noPano ? IconCollection.iconRed : IconCollection.iconGreen);
|
MapEditor.selectedMarker.setIcon(places[placeId].noPano ? IconCollection.iconRed : IconCollection.iconGreen);
|
||||||
MapEditor.selectedMarker.setZIndexOffset(1000);
|
MapEditor.selectedMarker.setZIndexOffset(1000);
|
||||||
} else {
|
} else {
|
||||||
@ -191,29 +210,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
MapEditor.selectedMarker.setLatLng({ lat: places[placeId].lat, lng: places[placeId].lng });
|
MapEditor.selectedMarker.setLatLng({ lat: places[placeId].lat, lng: places[placeId].lng });
|
||||||
|
|
||||||
|
document.getElementById('saveButton').disabled = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
closePlace: function () {
|
closePlace: function (del) {
|
||||||
|
document.getElementById('metadata').classList.remove('selected')
|
||||||
document.getElementById('map').classList.remove('selected');
|
document.getElementById('map').classList.remove('selected');
|
||||||
document.getElementById('control').classList.remove('selected');
|
document.getElementById('control').classList.remove('selected');
|
||||||
document.getElementById('noPano').style.visibility = 'hidden';
|
document.getElementById('noPano').style.visibility = 'hidden';
|
||||||
document.getElementById('panorama').style.visibility = 'hidden';
|
document.getElementById('panorama').style.visibility = 'hidden';
|
||||||
document.getElementById('placeControl').style.visibility = 'hidden';
|
document.getElementById('placeControl').style.visibility = 'hidden';
|
||||||
|
|
||||||
MapEditor.resetSelected();
|
MapEditor.resetSelected(del);
|
||||||
MapEditor.selectedMarker = null;
|
MapEditor.selectedMarker = null;
|
||||||
|
|
||||||
MapEditor.map.invalidateSize(true);
|
MapEditor.map.invalidateSize(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
deletePlace: function () {
|
deletePlace: function () {
|
||||||
document.getElementById('map').classList.remove('selected');
|
|
||||||
document.getElementById('control').classList.remove('selected');
|
|
||||||
document.getElementById('noPano').style.visibility = 'hidden';
|
|
||||||
document.getElementById('panorama').style.visibility = 'hidden';
|
|
||||||
document.getElementById('placeControl').style.visibility = 'hidden';
|
|
||||||
document.getElementById('deleteButton').style.display = 'none';
|
|
||||||
|
|
||||||
var placeId = MapEditor.selectedMarker.placeId;
|
var placeId = MapEditor.selectedMarker.placeId;
|
||||||
|
|
||||||
if (places[placeId].id && !MapEditor.added[placeId]) {
|
if (places[placeId].id && !MapEditor.added[placeId]) {
|
||||||
@ -222,23 +237,29 @@
|
|||||||
document.getElementById('deleted').innerHTML = String(Object.keys(MapEditor.deleted).length);
|
document.getElementById('deleted').innerHTML = String(Object.keys(MapEditor.deleted).length);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete places[placeId];
|
MapEditor.closePlace(true);
|
||||||
|
|
||||||
delete MapEditor.added[placeId];
|
delete MapEditor.added[placeId];
|
||||||
delete MapEditor.edited[placeId];
|
delete MapEditor.edited[placeId];
|
||||||
|
|
||||||
document.getElementById('added').innerHTML = String(Object.keys(MapEditor.added).length);
|
document.getElementById('added').innerHTML = String(Object.keys(MapEditor.added).length);
|
||||||
document.getElementById('edited').innerHTML = String(Object.keys(MapEditor.edited).length);
|
document.getElementById('edited').innerHTML = String(Object.keys(MapEditor.edited).length);
|
||||||
|
|
||||||
MapEditor.map.removeLayer(MapEditor.selectedMarker);
|
document.getElementById('saveButton').disabled = false;
|
||||||
MapEditor.selectedMarker = null;
|
|
||||||
|
|
||||||
MapEditor.map.invalidateSize(true);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
saveMap: function () {
|
saveMap: function () {
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
|
|
||||||
var data = new FormData();
|
var data = new FormData();
|
||||||
|
|
||||||
|
if (MapEditor.metadata.name !== null) {
|
||||||
|
data.append('name', MapEditor.metadata.name);
|
||||||
|
}
|
||||||
|
if (MapEditor.metadata.description !== null) {
|
||||||
|
data.append('description', MapEditor.metadata.description);
|
||||||
|
}
|
||||||
|
|
||||||
for (var placeId in MapEditor.added) {
|
for (var placeId in MapEditor.added) {
|
||||||
if (!MapEditor.added.hasOwnProperty(placeId)) {
|
if (!MapEditor.added.hasOwnProperty(placeId)) {
|
||||||
continue;
|
continue;
|
||||||
@ -277,6 +298,8 @@
|
|||||||
document.getElementById('added').innerHTML = '0';
|
document.getElementById('added').innerHTML = '0';
|
||||||
document.getElementById('edited').innerHTML = '0';
|
document.getElementById('edited').innerHTML = '0';
|
||||||
document.getElementById('deleted').innerHTML = '0';
|
document.getElementById('deleted').innerHTML = '0';
|
||||||
|
|
||||||
|
document.getElementById('saveButton').disabled = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.open('POST', '/admin/saveMap/' + mapId + '/json', true);
|
xhr.open('POST', '/admin/saveMap/' + mapId + '/json', true);
|
||||||
@ -381,6 +404,29 @@
|
|||||||
motionTracking: false
|
motionTracking: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('mapName').onclick = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var metadata = document.getElementById('metadata');
|
||||||
|
|
||||||
|
if (metadata.style.visibility === 'visible') {
|
||||||
|
metadata.style.visibility = 'hidden';
|
||||||
|
} else {
|
||||||
|
metadata.style.visibility = 'visible';
|
||||||
|
document.getElementById('metadataForm').elements.name.select();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('metadataForm').onsubmit = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
MapEditor.editMetadata();
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById('closeMetadataButton').onclick = function () {
|
||||||
|
document.getElementById('metadata').style.visibility = 'hidden';
|
||||||
|
};
|
||||||
|
|
||||||
document.getElementById('saveButton').onclick = function () {
|
document.getElementById('saveButton').onclick = function () {
|
||||||
MapEditor.saveMap();
|
MapEditor.saveMap();
|
||||||
};
|
};
|
||||||
@ -389,7 +435,7 @@
|
|||||||
MapEditor.applyPlace();
|
MapEditor.applyPlace();
|
||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById('cancelButton').onclick = function () {
|
document.getElementById('closeButton').onclick = function () {
|
||||||
MapEditor.closePlace();
|
MapEditor.closePlace();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ use MapGuesser\Interfaces\Authorization\ISecured;
|
|||||||
use MapGuesser\Interfaces\Database\IResultSet;
|
use MapGuesser\Interfaces\Database\IResultSet;
|
||||||
use MapGuesser\Interfaces\Request\IRequest;
|
use MapGuesser\Interfaces\Request\IRequest;
|
||||||
use MapGuesser\Interfaces\Response\IContent;
|
use MapGuesser\Interfaces\Response\IContent;
|
||||||
|
use MapGuesser\Repository\MapRepository;
|
||||||
use MapGuesser\Repository\PlaceRepository;
|
use MapGuesser\Repository\PlaceRepository;
|
||||||
use MapGuesser\Response\HtmlContent;
|
use MapGuesser\Response\HtmlContent;
|
||||||
use MapGuesser\Response\JsonContent;
|
use MapGuesser\Response\JsonContent;
|
||||||
@ -18,11 +19,14 @@ class MapAdminController implements ISecured
|
|||||||
{
|
{
|
||||||
private IRequest $request;
|
private IRequest $request;
|
||||||
|
|
||||||
|
private MapRepository $mapRepository;
|
||||||
|
|
||||||
private PlaceRepository $placeRepository;
|
private PlaceRepository $placeRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
|
$this->mapRepository = new MapRepository();
|
||||||
$this->placeRepository = new PlaceRepository();
|
$this->placeRepository = new PlaceRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,11 +48,11 @@ class MapAdminController implements ISecured
|
|||||||
{
|
{
|
||||||
$mapId = (int) $this->request->query('mapId');
|
$mapId = (int) $this->request->query('mapId');
|
||||||
|
|
||||||
$bounds = $this->getMapBounds($mapId);
|
$map = $this->mapRepository->getById($mapId);
|
||||||
|
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
||||||
$places = $this->getPlaces($mapId);
|
$places = $this->getPlaces($mapId);
|
||||||
|
|
||||||
$data = ['mapId' => $mapId, 'bounds' => $bounds->toArray(), 'places' => &$places];
|
$data = ['mapId' => $mapId, 'mapName' => $map['name'], 'mapDescription' => str_replace('<br>', '\n', $map['description']), 'bounds' => $bounds->toArray(), 'places' => &$places];
|
||||||
return new HtmlContent('admin/map_editor', $data);
|
return new HtmlContent('admin/map_editor', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,25 +113,19 @@ class MapAdminController implements ISecured
|
|||||||
'bound_east_lng' => $mapBounds->getEastLng()
|
'bound_east_lng' => $mapBounds->getEastLng()
|
||||||
];
|
];
|
||||||
|
|
||||||
|
if (isset($_POST['name'])) {
|
||||||
|
$map['name'] = $_POST['name'] ? $_POST['name'] : '[unnamed map]';
|
||||||
|
}
|
||||||
|
if (isset($_POST['description'])) {
|
||||||
|
$map['description'] = str_replace(['\n', '\r\n'], '<br>', $_POST['description']);
|
||||||
|
}
|
||||||
|
|
||||||
$this->saveMapData($mapId, $map);
|
$this->saveMapData($mapId, $map);
|
||||||
|
|
||||||
$data = ['added' => $addedIds];
|
$data = ['added' => $addedIds];
|
||||||
return new JsonContent($data);
|
return new JsonContent($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getMapBounds(int $mapId): Bounds
|
|
||||||
{
|
|
||||||
$select = new Select(\Container::$dbConnection, 'maps');
|
|
||||||
$select->columns(['bound_south_lat', 'bound_west_lng', 'bound_north_lat', 'bound_east_lng']);
|
|
||||||
$select->whereId($mapId);
|
|
||||||
|
|
||||||
$map = $select->execute()->fetch(IResultSet::FETCH_ASSOC);
|
|
||||||
|
|
||||||
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
|
||||||
|
|
||||||
return $bounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function calculateMapBounds(int $mapId): Bounds
|
private function calculateMapBounds(int $mapId): Bounds
|
||||||
{
|
{
|
||||||
$select = new Select(\Container::$dbConnection, 'places');
|
$select = new Select(\Container::$dbConnection, 'places');
|
||||||
|
@ -3,18 +3,53 @@
|
|||||||
<div class="header small">
|
<div class="header small">
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<h1>
|
<h1>
|
||||||
<a href="/maps" title="Back to playable maps">
|
<a href="/admin/maps" title="Back to maps">
|
||||||
<img class="inline" src="/static/img/icon.svg">
|
<img class="inline" src="/static/img/icon.svg">
|
||||||
<span>MapGuesser</span>
|
<span>MapGuesser</span>
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p>Added: <span id="added" class="mono bold">0</span> | Edited: <span id="edited" class="mono bold">0</span> | Deleted: <span id="deleted" class="mono bold">0</span></p>
|
<p>
|
||||||
|
<span class="bold"><a href="#" id="mapName"><?= $mapName ?></a></span><!--
|
||||||
|
--><span><!--
|
||||||
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
|
--><svg class="inline" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" d="M8 3.5a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5H4a.5.5 0 0 1 0-1h3.5V4a.5.5 0 0 1 .5-.5z"/>
|
||||||
|
<path fill-rule="evenodd" d="M7.5 8a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1H8.5V12a.5.5 0 0 1-1 0V8z"/>
|
||||||
|
<path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
||||||
|
</svg>
|
||||||
|
<span id="added" class="bold">0</span><!--
|
||||||
|
--></span><!--
|
||||||
|
--><span><!--
|
||||||
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
|
--><svg class="inline" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15.502 1.94a.5.5 0 0 1 0 .706a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456l-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/> <path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
||||||
|
</svg>
|
||||||
|
<span id="edited" class="bold">0</span><!--
|
||||||
|
--></span><!--
|
||||||
|
--><span><!--
|
||||||
|
<?php /* Copyright (c) 2019 The Bootstrap Authors. License can be found in 'USED_SOFTWARE' in section 'Bootstrap Icons'. */ ?>
|
||||||
|
--><svg class="inline" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" d="M3.5 8a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 0 1H4a.5.5 0 0 1-.5-.5z"/>
|
||||||
|
<path fill-rule="evenodd" d="M14 1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2z"/>
|
||||||
|
</svg>
|
||||||
|
<span id="deleted" class="bold">0</span><!--
|
||||||
|
--></span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="metadata">
|
||||||
|
<form id="metadataForm">
|
||||||
|
<input class="fullWidth" type="text" name="name" value="<?= $mapName ?>" placeholder="Name of the map">
|
||||||
|
<textarea class="fullWidth marginTop" name="description" rows="4" placeholder="Description of the map"><?= $mapDescription ?></textarea>
|
||||||
|
<div style="text-align: right;">
|
||||||
|
<button id="closeMetadataButton" class="gray marginTop" type="button">Close</button>
|
||||||
|
<button class="marginTop" type="submit">Apply</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
<div id="control">
|
<div id="control">
|
||||||
<button id="saveButton" class="fullWidth">Save</button>
|
<button id="saveButton" class="fullWidth" disabled>Save</button>
|
||||||
<a class="button gray fullWidth marginTop" href="/admin/maps" title="Back to maps">Back to maps</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="panorama"></div>
|
<div id="panorama"></div>
|
||||||
<div id="noPano">
|
<div id="noPano">
|
||||||
@ -22,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="placeControl">
|
<div id="placeControl">
|
||||||
<button id="applyButton" class="fullWidth">Apply</button>
|
<button id="applyButton" class="fullWidth">Apply</button>
|
||||||
<button id="cancelButton" class="gray fullWidth marginTop">Cancel</button>
|
<button id="closeButton" class="gray fullWidth marginTop">Close</button>
|
||||||
<button id="deleteButton" class="red fullWidth marginTop">Delete</button>
|
<button id="deleteButton" class="red fullWidth marginTop">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
Reference in New Issue
Block a user