class InputExtensions { static autoheightElement(element) { return $(element) .css({ 'height': 'auto' }) .height(element.scrollHeight); } static applyNotesAutoHeight() { $('.mmi-new-notes:not(.mmi-new-notes-processed)').on('input', function () { InputExtensions.autoheightElement(this); }); } } class Note { constructor(element, init = true) { var self = this; this.noteTextBox = $(element); this.editable = $(element).hasClass('editable'); this.deletable = $(element).hasClass('deletable'); this.minimal = $(element).hasClass('minimal'); var hfValue = this.noteTextBox.siblings('.notes-original-value').first(); this.originalValue = hfValue.length > 0 ? hfValue.val() : null; var hfNoteId = this.noteTextBox.parents('.child-collection').find('.child-collection-id').first(); this.noteId = hfNoteId.val(); this.buttons = this.noteTextBox.closest('.row').find('.icon-button'); if (init) { this.buttons.each(function () { var button = $(this); button.hide(); if ((button.hasClass('edit') && self.editable) || (button.hasClass('delete') && self.deletable)) { button.show(); } button.on('click', function () { if (button.hasClass('edit')) { self.editNote(button); } else if (button.hasClass('save')) { self.saveNote(button); } else if (button.hasClass('delete')) { self.deleteNote(button); } else if (button.hasClass('reset')) { self.resetNote(button); } }); }); } } enableAdd() { $('#add-note').addClass('note-disabled'); } disableAdd() { $('#add-note').removeClass('note-disabled'); } getCurrentValue() { return this.noteTextBox === null ? null : $(this.noteTextBox).val(); } editNote(editButton) { if (this.noteTextBox !== null && this.noteTextBox.hasClass('editable')) { $('#add-note').addClass('note-disabled'); $(editButton).hide(); var saveButton = Note.getSiblingButton(editButton, 'save'); var resetButton = Note.getSiblingButton(saveButton, 'reset'); $(saveButton).show(); $(resetButton).show(); this.noteTextBox.removeAttr('disabled'); this.noteTextBox.focus(); } } saveNote(saveButton) { if (this.noteTextBox !== null && this.editable) { var currentValue = this.getCurrentValue(); if (this.originalValue === null) { alert('Error saving. Please reload the page and try again. Error: originalValue null.'); Notifications.elementNotificationError(saveButton, 'Error', 'There was an error saving.'); return; } if (currentValue.trim() === '') { Notifications.elementNotificationError(saveButton, 'Error', 'Please use the delete button instead of clearing the note (if deletable).'); return; } var editButton = Note.getSiblingButton(saveButton, 'edit'); var resetButton = Note.getSiblingButton(saveButton, 'reset'); this.noteTextBox.attr('disabled', 'disabled'); $(saveButton).hide(); $(resetButton).hide(); $(editButton).show(); if (this.originalValue === currentValue) { Notifications.elementNotificationSuccess(editButton, 'Success!', 'There were no detected changes.'); } else { // Different so push out an update var url = '/Notes/Edit/' + this.noteId + '?minimal=' + this.minimal; // We're going to push an update and then reload the partial view var collection = $(saveButton).parents('.child-collection').first(); $.post(url, { content: currentValue }, function (data) { var newNote = $(data); newNote.insertBefore(collection); // add new one collection.remove(); // remove old one Note.initNewNotes(); // Find edit button in the new note var newEditButton = newNote.find('.icon-button.edit').first(); Notifications.elementNotificationSuccess(newEditButton, 'Success!', 'This note has been updated.'); } ); } this.enableAdd(); } } deleteNote(deleteButton) { if (this.noteTextBox !== null && this.deletable && confirm('Please confirm that you wish to DELETE this Note.')) { var url = '/Notes/Delete/' + this.noteId; var collection = $(deleteButton).parents('.child-collection').first(); $.post(url, function (data) { collection.remove(); // remove old one }); } } resetNote(resetButton) { if (this.noteTextBox !== null && (this.getCurrentValue() === this.originalValue || confirm('You have unsaved changes on this Note. Please confirm that you wish to UNDO your changes.')) ) { this.noteTextBox.val(this.originalValue); var editButton = Note.getSiblingButton(resetButton, 'edit'); var saveButton = Note.getSiblingButton(resetButton, 'save'); InputExtensions.autoheightElement(this.noteTextBox[0]); this.noteTextBox.attr('disabled', 'disabled'); $(saveButton).hide(); $(resetButton).hide(); $(editButton).show(); } } isDirty() { var hfValue = this.noteTextBox.siblings('.notes-original-value').first(); this.originalValue = hfValue.length > 0 ? hfValue.val() : null; return this.originalValue !== this.getCurrentValue(); } static GetNoteFromButton(button) { var noteTextBox = $(button).parent().siblings().find('.mmi-new-notes'); return new Note(noteTextBox); } static getSiblingButton(button, buttonType) { var elem = $(button).siblings('.icon-button.' + buttonType); return elem; } static initAllOnPage() { Note.initNewNotes(); $('.notes-show-all-checkbox').click(function () { var showAllNotes = $(this).prop('checked'); //StorageHelper.SetStorage('notes-show-all', showAllNotes); if (showAllNotes) $('.note-hidden-default').show(); else $('.note-hidden-default').hide(); }); } static initNewNotes() { InputExtensions.applyNotesAutoHeight(); var showAllNotes = false; // StorageHelper.GetFromStorage('notes-show-all') || false; $('.notes-show-all-checkbox').attr('checked', showAllNotes); if (showAllNotes) $('.note-hidden-default').show(); else $('.note-hidden-default').hide(); $('.mmi-new-notes:not(.mmi-new-notes-processed)').each(function () { InputExtensions.autoheightElement(this); $(this).attr('disabled', 'disabled'); $(this).addClass('mmi-new-notes-processed'); var n = new Note(this); }); } static addNote(addButton, url, minimal) { if ($('#add-note').hasClass('note-disabled')) return; $('#add-note').addClass('note-disabled'); var template = `
`; template = template.replace('{url}', "'" + url + "'"); var addButtonGroup = $(addButton).parents('.child-collection-new').first(); $(template).insertAfter(addButtonGroup); } static saveNewNote(saveButton, url) { var collection = $(saveButton).parents('.child-collection').first(); var currentValue = $(collection).find('.mmi-new-notes').first().val(); if (currentValue.trim() === '') { Notifications.elementNotificationError(saveButton, 'Error', 'Please add some content for your new Note!'); return; } $('#add-note').removeClass('note-disabled'); $.post(url, { content: currentValue }, function (data) { var newNote = $(data); newNote.insertBefore(collection); // add new one collection.remove(); // remove old one Note.initNewNotes(); // Find edit button in the new note var newEditButton = newNote.find('.icon-button.edit').first(); Notifications.elementNotificationSuccess(newEditButton, 'Success!', 'This note has been created.'); } ); } static deleteNewNote(deleteButton) { var collection = $(deleteButton).parents('.child-collection').first(); if (collection.find('.editable').val() == "" || confirm('Please confirm that you wish to DELETE this Note.')) { collection.remove(); $('#add-note').removeClass('note-disabled'); } } } class Notifications { static elementNotification(element, title, message, status = '', showDuration = -1) { console.log(message); var template = ``; var popOverSettings = { placement: 'right', trigger: 'manual', title: title, content: message, html: true, template: template }; $(element).popover(popOverSettings); $(element).popover('show'); var timeout; if (showDuration > 0) { timeout = showDuration; } else { timeout = 1000; if (message !== null) { timeout += message.length * 20; } } setTimeout(function () { $(element).popover('dispose'); }, timeout); } static elementNotificationSuccess(element, title, message) { this.elementNotification(element, title, message, 'success'); } static elementNotificationError(element, title, message) { this.elementNotification(element, title, message, 'error'); } } /* * This class handles all interaction with the PurchasePal endpoint in API */ class PurchasePalAPI { constructor(hostUrl, apiKey, appToken, occupantToken) { if (hostUrl === null || hostUrl === undefined || hostUrl === '') { this.hostUrl = 'https://api.movemein.com.au/API' } else { this.hostUrl = hostUrl; } this.appToken = appToken; this.apiKey = apiKey; this.occupantToken = occupantToken; } getAuthorizationHeader() { if (this.apiKey === null || this.apiKey.trim() === '') return {}; return { 'Authorization': 'API_KEY ' + this.apiKey }; } async updateServiceOfferingStatus(serviceOfferingId, status) { let url = `UpdateServiceOfferingStatus?serviceOfferingId=${serviceOfferingId}&status=${status}`; return await this.makeApiCall(url, "POST", false, true); } async postAddInsureLead(serviceOfferingId) { let url = `PostAddInsuranceLead?serviceOfferingId=${serviceOfferingId}`; return await this.makeApiCall(url, "POST", false, true); } async createEmptyServiceOfferingData(connectionType) { let url = `CreateEmptyServiceOfferingData?connectionType=${connectionType}`; return await this.makeApiCall(url, "POST", false, true); } async createExternalReferral(connectionType, referrerIds) { let url = `PostExternalReferralConnection?connectionType=${connectionType}&externalReferralProviderIds=${referrerIds}`; return await this.makeApiCall(url, "POST", false, true) } async makeApiCall(url, type, alertBadResponse, throwBadResponse) { try { url = `/PurchasePal/AppToken/${this.appToken}/` + url; if (this.occupantToken != null && this.occupantToken != "") url += `&occupantAppToken=${this.occupantToken}`; const ajaxObject = { url: this.hostUrl + url, headers: this.getAuthorizationHeader(), async: true, type: type, xhrFields: { withCredentials: true } } if (type === "POST") { ajaxObject.processData = false; ajaxObject.contentType = false; } return await $.ajax(ajaxObject); } catch (e) { console.error(e); if (alertBadResponse === true) { siteUtilities.displayErrorModal("Error"); } if (throwBadResponse === true) { throw e; } } } } /* * This class handles the javascript logic for the service offering dial * on the index page and the service offering details view that slides up * after clikcing on a dial. */ class ServiceOfferingHelper { constructor(apiHelper, siteUtilities, signalRHelper) { this.apiHelper = apiHelper; this.siteUtilities = siteUtilities; this.signalRHelper = signalRHelper; this.initDial(); this.initDetailsView(); this.appToken = $('#hfAppToken').val(); this.occupantToken = $('#hfOccupantToken').val(); // Open first available offering if ($('#hfFromSignupOfferingId').length > 0) this.moveToNext($('#hfFromSignupOfferingId').val(), true) else this.moveToNext(undefined, true); } // General Methods ------------------------------- /* * This method updates the dial icon, the details status icon, * and posts the update to the API. */ async updateOfferingStatus(serviceOfferingId, newStatus, button) { // confirm if test link if (!this.siteUtilities.testLinkConfirm()) return; const dialItem = $(`.serviceOfferingDialItem[data-service-id="${serviceOfferingId}"]`); // store old dial item and currently selected details button if open in case of failure const currentClasses = $(dialItem).attr('class'); const currentlySelectedStatusButton = $('.serviceOfferingStatusCircle.selected'); try { // update dial icon, dial outer circle, and stop any highlighted animations this.updateDialIconStatus(dialItem, newStatus); this.updateOuterDialCircle(); // update details button if provided if (button != undefined) { $('.serviceOfferingStatusCircle').removeClass('selected'); if (newStatus != '0') { $(button).addClass('selected'); } await this.apiHelper.updateServiceOfferingStatus(serviceOfferingId, newStatus); } } catch (e) { console.error(e); // reset dial icon and button on failure $('.serviceOfferingStatusCircle').removeClass('selected'); $(currentlySelectedStatusButton).addClass('selected'); $(dialItem).attr('class', currentClasses); this.siteUtilities.displayErrorModal(); } } // Service Dial Methods -------------------------- initDial() { // Set listeners for dial icons this.setDialIconListeners(); } setDialIconListeners() { const helper = this; $('.serviceOfferingDialItem:not(.offering-excluded)').click(function () { try { const serviceId = this.dataset.serviceId; helper.openDetailsView(serviceId, helper.appToken, helper.occupantToken); } catch (e) { console.error(e); helper.siteUtilities.displayErrorModal(); helper.resetOfferingDetailsView(); } }); // Click out of service offering details $('html').click(function (event) { var skippedTags = []; skippedTags.push('a'); skippedTags.push('i'); skippedTags.push('button'); if (!skippedTags.includes(event.target.tagName.toLowerCase()) && $(event.target).closest('button, a, i').length === 0 && $(event.target).closest('.modal').length == 0 && $(event.target).closest("#serviceOfferingDetails").length === 0 && $(event.target).closest(".serviceOfferingDialItem").length === 0) { helper.closeOfferingDetails(); $('#serviceOfferingDetails').removeClass('d-flex'); $('#serviceOfferingDetails').hide("slide", { direction: "down" }, 200); } }) } updateDialIconStatus(dialItem, status) { dialItem.removeClass(function (index, className) { return (className.match(/(^|\s)serviceOfferingStatus\S+/g) || []).join(' '); }); dialItem.addClass(this.getIconClass(status)); } /* Method determines whether to show the Action Now, Completed, and Unconditional dial circles */ updateOuterDialCircle() { const incompleteConditionalIcons = $('.serviceOfferingDialItem:not(.serviceOfferingStatusComplete):not(.serviceOfferingStatusNotRequired)[data-service-stage="Conditional"]'); if (incompleteConditionalIcons.length > 0) { // Set to action now $('#ConditionalContainer').removeClass('d-none'); $('#UnconditionalContainer').addClass('d-none'); } else { // Set to complete $('#UnconditionalContainer').removeClass('d-none'); $('#ConditionalContainer').addClass('d-none'); } } getIconClass(newStatus) { switch (newStatus) { case "-1": return `serviceOfferingStatusNotRequired`; case "0": return `serviceOfferingStatusActionNow`; case "1": return `serviceOfferingStatusInProgress`; case "2": return `serviceOfferingStatusComplete`; default: console.error('no status foud for ' + newStatus); return ""; } } // Service Details Methods ----------------------- initDetailsView() { // Set listener for close offering details $('#closeLoadServiceOfferingDetailsButton').click(() => { this.closeOfferingDetails(); }); } closeOfferingDetails() { $('div.serviceOfferingDialItem').attr('data-selected', false); $('.serviceOfferingDialItem').attr('data-popup-active', false); document.getElementById('serviceOfferingDetails').dataset.serviceId = ""; this.initDetailsView(); this.resetOfferingDetailsView(); // make the dial big again if ($('.contentWrapper.dial').hasClass('dial-small')) { $('.contentWrapper.dial').removeClass('dial-small'); $('.contentWrapper.dial').css('width', '95%'); } } async openDetailsView(serviceId, appToken, occupantToken, reload) { if (reload == null) { reload = false; } if (!reload && document.getElementById('serviceOfferingDetails').dataset.serviceId == serviceId) { return; } // set all dial icons to unselected $('.serviceOfferingDialItem').attr('data-selected', false); // set all dial icons to data-popup-active = true (used for hiding pulse on icons) $('.serviceOfferingDialItem').attr('data-popup-active', true); // set clicked icon to selected const serviceIcon = $(`.serviceOfferingDialItem[data-service-id="${serviceId}"]`); $(serviceIcon).attr('data-selected', true); //this.resetOfferingDetailsView(); $('#serviceOfferingDetails').show("slide", { direction: "down" }, 200); $('#serviceOfferingDetails').addClass("d-flex"); $('#serviceOfferingDetails').attr("style", ""); serviceIcon[0].dataset.selected = true; // fetch service html and insert await this.siteUtilities.fetchHtml('#serviceOfferingDetailsContent', `/ServiceOfferingData/details?requestId=${appToken}&serviceOfferingId=${serviceId}&occupantId=${occupantToken}`); $('.loadServiceOfferingContainer').hide(); // set listeners for elements in the details page this.setDetailsViewListeners(); // Set signal R Listeners for status update if (this.signalRHelper != null) { this.signalRHelper.setServiceOfferingDetailsListener(); } document.getElementById('serviceOfferingDetails').dataset.serviceId = serviceId; // make the dial small var screenHeight = $(window).height(); var screenWidth = $(window).width(); var navbarHeight = $('.navbar').outerHeight(true); var detailsHeight = $('#serviceOfferingDetails').outerHeight(true); var newDialHeight = screenHeight - navbarHeight - detailsHeight - 15; if (newDialHeight < screenWidth - 15 && screenWidth < 425) { $('.contentWrapper.dial').addClass('dial-small'); $('.contentWrapper.dial').css('width', newDialHeight); } } setDetailsViewListeners() { const helper = this; // listener to change the status of the service offering $('.serviceOfferingStatusCircle').on('click', function () { const serviceOfferingId = this.dataset.offeringId; var newStatus = this.dataset.offeringStatus; if ($(this).hasClass('selected')) { newStatus = '0'; } helper.updateOfferingStatus(serviceOfferingId, newStatus, this); }); // Actioning service offering Buttons use AsyncCallbackButton html helper method $('.portal-action-button').on('click', function () { $(this).attr('disabled', 'disabled'); const url = this.dataset.actionurl; helper.siteUtilities.triggerAsyncBtnCallback(this, () => helper.openServiceOfferingLink(url)); }); $('.cbSendExternalReferral').on('change', function () { const serviceOfferingId = this.dataset.serviceId; const actionBtn = $('.service-action-btn.referral-action-button[data-service-id="' + serviceOfferingId + '"]'); const checked = $('input:checkbox.cbSendExternalReferral:checked'); if (checked != null && checked.length > 0) { actionBtn.removeClass('disabled'); actionBtn.removeAttr('disabled'); } else { actionBtn.addClass('disabled'); actionBtn.attr('disabled', 'disabled'); } }); $('form.serviceOfferingReferral-form').on('submit', function (event) { const serviceOfferingId = this.dataset.serviceId; const connectionType = this.dataset.connectionType; var form = $(this); var actionUrl = form.attr('action'); //event.preventDefault(); $('.referral-action-button').attr('disabled', 'disabled'); $.ajax({ type: "POST", url: actionUrl, data: form.serialize(), // serializes the form's elements. success: function (data) { helper.updateOfferingStatus(serviceOfferingId, "1"); helper.siteUtilities.displayErrorModal('Nice One!', "Your details have been sent, " + "you can expect a response from them soon."); } }); $('.referral-action-button').removeAttr('disabled'); helper.moveToNext(serviceOfferingId); }) $('.not-interested-btn').on('click', async function () { // confirm if test link if (!helper.siteUtilities.testLinkConfirm()) return; const serviceOfferingId = this.dataset.serviceId; helper.updateOfferingStatus(serviceOfferingId, "-1", this); helper.moveToNext(serviceOfferingId); }); $('.already-organised-btn').on('click', async function () { // confirm if test link if (!helper.siteUtilities.testLinkConfirm()) return; const serviceOfferingId = this.dataset.serviceId; helper.updateOfferingStatus(serviceOfferingId, "2", this); helper.moveToNext(serviceOfferingId); }); $('.step-not-interested').on('click', async function () { // confirm if test link if (!helper.siteUtilities.testLinkConfirm()) return; const serviceOfferingId = this.dataset.serviceId; helper.updateOfferingStatus(serviceOfferingId, "-1", this); helper.moveToNext(serviceOfferingId); }); $('.step-reset-no').on('click', () => { helper.changeStep(2); }); $('.step-restart-no').on('click', (event) => { // confirm if test link if (!helper.siteUtilities.testLinkConfirm()) return; const serviceOfferingId = event.target.dataset.serviceId; helper.updateOfferingStatus(serviceOfferingId, "0", event.target); helper.changeStep(2); }); $('.step-next').on('click', () => { const currentStep = helper.currentStep(); helper.changeStep(currentStep + 1); }); $('.step-skip').on('click', function () { // create empty service offering in data to avoid step 1 step 2 on open const connectionType = this.dataset.connectionType; //helper.createEmptyServiceOfferingData(connectionType); // remove not actioned class so move next doesnt open the same offering const serviceId = this.dataset.serviceId; helper.moveToNext(serviceId); }); $('.service-next-btn').on('click', function () { const serviceId = this.dataset.serviceId; helper.moveToNext(serviceId); }); $('.service-previous-btn').on('click', function () { const serviceId = this.dataset.serviceId; helper.moveToPrevious(serviceId); }); } async openServiceOfferingLink(url) { try { if (url != null && url != "") { let unencodedUrl = url.replace(/&/g, '&') window.location.href = unencodedUrl; } } catch (e) { console.error(e); this.siteUtilities.displayErrorModal(); } } async createEmptyServiceOfferingData(connectionType) { try { await this.apiHelper.createEmptyServiceOfferingData(connectionType); } catch (e) { console.error(e); this.siteUtilities.displayErrorModal(); } } currentStep() { if (!$('.offer-step-1').hasClass('d-none')) { return 1; } else if (!$('.offer-step-2').hasClass('d-none')) { return 2; } else if (!$('.offer-step-3').hasClass('d-none')) { return 3; } return 0; } changeStep(stepNo) { const hasStep1 = (/true/i).test(document.getElementById('hfHasStep1').value); const hasStep2 = (/true/i).test(document.getElementById('hfHasStep2').value); const hasStep3 = (/true/i).test(document.getElementById('hfHasStep3').value); $('.offer-step-1').addClass('d-none'); $('.offer-step-2').addClass('d-none'); $('.offer-step-3').addClass('d-none'); switch (stepNo) { case 1: if (hasStep1) { $('.offer-step-3').removeClass('d-none'); } break; case 2: if (hasStep2) { $('.offer-step-2').removeClass('d-none'); } else { $('.offer-step-3').removeClass('d-none'); } break; case 3: if (hasStep3) { $('.offer-step-3').removeClass('d-none'); } break; } } moveToPrevious(currentServiceId, actionOnly) { this.moveTo(currentServiceId, moveToOptions.previous, actionOnly); } moveToNext(currentServiceId, actionOnly) { this.moveTo(currentServiceId, moveToOptions.next, actionOnly); } moveTo(currentServiceId, moveToOption, actionOnly) { let availableElements = $(`.serviceOfferingDialItem${actionOnly === true ? '.serviceOfferingStatusActionNow' : ''}:not(.offering-excluded)`); let max = availableElements.length > 0 ? $(availableElements).last()[0].dataset.dialIndex : 0; // reverse list for looping if going to previous if (moveToOption == moveToOptions.previous) availableElements = $(availableElements).toArray().reverse(); let nextElem; if (currentServiceId == undefined) { nextElem = $(availableElements).first(); } else { let dialItemIndex = $(`.serviceOfferingDialItem[data-service-id="${currentServiceId}"]`)[0].dataset.dialIndex; $(availableElements).each(function (index) { if (nextElem != undefined) return; if ((moveToOption == moveToOptions.next && parseInt(this.dataset.dialIndex) > parseInt(dialItemIndex)) || (moveToOption == moveToOptions.previous && parseInt(this.dataset.dialIndex) < parseInt(dialItemIndex))) { nextElem = $(this); } else if (moveToOption == moveToOptions.next && parseInt(dialItemIndex) == parseInt(max)) { nextElem = $(availableElements).first(); } else if (moveToOption == moveToOptions.previous && (parseInt(this.dataset.dialIndex) == 0 || $(this.previousElementSibling).hasClass('offering-excluded'))) { nextElem = $(availableElements).first(); } }); } if (nextElem != undefined && nextElem[0] != undefined) { this.closeOfferingDetails(); this.openDetailsView(nextElem[0].dataset.serviceId, this.appToken, this.occupantToken); } else { this.closeOfferingDetails(); $('#serviceOfferingDetails').removeClass('d-flex'); $('#serviceOfferingDetails').hide("slide", { direction: "down" }, 200); } } resetOfferingDetailsView() { $('.loadServiceOfferingContainer').show(); $('#serviceOfferingDetailsContent').html(''); } } const moveToOptions = { next: 0, previous: 1 }; class SiteUtilities { constructor(testLink, demo) { this.testLink = testLink != null && testLink.toLowerCase() === "true"; this.demo = testLink != null && demo.toLowerCase() === "true"; } insertSpinner(selector) { let html = `
Loading...
`; $(selector).html(html); } removeSpinner(selector) { $(selector).html(''); } async fetchHtml(selector, url) { this.insertSpinner(selector); try { const data = await $.get(url); this.removeSpinner(selector); $('#serviceOfferingDetailsContent').html(data); } catch (e) { this.displayErrorModal("Error") this.removeSpinner(selector); } } displayErrorModal(header, bodyInnerHtml) { const errorModal = new bootstrap.Modal(document.getElementById('errorModal'), {}); $('#errorModalHeader').text(header != undefined ? header : "An unexpected error occoured."); $('#errorModalBody').html(bodyInnerHtml ?? "We could not complete your request at this time. Please contact us on 0401 648 791."); errorModal.show(); } insertButtonSpinner(selector) { let html = `
Loading...
`; $(selector).html(html); } async triggerAsyncBtnCallback(button, asyncCallback) { try { await (new Promise(res => { $(button).find('.callback-button-content').slideUp('fast', function () { $(button).find('.callback-button-spinner').slideDown('fast', function () { res(); }); //await asyncCallback(); }); })); await asyncCallback(); } catch (e) { console.error(e); } finally { //setTimeout(function () { //$(button).find('.callback-button-spinner').slideUp('fast', function () { // //$(button).find('.callback-button-content').slideDown('fast'); //}); //}, 2000); } } testLinkConfirm() { // dont show alert if link is not a test if (this.demo || !this.testLink) return true; return confirm("Are you sure youd like to perform this action?"); } isEmail(email) { let regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; return regex.test(email); } isMobile(mobile) { let regex = /^0[0-8]\d{8}$/g; return regex.test(mobile); } formatMobile(tbMobile) { // remove any non numerical characters var strippedMobile = tbMobile.value.replace(/\D/g, ''); // if stripped mobile begins with 614, replace the 61 with a 0 if (strippedMobile.substring(0, 3) === '614') strippedMobile = '0' + strippedMobile.substring(2); // if stripped mobile begins with 610, replace the 610 with a 0 if (strippedMobile.substring(0, 3) === '610') strippedMobile = '0' + strippedMobile.substring(3); tbMobile.value = strippedMobile; } } class StorageHelper { static GetFromStorage(key) { return JSON.parse(localStorage.getItem(key)); } static SetStorage(key, value) { localStorage.setItem(key, JSON.stringify(value)); } } class SignalRService { constructor(logToken, appToken, occupantToken, testing, contactChannel) { this.logToken = logToken; this.appToken = appToken; this.occupantToken = occupantToken; this.testing = testing; this.contactChannel = contactChannel; this.Initialised = false; this.connectionId = null; this.initService(); } async initService() { var helper = this; // Start hub and set user events $.connection.hub.qs = { "token": helper.logToken, "appToken": helper.appToken, "occupantToken": helper.occupantToken, "contactChannel": helper.contactChannel }; helper.logHub = $.connection.purchasePalLogHub; helper.loadClientMethods(helper.logHub); $.connection.hub.start() .done(function () { helper.Initialised = true; helper.setUserEventHandlers(); helper.connectionId = $.connection.hub.id; }); $.connection.hub.disconnected(function () { setTimeout(function () { helper.Initialised = false; $.connection.hub.start(); helper.Initialised = true; }, 2000); // Restart connection after 2 seconds. }); } loadClientMethods(objHub) { var helper = this; objHub.client.onConnected = function (connectionID) { //console.log('connected'); } } setUserEventHandlers() { // declaring service to use when scope of 'this' changes const service = this; // Link clicks $('a').click(function () { service.logActivity(this, userEvents.click); }); // button clicks $(':button').click(function () { let userEvent = userEvents.click; service.logActivity(this, userEvent); }); // Dial icons $('.serviceOfferingDialItem').click(function () { service.logActivity(this, userEvents.dialIcon); }); // modal shown $('.modal').on('shown.bs.modal', function () { service.logActivity(this, userEvents.showModal); }); // service offering update this.setServiceOfferingDetailsListener(); } // Done as a seperate function as these elements can appear after page load setServiceOfferingDetailsListener() { const service = this; $('.serviceOfferingStatusCircle').click(function () { service.logActivity(this, userEvents.manualStatusUpdate); }); $('.service-action-btn').click(function () { service.logActivity(this, userEvents.navigateToService); }); } logActivity(element, userEvent) { if (this.testing || element == null) return; const messageComponents = { id: $(element).attr('id'), type: 0, srcUrl: null, userEvent: userEvent }; this.logHub.invoke('LogNewEvent', messageComponents.id, messageComponents.type, messageComponents.srcUrl, messageComponents.userEvent, this.connectionId ).done().fail(); } } const userEvents = { click: 1, open: 2, close: 5, changePage: 6, showModal: 7, backgroundEvent: 9, manualStatusUpdate: 12, navigateToService: 13, dialIcon: 14, }