File "utilities.js"
Full Path: /home/pulsehostuk9/public_html/invoicer.pulsehost.co.uk/resources/scripts/helpers/utilities.js
File size: 7.07 KB
MIME-type: text/plain
Charset: utf-8
import i18n from '../plugins/i18n'
const { global } = i18n
import { useNotificationStore } from '@/scripts/stores/notification'
import { isArray } from 'lodash'
export default {
isImageFile(fileType) {
const validImageTypes = ['image/gif', 'image/jpeg', 'image/png']
return validImageTypes.includes(fileType)
},
addClass(el, className) {
if (el.classList) el.classList.add(className)
else el.className += ' ' + className
},
hasClass(el, className) {
const hasClass = el.classList
? el.classList.contains(className)
: new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className)
return hasClass
},
formatMoney(amount, currency = 0) {
if (!currency) {
currency = {
precision: 2,
thousand_separator: ',',
decimal_separator: '.',
symbol: '$',
}
}
amount = amount / 100
let {
precision,
decimal_separator,
thousand_separator,
symbol,
swap_currency_symbol,
} = currency
try {
precision = Math.abs(precision)
precision = isNaN(precision) ? 2 : precision
const negativeSign = amount < 0 ? '-' : ''
let i = parseInt(
(amount = Math.abs(Number(amount) || 0).toFixed(precision))
).toString()
let j = i.length > 3 ? i.length % 3 : 0
let moneySymbol = `${symbol}`
let thousandText = j ? i.substr(0, j) + thousand_separator : ''
let amountText = i
.substr(j)
.replace(/(\d{3})(?=\d)/g, '$1' + thousand_separator)
let precisionText = precision
? decimal_separator +
Math.abs(amount - i)
.toFixed(precision)
.slice(2)
: ''
let combinedAmountText =
negativeSign + thousandText + amountText + precisionText
return swap_currency_symbol
? combinedAmountText + ' ' + moneySymbol
: moneySymbol + ' ' + combinedAmountText
} catch (e) {
console.error(e)
}
},
// Merge two objects but only existing properties
mergeSettings(target, source) {
Object.keys(source).forEach(function (key) {
if (key in target) {
// or target.hasOwnProperty(key)
target[key] = source[key]
}
})
},
checkValidUrl(url) {
if (
url.includes('http://localhost') ||
url.includes('http://127.0.0.1') ||
url.includes('https://localhost') ||
url.includes('https://127.0.0.1')
) {
return true
}
let pattern = new RegExp(
'^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$',
'i'
) // fragment locator
return !!pattern.test(url)
},
checkValidDomainUrl(url) {
if (url.includes('localhost') || url.includes('127.0.0.1')) {
return true
}
let pattern = new RegExp(
'^(https?:\\/\\/)?' + // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))' + // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?' + // query string
'(\\#[-a-z\\d_]*)?$',
'i'
) // fragment locator
return !!pattern.test(url)
},
fallbackCopyTextToClipboard(text) {
var textArea = document.createElement('textarea')
textArea.value = text
// Avoid scrolling to bottom
textArea.style.top = '0'
textArea.style.left = '0'
textArea.style.position = 'fixed'
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
try {
var successful = document.execCommand('copy')
var msg = successful ? 'successful' : 'unsuccessful'
console.log('Fallback: Copying text command was ' + msg)
} catch (err) {
console.error('Fallback: Oops, unable to copy', err)
}
document.body.removeChild(textArea)
},
copyTextToClipboard(text) {
if (!navigator.clipboard) {
this.fallbackCopyTextToClipboard(text)
return
}
navigator.clipboard.writeText(text).then(
function () {
return true
},
function (err) {
return false
}
)
},
arrayDifference(array1, array2) {
return array1?.filter((i) => {
return array2?.indexOf(i) < 0
})
},
getBadgeStatusColor(status) {
switch (status) {
case 'DRAFT':
return {
bgColor: '#F8EDCB',
color: '#744210',
}
case 'PAID':
return {
bgColor: '#D5EED0',
color: '#276749',
}
case 'UNPAID':
return {
bgColor: '#F8EDC',
color: '#744210',
}
case 'SENT':
return {
bgColor: 'rgba(246, 208, 154, 0.4)',
color: '#975a16',
}
case 'REJECTED':
return {
bgColor: '#E1E0EA',
color: '#1A1841',
}
case 'ACCEPTED':
return {
bgColor: '#D5EED0',
color: '#276749',
}
case 'VIEWED':
return {
bgColor: '#C9E3EC',
color: '#2c5282',
}
case 'EXPIRED':
return {
bgColor: '#FED7D7',
color: '#c53030',
}
case 'PARTIALLY PAID':
return {
bgColor: '#C9E3EC',
color: '#2c5282',
}
case 'COMPLETED':
return {
bgColor: '#D5EED0',
color: '#276749',
}
case 'DUE':
return {
bgColor: '#F8EDCB',
color: '#744210',
}
case 'YES':
return {
bgColor: '#D5EED0',
color: '#276749',
}
case 'NO':
return {
bgColor: '#FED7D7',
color: '#c53030',
}
}
},
getStatusTranslation(status) {
switch (status) {
case 'DRAFT':
return global.t('general.draft')
case 'PAID':
return global.t('invoices.paid')
case 'UNPAID':
return global.t('invoices.unpaid')
case 'SENT':
return global.t('general.sent')
case 'REJECTED':
return global.t('estimates.rejected')
case 'ACCEPTED':
return global.t('estimates.accepted')
case 'VIEWED':
return global.t('invoices.viewed')
case 'EXPIRED':
return global.t('estimates.expired')
case 'PARTIALLY PAID':
return global.t('estimates.partially_paid')
case 'COMPLETED':
return global.t('invoices.completed')
case 'DUE':
return global.t('general.due')
default:
return status
}
},
toFormData(object) {
const formData = new FormData()
Object.keys(object).forEach((key) => {
if (isArray(object[key])) {
formData.append(key, JSON.stringify(object[key]))
} else {
// Convert null to empty strings (because formData does not support null values and converts it to string)
if (object[key] === null) {
object[key] = ''
}
formData.append(key, object[key])
}
})
return formData
},
}