Files
DredgePos/wwwroot/scripts/ts/dredgepos.core.ts
2022-01-23 18:16:18 +10:00

239 lines
6.7 KiB
TypeScript

/// <reference path="./typings/currency.d.ts" />
const Application: ApplicationState = {
keyboard: null,
mode: [],
languageVars: {}
}
/** Parses a language variable. */
const lang = (key: string, replacements?: string[] | string) => {
let finalValue = Application.languageVars[key] || ''
if (!replacements) return finalValue
if (typeof replacements === 'string') replacements = [replacements]
replacements.forEach((replacement, index) => {
const correctIndex = index + 1
finalValue = finalValue.replace(`[${correctIndex}]`, replacement)
})
return finalValue
}
/** Check if a variable is defined */
const defined = (variable: any) => {
return typeof variable !== 'undefined'
}
/** Call an Ajax function asynchronously */
const ajax = (endpoint: string, data: any, method = 'POST', successFunction: Function, errorFunction: Function, beforeFunction: any) => {
data = (data == null) ? data : JSON.stringify(data)
return $.ajax({
url: endpoint,
method: method,
data: data,
success: (response: ajaxResult) => {
if (successFunction && response.status == 'success')
successFunction(JSON.parse(response.data))
else if (errorFunction && response.status != 'success') {
errorFunction(JSON.parse(response.data))
}
},
error: (error) => console.log(error.statusCode),
beforeSend: beforeFunction
})
}
/*
For the flow of the app, synchronous is commonly preferred
though trying to keep its usage as low as possible.
*/
const ajaxSync = (endpoint: string, data?: any, method = 'POST') => {
const response = JSON.parse(
$.ajax({
url: endpoint,
method: method,
data: JSON.stringify(data),
async: false,
}).responseText)
if (response.data) {
response.data = JSON.parse(response.data)
return response.data
}
return response
}
/* Redirect to a specific URL */
const redirect = (url: string): void => location.assign(url)
const resize = () => {
$('#pageContainer').height(window.innerHeight + "px");
}
const setupCore = (languageVars: Record<string, string>) => {
Application.languageVars = languageVars
const doc = $(document)
doc.on('click', '#alertNo, #alertOk', hideAlerts)
doc.on('click', '.toggle', toggle)
window.addEventListener('resize', resize)
resize()
setElementVisibilityByMode()
}
const posAlert = (message: string, title = 'Message') => {
const alertBox = $('#alert')
alertBox.css('display', 'flex');
alertBox.data('value', '');
$('#alertHeading').text(title);
$('#alertMessage').text(message);
$('#alertOk').css('display', 'flex');
$('#alertYes').css('display', 'none');
$('#alertNo').css('display', 'none');
}
const confirmation = (message: string, data: any, title = 'Confirm', submitFunction = (data: any) => {hideAlerts()}) => {
const alert = $('#alert')
$(document).on('click', '#alert #alertYes', () => {
hideAlerts()
submitFunction(data)
$(document).off('click', '#alert #alertYes')
})
alert.css('display', 'flex')
$('#alertHeading').html(title)
$('#alertMessage').html(message)
$('#alertOk').css('display', 'none')
$('#alertYes').css('display', 'flex')
$('#alertNo').css('display', 'flex')
}
const hideAlerts = () => $('#alert').hide()
const turnOnMode = (mode: PosMode) => {
Application.mode.push(mode)
setElementVisibilityByMode()
}
const turnOffMode = (mode: PosMode) => {
Application.mode = Application.mode.filter((value) => value != mode)
setElementVisibilityByMode()
}
const toggleMode = (mode: PosMode) => {
if (!isInMode(mode))
turnOnMode(mode)
else
turnOffMode(mode)
}
const clearModes = () => {
Application.mode = []
setElementVisibilityByMode()
}
const isInMode = (mode: PosMode) => Application.mode.includes(mode)
const setElementVisibilityByMode = () => {
const mode = Application.mode
const elements = $('[data-visible-in-mode]')
elements.each((index, elem) => {
const element = $(elem)
const visibleInModes: PosModes = element.data('visible-in-mode')
const showElement = visibleInModes.every(visibleMode => {
return mode.includes(visibleMode)
});
if (element.hasClass('useVisibility')) {
if (showElement) {
element.css('visibility', 'visible')
} else element.css('visibility', 'hidden')
} else element.toggle(showElement)
})
const invisibleElements = $('[data-invisible-in-mode]')
invisibleElements.each((index, elem) => {
const element = $(elem)
const inVisibleInModes: PosModes = element.data('invisible-in-mode')
const hideElement = inVisibleInModes.some(invisibleMode => {
return mode.includes(invisibleMode)
})
element.toggle(!hideElement)
})
$('[data-active-in-mode]').each((index, elem) => {
const button = $(elem)
const activeInMode: PosMode = button.data('active-in-mode')
mode.includes(activeInMode)
? button.addClass('active')
: button.removeClass('active')
})
}
const pulseElement = (element: JQuery) => element.addClass('pulse').on('animationend', () => element.removeClass('pulse'))
Array.prototype.where = function<x>(this: x[], property: string, value: any) {
return this.filter( item => (item as any)[property] === value)[0] || null
}
const money = (amount: number, fromCents=true) => currency(amount, {fromCents: fromCents})
const moneyFromString = (amount: string) => currency(amount)
const toggle = (e: JQuery.TriggeredEvent) => {
const button = $(e.target)
const toggleGroup = button.closest('.toggleGroup')
const input = toggleGroup.find('input.value')
const isActive = button.hasClass('active')
toggleGroup
.find('.toggle')
.removeClass('active')
let value = !isActive
? button.addClass('active').data('value')
: toggleGroup
.find('.toggle.default')
.addClass('active')
.data('value')
input.val(value).trigger('change')
}
const resetToggle = (input: JQuery) => {
input
.closest('.toggleGroup')
.find('.toggle.default')
.trigger('click')
}
//Id generator.
function* newestId(){
let id = 0
while(true){
id++
yield id
}
}
const loadTemplate = (templateSelector: string) => {
const content = $(templateSelector)
.clone()
.removeAttr('id')
.prop('content')
return $(content)
}
$(() => ajax('/ajax/languageVars', null, 'GET', setupCore, null, null))