Add event support and improve UI/UX
This commit is contained in:
parent
e37382eedf
commit
9e620e4627
125
www/assets/js/addevent.js
Normal file
125
www/assets/js/addevent.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 Netsyms Technologies.
|
||||||
|
* 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/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function openEventAddScreen(machineid) {
|
||||||
|
app.dialog.preloader("Loading...");
|
||||||
|
apirequest(
|
||||||
|
"geteventtypes",
|
||||||
|
{},
|
||||||
|
function (resp) {
|
||||||
|
app.dialog.close();
|
||||||
|
|
||||||
|
catoptions = [
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const catlabel in resp) {
|
||||||
|
var options = [];
|
||||||
|
for (const optionval in resp[catlabel]) {
|
||||||
|
options.push({
|
||||||
|
value: optionval,
|
||||||
|
label: resp[catlabel][optionval]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catoptions.push({
|
||||||
|
label: catlabel,
|
||||||
|
options: options
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(catoptions);
|
||||||
|
|
||||||
|
router.navigate("/addevent", {
|
||||||
|
context: {
|
||||||
|
machineid: machineid,
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: "event",
|
||||||
|
label: "Event",
|
||||||
|
type: "select",
|
||||||
|
catoptions: catoptions,
|
||||||
|
value: "",
|
||||||
|
tabindex: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "date",
|
||||||
|
label: "Date/Time",
|
||||||
|
type: "datetime",
|
||||||
|
value: "",
|
||||||
|
tabindex: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "privatenotes",
|
||||||
|
label: "Private Notes",
|
||||||
|
type: "textarea",
|
||||||
|
value: "",
|
||||||
|
tabindex: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "publicnotes",
|
||||||
|
label: "Public Notes",
|
||||||
|
type: "textarea",
|
||||||
|
value: "",
|
||||||
|
tabindex: 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function (xhr) {
|
||||||
|
app.dialog.close();
|
||||||
|
var error = $.parseJSON(xhr.responseText);
|
||||||
|
if (error && typeof error.msg != 'undefined') {
|
||||||
|
app.dialog.alert(error.msg, "Error");
|
||||||
|
} else {
|
||||||
|
app.dialog.alert("A server or network error occurred.", "Error");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getStorage("username"),
|
||||||
|
getStorage("password")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addEvent(machineid) {
|
||||||
|
app.dialog.preloader("Adding event...");
|
||||||
|
|
||||||
|
var eventdata = {
|
||||||
|
id: machineid
|
||||||
|
};
|
||||||
|
$("#eventform .eventfield").each(function (i, o) {
|
||||||
|
if ($(this).parent().is(".smart-select")) {
|
||||||
|
eventdata[$(this).attr("name")] = app.smartSelect.get('#smartselect-' + $(this).attr("name")).getValue();
|
||||||
|
} else {
|
||||||
|
eventdata[$(this).attr("name")] = $(this).val();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
apirequest(
|
||||||
|
"addevent",
|
||||||
|
eventdata,
|
||||||
|
function (resp) {
|
||||||
|
app.dialog.close();
|
||||||
|
if (resp.status == "ERROR") {
|
||||||
|
app.dialog.alert(resp.msg, "Error");
|
||||||
|
} else {
|
||||||
|
app.toast.create({
|
||||||
|
text: 'Event added!',
|
||||||
|
closeTimeout: 2000,
|
||||||
|
}).open();
|
||||||
|
openMachineInfo(machineid);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function (xhr) {
|
||||||
|
app.dialog.close();
|
||||||
|
var error = $.parseJSON(xhr.responseText);
|
||||||
|
if (error && typeof error.msg != 'undefined') {
|
||||||
|
app.dialog.alert(error.msg, "Error");
|
||||||
|
} else {
|
||||||
|
app.dialog.alert("A server or network error occurred.", "Error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -32,7 +32,7 @@ function addMachineToSearchHistory(machineid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openMachineEditor(machineid) {
|
function openMachineEditor(machineid) {
|
||||||
app.dialog.preloader("Loading...");
|
app.dialog.preloader("Loading editor...");
|
||||||
|
|
||||||
apirequest(
|
apirequest(
|
||||||
"lookup",
|
"lookup",
|
||||||
@ -89,14 +89,11 @@ function openMachineEditor(machineid) {
|
|||||||
} else {
|
} else {
|
||||||
app.dialog.alert("A server or network error occurred.", "Error");
|
app.dialog.alert("A server or network error occurred.", "Error");
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
getStorage("username"),
|
|
||||||
getStorage("password")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openMachineInfo(machineid) {
|
function openMachineInfo(machineid) {
|
||||||
app.dialog.preloader("Searching...");
|
app.dialog.preloader("Loading...");
|
||||||
|
|
||||||
apirequest(
|
apirequest(
|
||||||
"lookup",
|
"lookup",
|
||||||
@ -108,10 +105,23 @@ function openMachineInfo(machineid) {
|
|||||||
if (resp.status == "ERROR") {
|
if (resp.status == "ERROR") {
|
||||||
app.dialog.alert(resp.msg, "Error");
|
app.dialog.alert(resp.msg, "Error");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
var events = [];
|
||||||
|
for (var i = 0; i < resp.events.length; i++) {
|
||||||
|
events.push({
|
||||||
|
name: resp.events[i].name,
|
||||||
|
date: timestampToDateTimeString(resp.events[i].date),
|
||||||
|
shortdate: formatTimestamp("M j", resp.events[i].date),
|
||||||
|
publicnotes: resp.events[i].publicnotes,
|
||||||
|
privatenotes: resp.events[i].privatenotes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
var context = {
|
var context = {
|
||||||
machineid: resp.id,
|
machineid: resp.id,
|
||||||
type: resp.type,
|
type: resp.type,
|
||||||
icon: resp.icon,
|
icon: resp.icon,
|
||||||
|
events: events,
|
||||||
machineprops: {
|
machineprops: {
|
||||||
machineid: {
|
machineid: {
|
||||||
name: "machineid",
|
name: "machineid",
|
||||||
@ -178,10 +188,7 @@ function openMachineInfo(machineid) {
|
|||||||
} else {
|
} else {
|
||||||
app.dialog.alert("A server or network error occurred.", "Error");
|
app.dialog.alert("A server or network error occurred.", "Error");
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
getStorage("username"),
|
|
||||||
getStorage("password")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveMachineEdits(machineid) {
|
function saveMachineEdits(machineid) {
|
||||||
@ -221,10 +228,7 @@ function saveMachineEdits(machineid) {
|
|||||||
} else {
|
} else {
|
||||||
app.dialog.alert("A server or network error occurred.", "Error");
|
app.dialog.alert("A server or network error occurred.", "Error");
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
getStorage("username"),
|
|
||||||
getStorage("password")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$("#app").on("keypress", "#machineform .machinefield", function (evt) {
|
$("#app").on("keypress", "#machineform .machinefield", function (evt) {
|
||||||
|
@ -26,11 +26,17 @@ function uuidv4() {
|
|||||||
* @param {array} data AJAX data to POST
|
* @param {array} data AJAX data to POST
|
||||||
* @param {function} success
|
* @param {function} success
|
||||||
* @param {function} error
|
* @param {function} error
|
||||||
* @param {string|undefined} username
|
* @param {string|null|undefined} username null will send no authentication, undefined will fill from getStorage('username')
|
||||||
* @param {string|undefined} password
|
* @param {string|null|undefined} password null will send no authentication, undefined will fill from getStorage('password')
|
||||||
* @returns {jqXHR}
|
* @returns {jqXHR}
|
||||||
*/
|
*/
|
||||||
function apirequest(action, data, success, error, username, password) {
|
function apirequest(action, data, success, error, username, password) {
|
||||||
|
if (typeof username == 'undefined') {
|
||||||
|
username = getStorage("username");
|
||||||
|
}
|
||||||
|
if (typeof password == 'undefined') {
|
||||||
|
password = getStorage("password");
|
||||||
|
}
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: SETTINGS.apiserver + action,
|
url: SETTINGS.apiserver + action,
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
|
@ -37,5 +37,6 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
<script src="routes.js"></script>
|
<script src="routes.js"></script>
|
||||||
|
|
||||||
<script src="assets/js/machine.js"></script>
|
<script src="assets/js/machine.js"></script>
|
||||||
|
<script src="assets/js/addevent.js"></script>
|
||||||
|
|
||||||
<script src="assets/js/main.js"></script>
|
<script src="assets/js/main.js"></script>
|
||||||
|
92
www/pages/addevent.html
Normal file
92
www/pages/addevent.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<!--
|
||||||
|
Copyright 2020 Netsyms Technologies.
|
||||||
|
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="addevent">
|
||||||
|
|
||||||
|
<div class="navbar">
|
||||||
|
<div class="navbar-bg"></div>
|
||||||
|
<div class="navbar-inner">
|
||||||
|
<div class="left">
|
||||||
|
<a href="#" class="link icon-only" onclick="router.navigate('/')">
|
||||||
|
<i class="icon icon-back"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="title"><i class="{{icon}}"></i> Add Event for #{{machineid}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-extended fab-right-bottom color-green" id="save-fab">
|
||||||
|
<a href="#" onclick="addEvent('{{machineid}}');">
|
||||||
|
<!-- Icons For iOS Theme -->
|
||||||
|
<i class="icon f7-icons if-not-md">floppy_disk</i>
|
||||||
|
<!-- Icons For MD Theme -->
|
||||||
|
<i class="icon material-icons md-only">save</i>
|
||||||
|
<div class="fab-text">Save</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="page-content">
|
||||||
|
<form id="eventform" style="margin-bottom: 5rem;">
|
||||||
|
<div class="list no-hairlines no-margin-top">
|
||||||
|
<ul>
|
||||||
|
{{#each fields}}
|
||||||
|
{{#js_if "this.type == 'select'"}}
|
||||||
|
<li>
|
||||||
|
<a class="item-link smart-select smart-select-init" id="smartselect-{{name}}" data-close-on-select="true" data-searchbar="true" data-searchbar-placeholder="Search">
|
||||||
|
<select name="{{name}}" class="eventfield" tabindex="{{tabindex}}">
|
||||||
|
{{#if catoptions}}
|
||||||
|
<option value="">Choose</option>
|
||||||
|
{{#each catoptions}}
|
||||||
|
<optgroup label="{{label}}">
|
||||||
|
{{#each options}}
|
||||||
|
<option value="{{value}}" data-display-as="{{value}}">{{label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</optgroup>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if options}}
|
||||||
|
{{#each options}}
|
||||||
|
<option value="{{value}}">{{label}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/if}}
|
||||||
|
</select>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title">{{label}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{else}}
|
||||||
|
<li class="item-content item-input">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title item-floating-label">{{label}}</div>
|
||||||
|
<div class="item-input-wrap">
|
||||||
|
{{#js_if "this.type == 'textarea'"}}
|
||||||
|
<textarea class="eventfield" rows="4" name="{{name}}" placeholder="" tabindex="{{tabindex}}">{{value}}</textarea>
|
||||||
|
{{else}}
|
||||||
|
{{#js_if "this.type == 'datetime'"}}
|
||||||
|
<input name="{{name}}" type="text" placeholder="Select date and time" readonly="readonly" tabindex="{{tabindex}}" class="eventfield datetime-textbox"/>
|
||||||
|
{{else}}
|
||||||
|
<input class="eventfield" type="{{type}}" name="{{name}}" placeholder="" value="{{value}}" tabindex="{{tabindex}}">
|
||||||
|
<span class="input-clear-button machinefield-clear-button display-none"></span>
|
||||||
|
{{/js_if}}
|
||||||
|
{{/js_if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/js_if}}
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var machineid = "{{machineid}}";
|
||||||
|
</script>
|
||||||
|
</div>
|
@ -20,17 +20,35 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if editable}}
|
{{#if editable}}
|
||||||
<div class="fab fab-right-bottom" id="edit-fab">
|
<div class="fab fab-extended fab-right-bottom color-green" id="event-fab">
|
||||||
|
<a href="#" onclick="openEventAddScreen('{{machineid}}');">
|
||||||
|
<!-- Icons For iOS Theme -->
|
||||||
|
<i class="icon f7-icons if-not-md">plus</i>
|
||||||
|
<!-- Icons For MD Theme -->
|
||||||
|
<i class="icon material-icons md-only">add</i>
|
||||||
|
<div class="fab-text">Add Event</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fab fab-left-bottom" id="edit-fab">
|
||||||
<a href="#" onclick="openMachineEditor('{{machineid}}');">
|
<a href="#" onclick="openMachineEditor('{{machineid}}');">
|
||||||
<span class="material-icons">edit</span>
|
<span class="material-icons">edit</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<div class="page-content">
|
<div class="toolbar tabbar toolbar-top">
|
||||||
<div class="card elevation-4">
|
<div class="toolbar-inner">
|
||||||
<div class="card-content">
|
<a href="#tab-info" class="tab-link tab-link-active">Info</a>
|
||||||
<div class="list">
|
<a href="#tab-events" class="tab-link">Events</a>
|
||||||
|
<a href="#tab-client" class="tab-link">Client</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tabs-swipeable-wrap">
|
||||||
|
<div class="tabs">
|
||||||
|
<div id="tab-info" class="page-content tab tab-active">
|
||||||
|
<div class="list no-margin-top">
|
||||||
<ul>
|
<ul>
|
||||||
{{#each machineprops}}
|
{{#each machineprops}}
|
||||||
{{#if value}}
|
{{#if value}}
|
||||||
@ -49,19 +67,75 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if clientinfo}}
|
<div id="tab-events" class="page-content tab">
|
||||||
{{#with clientinfo}}
|
<div class="list accordion-list no-margin-top">
|
||||||
<div class="card">
|
<ul>
|
||||||
<div class="card-header"><h4 class="no-margin"><i class="fas fa-user"></i> Client</h4></div>
|
{{#each events}}
|
||||||
|
<li class="accordion-item"><a href="#" class="item-content item-link">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title">{{name}}</div>
|
||||||
|
<div class="item-after">{{shortdate}}</div>
|
||||||
|
</div></a>
|
||||||
|
<div class="accordion-item-content">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="list">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title" style="white-space: normal !important;">
|
||||||
|
<div class="item-header">Date/Time</div>
|
||||||
|
{{date}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{#if privatenotes}}
|
||||||
|
<li>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title" style="white-space: normal !important;">
|
||||||
|
<div class="item-header">Private Notes</div>
|
||||||
|
{{privatenotes}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if publicnotes}}
|
||||||
|
<li>
|
||||||
|
<div class="item-content">
|
||||||
|
<div class="item-inner">
|
||||||
|
<div class="item-title" style="white-space: normal !important;">
|
||||||
|
<div class="item-header">Public Notes</div>
|
||||||
|
{{publicnotes}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card-content">
|
<div id="tab-client" class="page-content tab">
|
||||||
<div class="list">
|
{{#if clientinfo}}
|
||||||
|
{{#with clientinfo}}
|
||||||
|
<div class="list no-margin-top">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<div class="item-content">
|
<div class="item-content">
|
||||||
<div class="item-inner">
|
<div class="item-inner">
|
||||||
|
<div class="item-header">Name</div>
|
||||||
<div class="item-title">
|
<div class="item-title">
|
||||||
{{name}}
|
{{name}}
|
||||||
</div>
|
</div>
|
||||||
@ -106,10 +180,12 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||||||
{{/if}}
|
{{/if}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
{{/with}}
|
||||||
|
{{else}}
|
||||||
|
<div class="block">No client has been linked.</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/with}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -9,7 +9,7 @@ var routes = [
|
|||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
name: "home",
|
name: "home",
|
||||||
async: function(routeTo, routeFrom, resolve, reject) {
|
async: function (routeTo, routeFrom, resolve, reject) {
|
||||||
resolve({
|
resolve({
|
||||||
templateUrl: "pages/home.html",
|
templateUrl: "pages/home.html",
|
||||||
}, {
|
}, {
|
||||||
@ -29,6 +29,21 @@ var routes = [
|
|||||||
name: "machineeditor",
|
name: "machineeditor",
|
||||||
templateUrl: "pages/machineeditor.html"
|
templateUrl: "pages/machineeditor.html"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/addevent",
|
||||||
|
name: "addevent",
|
||||||
|
templateUrl: "pages/addevent.html",
|
||||||
|
on: {
|
||||||
|
pageInit: function () {
|
||||||
|
$(".datetime-textbox").val(formatTimestamp("Y-m-d g:i A"));
|
||||||
|
app.calendar.create({
|
||||||
|
inputEl: '.datetime-textbox',
|
||||||
|
timePicker: true,
|
||||||
|
dateFormat: "yyyy-mm-dd h::mm A",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "login",
|
name: "login",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user