Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ed52f6d
Showing
8 changed files
with
1,025 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
src/mapsApiKey.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# effex-demo-markers | ||
A demo using the Ephemeral Exchange API to connect a Maps app to various back ends | ||
|
||
Read more about this at http://ramblings.mcpher.com/Home/excelquirks/ephemeralexchange/sheetsmaps |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>effex-demo-markers</title> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<!-- load MUI --> | ||
<link href="https://cdn.muicss.com/mui-0.9.9/css/mui.min.css" rel="stylesheet" type="text/css" /> | ||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> | ||
<link rel="shortcut icon" href="img/exn64.ico" type="image/x-icon"> | ||
<script src="https://cdn.muicss.com/mui-0.9.9/js/mui.min.js"></script> | ||
|
||
<style> | ||
|
||
#map { | ||
height: 100%; | ||
margin-left: 210px; | ||
|
||
} | ||
|
||
#panel { | ||
height: 100%; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
z-index: 5; | ||
background-color: #fff; | ||
width:180px; | ||
|
||
} | ||
|
||
#errify { | ||
height:110px; | ||
position: absolute; | ||
bottom: 0; | ||
left: 0; | ||
width:180px; | ||
padding:15px; | ||
} | ||
|
||
html, body { | ||
height: 100%; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
|
||
.iconlink { | ||
cursor:pointer; | ||
} | ||
|
||
#camera { | ||
position:absolute; | ||
display:block; | ||
background-color:white; | ||
width:24px; | ||
height:56px; | ||
top:40px; | ||
right:20px; | ||
z-index:6; | ||
} | ||
|
||
</style> | ||
</head> | ||
|
||
|
||
<div id="map"></div> | ||
<div id="camera" class="mui--hide"> | ||
<div class="inconlink"> | ||
<i id="snap" class="material-icons">photo_camera</i> | ||
<i id="reset" class="material-icons">restore_page</i> | ||
</div> | ||
</div> | ||
<div id="panel" class="mui-panel" style="padding-top:0;padding-bottom:0;margin:0;"> | ||
<h4>Effex store data</h4> | ||
<div class="mui-divider"></div> | ||
<div>Updater key</div> | ||
<div id="efx-key" style="font-size:.7em;"></div> | ||
<div>Item key</div> | ||
<div id="efx-id" style="font-size:.7em;"></div> | ||
<div class="mui-divider"></div> | ||
<br> | ||
<div class="mui--text-dark-secondary"> | ||
<div>Collecting data using maps</div> | ||
<ul><br> | ||
<li>Clicking on a marker allows you to modify its contents, or to delete it</li>. | ||
<li>Right click somewhere on the map to drop in a new marker"</li> | ||
</ul> | ||
</div> | ||
<div style="padding-top:40px;"> | ||
<div>When finished, update the store to send back changes</div> | ||
<div><br></div> | ||
<button id="update" class="mui-btn mui-btn--primary">Update store</button> | ||
</div> | ||
|
||
<div id="errify" class="mui--bg-danger mui--hide mui--text-white mui--text-caption"></div> | ||
</div> | ||
<script src="https://www.google.com/jsapi"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/classlist/1.1.20150312/classList.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/4.0.5/es6-promise.min.js"></script> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.3/axios.min.js"></script> | ||
|
||
<script src="lib/effexapiclient.js"></script> | ||
<script src="src/mapsApiKey.js"></script> | ||
<script src="src/maps.js"></script> | ||
<script src="src/main.js"></script> | ||
|
||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
/** | ||
* @namespace EffexApiClient | ||
* lite effex API client, with no admin capabilities | ||
*/ | ||
/* global axios */ | ||
var EffexApiClient = (function(ns) { | ||
|
||
// the api base url | ||
var ax,keys; | ||
|
||
ns.setKeys = function (optionalKeys){ | ||
keys = optionalKeys || ns.getUriKeys(); | ||
}; | ||
|
||
ns.getKeys = function () { | ||
return keys; | ||
}; | ||
|
||
ns.setBase = function(base) { | ||
ax = axios.create({ | ||
baseURL: base, | ||
maxContentLength: 512000 | ||
}); | ||
}; | ||
|
||
|
||
|
||
function clone (ob) { | ||
return JSON.parse(JSON.stringify(ob || {})); | ||
} | ||
|
||
/** | ||
* turns a params object into a url | ||
* @param {object} params the params | ||
* @return {string} the uri | ||
*/ | ||
function makeParams(params) { | ||
params = params || {}; | ||
var pa = Object.keys(params).reduce(function(p, c) { | ||
p.push(c + "=" + encodeURIComponent(params[c])); | ||
return p; | ||
}, []); | ||
|
||
return pa.length ? ("?" + pa.join("&")) : ""; | ||
} | ||
|
||
ns.checkKeys = function (preview) { | ||
if (!Array.isArray(preview)) preview = [preview]; | ||
return preview.every(function(d){ return keys[d]}); | ||
}; | ||
|
||
/** | ||
* @param {string} boss the boss key | ||
* @param {string} mode the type like writer/reader/updater | ||
* @param {object} params the params | ||
* @return {Promise} to the result | ||
*/ | ||
ns.generateKey = function (boss, mode,params) { | ||
return ax.get ('/' + boss + '/' + mode + makeParams(params)); | ||
}; | ||
|
||
/** | ||
* ping the service | ||
* @return {object} "PONG" | ||
*/ | ||
ns.ping = function() { | ||
return ax.get('/ping'); | ||
}; | ||
|
||
/** | ||
* info the service | ||
* @return {object} result | ||
*/ | ||
ns.info = function() { | ||
return ax.get('/info'); | ||
}; | ||
|
||
/** | ||
* get quotas | ||
* @return {object} the quotas | ||
*/ | ||
ns.getQuotas = function() { | ||
return ax.get('/quotas'); | ||
}; | ||
|
||
/** | ||
* update an item | ||
* @param {string} id the item id | ||
* @param {string} updater the updater key | ||
* @param {object} data what to write | ||
* @param {string} method the to use (post,get) | ||
* @param {object} params the params | ||
* @return {Promise} to the result | ||
*/ | ||
ns.update = function (data, id, updater, method , params) { | ||
method = (method || "post").toLowerCase(); | ||
params = params || {}; | ||
|
||
if (method === "get") { | ||
params = clone(params); | ||
params.data = JSON.stringify(data); | ||
} | ||
var url = "/updater/" + ns.checkKey("updater",updater) + "/" + ns.checkKey("item",id) + makeParams(params); | ||
return ax[method] (url, {data:data}); | ||
}; | ||
|
||
/** | ||
* @param {string} writer the writer key | ||
* @param {object} data what to write | ||
* @param {string} method the to use (post,get) | ||
* @param {object} params the params | ||
* @return {Promise} to the result | ||
*/ | ||
ns.write = function (data, writer, method , params) { | ||
method = (method || "post").toLowerCase(); | ||
params = params || {}; | ||
|
||
if (method === "get") { | ||
params = clone(params); | ||
params.data = JSON.stringify(data); | ||
} | ||
var url = "/writer/" + ns.checkKey("writer",writer) + makeParams(params); | ||
return ax[method] (url, {data:data}); | ||
}; | ||
|
||
|
||
ns.checkKey = function (type, value) { | ||
var k= value || keys[type]; | ||
if (!k) console.log ("failed key check", type, value); | ||
return k; | ||
}; | ||
|
||
|
||
/** | ||
* @param {string} id the item id | ||
* @param {string} writer the writer key | ||
* @param {object} params the params | ||
* @return {Promise} to the result | ||
*/ | ||
ns.remove = function (id, writer , params) { | ||
return ax.remove ('/writer/' + ns.checkKey("writer",writer) + '/' + ns.checkKey("item",id) + makeParams(params || [])); | ||
}; | ||
|
||
ns.read = function (id, reader , params) { | ||
params = params || {}; | ||
id = id || keys.item; | ||
reader = reader || keys.reader; | ||
return ax.get ('/reader/' + ns.checkKey("reader",reader) + '/' + ns.checkKey("item",id) + makeParams(params)); | ||
}; | ||
|
||
/** | ||
* @param {string} coupon the coupon code | ||
* @return {Promise} to the result | ||
*/ | ||
ns.validateKey = function (coupon) { | ||
return ax.get ('/validate/' + coupon); | ||
}; | ||
|
||
/** | ||
* @param {string} id the item id | ||
* @param {string} writer the writer key | ||
* @param {string} key the key to assign the alias for | ||
* @param {string} alias the alias to assign | ||
* @param {object} params the params | ||
* @return {Promise} to the result | ||
*/ | ||
ns.registerAlias = function (writer, key, id , alias, params) { | ||
return ax.get('/'+ ns.checkKey("writer",writer) + '/' + key + | ||
'/alias/' + encodeURIComponent(alias) + '/' + ns.checkKey("item",id) + makeParams(params)); | ||
}; | ||
|
||
ns.getUriParam = function (name, source) { | ||
var match = RegExp('[?&]' + name + '=([^&]*)').exec(source || window.location.search); | ||
return match && decodeURIComponent(match[1].replace(/\+/g, ' ')); | ||
}; | ||
|
||
/** | ||
* standard parameters that might useful for an effex app | ||
* @return {object} keys | ||
*/ | ||
ns.getUriKeys = function() { | ||
var ob = ["updater", "reader", "item","boss","writer"] | ||
.reduce(function(p, c) { | ||
p[c] = ns.getUriParam(c); | ||
return p; | ||
}, {}); | ||
|
||
// updaters/writers can standin for readers | ||
ob.updater = ob.updater || ob.writer; | ||
ob.reader = ob.reader || ob.updater || ob.writer; | ||
|
||
return ob; | ||
}; | ||
|
||
// default prod | ||
ns.setBase("https://ephex-auth.appspot-preview.com"); | ||
ns.setKeys(); | ||
axios.defaults.headers.post['Content-Type'] = 'application/json'; | ||
|
||
return ns; | ||
})({}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* global google */ | ||
/* global Maps */ | ||
/* global EffexApiClient */ | ||
/* global getMapsApiKey */ | ||
|
||
google.load('maps', '3', { | ||
callback: function() { | ||
|
||
// this particular app is expecting to read and update an item, so ensure we have keys for that | ||
if (!EffexApiClient.checkKeys(["updater", "reader", "item"])) { | ||
errify('missing uri parameters', 'both an updater key and an item key are required'); | ||
} | ||
|
||
else { | ||
// give some info | ||
document.getElementById("efx-id").innerHTML = EffexApiClient.getKeys().item; | ||
document.getElementById("efx-key").innerHTML = EffexApiClient.getKeys().updater; | ||
|
||
var maps; | ||
// and get the data | ||
EffexApiClient.read() | ||
.then(function(response) { | ||
if (response.data && response.data.ok) { | ||
// initialize the map and get going | ||
maps = new Maps().init(response.data); | ||
} | ||
else { | ||
errify("Failed to get effexdata", JSON.stringify(response)); | ||
} | ||
}) | ||
.catch(function(err) { | ||
errify("grevious error getting data", err); | ||
}); | ||
|
||
// hook up the update button | ||
document.getElementById("update") | ||
.addEventListener("click", function() { | ||
EffexApiClient.update(maps.spots.map(function(d) { | ||
return d.place; | ||
})) | ||
.then(function(result) { | ||
if (result.data && result.data.ok) { | ||
errify("Effex updated", maps.spots.length + " spots sent"); | ||
} | ||
else { | ||
errify("Failed to update effexdata", JSON.stringify(result)); | ||
} | ||
}) | ||
.catch(function(err) { | ||
errify("grevious error updating data", err); | ||
}); | ||
}); | ||
} | ||
|
||
|
||
}, | ||
|
||
|
||
other_params: 'key=' + getMapsApiKey() | ||
|
||
}); | ||
|
||
// error messages | ||
function errify(message, error) { | ||
var ef = document.getElementById("errify"); | ||
ef.classList.remove ("mui--hide"); | ||
ef.innerHTML = message + '<br>' + error; | ||
console.log(message, error); | ||
setTimeout(function () { | ||
ef.classList.add ("mui--hide"); | ||
}, 5000); | ||
} |
Oops, something went wrong.