Add route notes feature (#22) TODO: street autofill and integration
This commit is contained in:
parent
4117adfe3a
commit
664d54ae97
61
www/assets/images/note-dashed.svg
Normal file
61
www/assets/images/note-dashed.svg
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
class="svg-inline--fa fa-box-open fa-w-19"
|
||||
aria-hidden="true"
|
||||
data-icon="box-open"
|
||||
data-prefix="fal"
|
||||
focusable="false"
|
||||
role="img"
|
||||
version="1.1"
|
||||
viewBox="0 0 608 512"
|
||||
id="svg879"
|
||||
sodipodi:docname="note-dashed.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<defs
|
||||
id="defs883" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1015"
|
||||
id="namedview881"
|
||||
showgrid="false"
|
||||
height="1"
|
||||
inkscape:zoom="1.3037281"
|
||||
inkscape:cx="241.86287"
|
||||
inkscape:cy="228.99761"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg879" />
|
||||
<metadata
|
||||
id="metadata875">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
d="M 392,320 H 528 V 56.000003 c 0,-13.3 -10.7,-24 -24,-24 H 104 c -13.3,0 -24,10.7 -24,24 V 456 c 0,13.3 10.7,24 24,24 H 368 V 344 c 0,-13.2 10.8,-24 24,-24 z m 129,55 -98,98 c -4.5,4.5 -10.6,7 -17,7 h -6 V 352 h 128 v 6.1 c 0,6.3 -2.5,12.4 -7,16.9 z"
|
||||
id="path2"
|
||||
style="fill:none;stroke:#9e9e9e;stroke-width:10;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
@ -37,18 +37,6 @@ function restartApplication() {
|
||||
window.location = "index.html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a UUID.
|
||||
* From https://stackoverflow.com/a/2117523
|
||||
* @returns {String}
|
||||
*/
|
||||
function uuidv4() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
router.on("pageInit", function (pagedata) {
|
||||
pagedata.$el.find('script').each(function (el) {
|
||||
|
128
www/assets/js/notes.js
Normal file
128
www/assets/js/notes.js
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
if (inStorage("notes")) {
|
||||
var notes = JSON.parse(getStorage("notes"));
|
||||
} else {
|
||||
var notes = [];
|
||||
setStorage("notes", "[]");
|
||||
}
|
||||
|
||||
function saveNote(id) {
|
||||
var exists = false;
|
||||
var index = -1;
|
||||
for (var i = 0; i < notes.length; i++) {
|
||||
if (notes[i].id == id) {
|
||||
exists = true;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
var note = {
|
||||
id: id,
|
||||
number: "",
|
||||
street: "",
|
||||
notes: "",
|
||||
toggles: {}
|
||||
};
|
||||
if (exists) {
|
||||
note = notes[index];
|
||||
}
|
||||
|
||||
note.number = $("input[name=number]").val();
|
||||
note.street = $("input[name=street]").val();
|
||||
note.notes = $("textarea#notes").val();
|
||||
|
||||
for (i in SETTINGS.routenotetoggles) {
|
||||
var toggle = SETTINGS.routenotetoggles[i];
|
||||
note.toggles[toggle.id] = $(".note-toggle[data-id=" + toggle.id + "]").is(":checked");
|
||||
}
|
||||
if (exists) {
|
||||
notes[index] = note;
|
||||
} else {
|
||||
notes.push(note);
|
||||
}
|
||||
|
||||
|
||||
setStorage("notes", JSON.stringify(notes));
|
||||
|
||||
app.toast.show({
|
||||
text: "<i class='fas fa-check'></i> Note saved!",
|
||||
position: "bottom",
|
||||
destroyOnClose: true,
|
||||
closeTimeout: 1000 * 3
|
||||
});
|
||||
}
|
||||
|
||||
function deleteNote(id) {
|
||||
for (var i = 0; i < notes.length; i++) {
|
||||
if (notes[i].id == id) {
|
||||
notes.splice(i, 1);
|
||||
}
|
||||
}
|
||||
setStorage("notes", JSON.stringify(notes));
|
||||
}
|
||||
|
||||
$(".view-main").on("click", "#savenotebtn", function () {
|
||||
saveNote($(this).data("noteid"));
|
||||
});
|
||||
|
||||
$(".view-main").on("click", ".editnotebtn", function () {
|
||||
var noteid = $(this).data("noteid");
|
||||
|
||||
var note = {};
|
||||
for (var i = 0; i < notes.length; i++) {
|
||||
if (notes[i].id == noteid) {
|
||||
note = notes[i];
|
||||
}
|
||||
}
|
||||
|
||||
var toggles = [];
|
||||
for (t in SETTINGS.routenotetoggles) {
|
||||
var toggle = SETTINGS.routenotetoggles[t];
|
||||
toggles.push({
|
||||
id: toggle.id,
|
||||
name: toggle.name,
|
||||
checked: note.toggles[toggle.id] == true
|
||||
});
|
||||
}
|
||||
|
||||
router.navigate("/myroute/editnote", {
|
||||
context: {
|
||||
title: "Edit Note",
|
||||
toggles: toggles,
|
||||
noteid: noteid,
|
||||
note: note
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(".view-main").on("click", ".deletenotebtn", function () {
|
||||
var noteid = $(this).data("noteid");
|
||||
app.dialog.confirm("Delete note?", "Confirm", function () {
|
||||
deleteNote(noteid);
|
||||
router.navigate("/myroute", {
|
||||
reloadCurrent: true
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
function getToggleName(id) {
|
||||
for (i in SETTINGS.routenotetoggles) {
|
||||
if (SETTINGS.routenotetoggles[i].id == id) {
|
||||
return SETTINGS.routenotetoggles[i].name;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Template7.registerHelper('notetogglename', function (key) {
|
||||
return getToggleName(key);
|
||||
});
|
||||
|
||||
Template7.registerHelper('newlinestobr', function (text) {
|
||||
return text.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
||||
});
|
@ -4,6 +4,17 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generate a UUID.
|
||||
* From https://stackoverflow.com/a/2117523
|
||||
* @returns {String}
|
||||
*/
|
||||
function uuidv4() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
function timestampToDateTimeString(timestamp) {
|
||||
var date = new Date(timestamp * 1000);
|
||||
|
@ -53,6 +53,14 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/myroute" class="item-link item-content">
|
||||
<div class="item-media"><i class="icon fas fa-sticky-note"></i></div>
|
||||
<div class="item-inner">
|
||||
<div class="item-title">Route Notes</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/toolbox" class="item-link item-content">
|
||||
<div class="item-media"><i class="icon fas fa-tools"></i></div>
|
||||
|
@ -16,7 +16,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="page-content" style="overflow-y: hidden;"> <!-- overflow-y:hidden removes an annoying pointless scrollbar that wiggles a few pixels up and down -->
|
||||
<iframe src="{{loginurl}}" id="loginframe" style="border: 0; width: 100%; height: calc(100vh - var(--f7-navbar-height));"></iframe>
|
||||
</div>
|
||||
|
||||
|
66
www/pages/myroute.html
Normal file
66
www/pages/myroute.html
Normal file
@ -0,0 +1,66 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<div class="page" data-name="myroute">
|
||||
|
||||
<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner">
|
||||
<div class="left">
|
||||
<a href="#" class="link icon-only back">
|
||||
<i class="icon icon-back"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="title">Route Notes</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="block-title">Notes</div>
|
||||
{{#if notes}}
|
||||
<div class="list accordion-list">
|
||||
<ul>
|
||||
{{#each notes}}
|
||||
<li class="accordion-item route-note" data-noteid="{{id}}">
|
||||
<a href="#" class="item-content item-link">
|
||||
<div class="item-inner">
|
||||
<div class="item-title">{{number}} {{street}}</div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="accordion-item-content">
|
||||
<div class="block">
|
||||
<a class="button button-small editnotebtn display-inline-block" data-noteid="{{id}}" href="#"><i class="material-icons">edit</i> Edit</a>
|
||||
<a class="button button-small deletenotebtn display-inline-block color-red" data-noteid="{{id}}" href="#"><i class="material-icons">delete</i> Delete</a>
|
||||
{{#if notes}}
|
||||
<p>{{newlinestobr notes}}</p>
|
||||
{{/if}}
|
||||
<div class="list simple-list" style="font-size: 95%;">
|
||||
<ul>
|
||||
{{#each toggles}}
|
||||
{{#if this}}
|
||||
<li style="height: 32px;">{{notetogglename @key}}</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="block text-align-center">
|
||||
<img style="width: 60%; max-width: 300px; max-height: 40vh;" src="assets/images/note-dashed.svg" class="margin-vertical" />
|
||||
<div class="margin-top">Press <i class="material-icons">add</i> to add a note.</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="fab fab-right-bottom">
|
||||
<a href="/myroute/addnote">
|
||||
<i class="icon material-icons">add</i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
79
www/pages/myroute/editnote.html
Normal file
79
www/pages/myroute/editnote.html
Normal file
@ -0,0 +1,79 @@
|
||||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<div class="page" data-name="editnote">
|
||||
|
||||
<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner">
|
||||
<div class="left">
|
||||
<a href="#" class="link icon-only" onclick="router.back({force: true, ignoreCache: true})">
|
||||
<i class="icon icon-back"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="title">{{title}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="fab fab-extended fab-right-bottom">
|
||||
<a id="savenotebtn" data-noteid="{{noteid}}">
|
||||
<i class="icon material-icons">save</i>
|
||||
<div class="fab-text">Save</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
|
||||
<div class="list no-margin-top no-hairlines">
|
||||
<ul>
|
||||
<li class="item-divider">Address</li>
|
||||
<li class="item-content item-input">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-label">Number</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="number" value="{{note.number}}" name="number" placeholder="1234" autocomplete="off" autocorrect="off" autocapitalize="off">
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li class="item-content item-input">
|
||||
<div class="item-inner">
|
||||
<div class="item-title item-label">Street</div>
|
||||
<div class="item-input-wrap">
|
||||
<input type="text" value="{{note.street}}" name="street" id="street" placeholder="Road Drive" autocomplete="off" autocorrect="off">
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="item-divider">Options</li>
|
||||
{{#each toggles}}
|
||||
<li class="item-content">
|
||||
<div class="item-inner">
|
||||
<div class="item-title">
|
||||
{{name}}
|
||||
</div>
|
||||
<div class="item-after">
|
||||
<label class="toggle toggle-init">
|
||||
<input class="note-toggle" type="checkbox" data-id="{{id}}" {{#if checked}}checked="checked"{{/if}}>
|
||||
<span class="toggle-icon"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/each}}
|
||||
|
||||
<li class="item-divider">Notes</li>
|
||||
<li class="item-content item-input">
|
||||
<div class="item-inner">
|
||||
<div class="item-input-wrap">
|
||||
<textarea id="notes" placeholder="" class="resizable">{{note.notes}}</textarea>
|
||||
<span class="input-clear-button"></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -52,7 +52,6 @@ var routes = [
|
||||
dropdownPlaceholderText: '',
|
||||
source: function (query, render) {
|
||||
var streets = searchAutofill(query, $("input[name=number]").val());
|
||||
|
||||
render(streets);
|
||||
}
|
||||
});
|
||||
@ -71,7 +70,6 @@ var routes = [
|
||||
on: {
|
||||
pageAfterIn: function () {
|
||||
loadPackageList();
|
||||
|
||||
searchbar = app.searchbar.create({
|
||||
el: '.package-list-searchbar',
|
||||
searchContainer: '#addresslist',
|
||||
@ -101,6 +99,65 @@ var routes = [
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/myroute',
|
||||
name: 'myroute',
|
||||
async: function (routeTo, routeFrom, resolve, reject) {
|
||||
var notes = false;
|
||||
if (inStorage("notes")) {
|
||||
notes = JSON.parse(getStorage("notes"));
|
||||
if (notes.length == 0) {
|
||||
notes = false;
|
||||
}
|
||||
}
|
||||
resolve({
|
||||
templateUrl: './pages/myroute.html'
|
||||
}, {
|
||||
context: {
|
||||
notes: notes
|
||||
}
|
||||
});
|
||||
},
|
||||
on: {
|
||||
pageAfterIn: function () {
|
||||
// TODO: searchbar
|
||||
}
|
||||
},
|
||||
routes: [
|
||||
{
|
||||
path: '/addnote',
|
||||
async: function (routeTo, routeFrom, resolve, reject) {
|
||||
var uuid = uuidv4();
|
||||
resolve({
|
||||
templateUrl: './pages/myroute/editnote.html'
|
||||
}, {
|
||||
context: {
|
||||
noteid: uuid,
|
||||
title: "Add Note",
|
||||
toggles: SETTINGS.routenotetoggles,
|
||||
note: {
|
||||
id: uuid,
|
||||
number: "",
|
||||
street: "",
|
||||
notes: "",
|
||||
toggles: {}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/editnote',
|
||||
templateUrl: './pages/myroute/editnote.html',
|
||||
options: {
|
||||
context: {
|
||||
title: "Edit Note",
|
||||
toggles: SETTINGS.routenotetoggles
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
templateUrl: './pages/login.html',
|
||||
@ -131,7 +188,6 @@ var routes = [
|
||||
async: function (routeTo, routeFrom, resolve, reject) {
|
||||
if (localStorage.getItem("scanevents") != null && localStorage.getItem("scanevents") != "[]") {
|
||||
var entries = JSON.parse(localStorage.getItem("scanevents"));
|
||||
|
||||
for (i in entries) {
|
||||
entries[i].event = entries[i].event.join(' <i class="fas fa-chevron-right"></i> ');
|
||||
}
|
||||
@ -260,7 +316,7 @@ var routes = [
|
||||
link: true,
|
||||
onclick: "logout()"
|
||||
},
|
||||
);
|
||||
);
|
||||
} else {
|
||||
settings.push(
|
||||
{
|
||||
@ -288,7 +344,6 @@ var routes = [
|
||||
link: true
|
||||
}
|
||||
);
|
||||
|
||||
if (platform_type == "cordova" && cordova.platformId != "browser") {
|
||||
settings.push({
|
||||
setting: "wakelock",
|
||||
@ -337,7 +392,6 @@ var routes = [
|
||||
onclick: "openBrowser('https://netsyms.com/legal?pk_campaign=PackageHelperApp')",
|
||||
link: true
|
||||
});
|
||||
|
||||
resolve({
|
||||
templateUrl: './pages/settings.html'
|
||||
}, {
|
||||
@ -399,7 +453,6 @@ var routes = [
|
||||
slider: true
|
||||
}
|
||||
];
|
||||
|
||||
resolve({
|
||||
templateUrl: './pages/settings.html'
|
||||
}, {
|
||||
@ -481,7 +534,6 @@ var routes = [
|
||||
onclick: ""
|
||||
}
|
||||
];
|
||||
|
||||
resolve({
|
||||
templateUrl: './pages/settings.html'
|
||||
}, {
|
||||
|
@ -301,6 +301,20 @@ var SETTINGS = {
|
||||
]
|
||||
}
|
||||
],
|
||||
routenotetoggles: [
|
||||
{
|
||||
name: "Vacant",
|
||||
id: "vacant"
|
||||
},
|
||||
{
|
||||
name: "Outside delivery radius",
|
||||
id: "undeliverable"
|
||||
},
|
||||
{
|
||||
name: "On hold",
|
||||
id: "hold"
|
||||
}
|
||||
],
|
||||
synckeyblacklist: [
|
||||
"username", "password", "trackingcodehistory", "packages",
|
||||
"user_latitude", "user_longitude", "geocode_cache", "scanevents",
|
||||
|
Loading…
x
Reference in New Issue
Block a user