fwk-quasar
Version:
Framework main store
485 lines (464 loc) • 15.3 kB
JavaScript
import { reactive, readonly } from 'vue'
import { ui } from 'fwk-q-ui'
import { Platform } from 'quasar'
import apiSrv from 'fwk-api'
import bus from 'fwk-bus'
import localStorage from 'fwk-localstorage'
import { App } from '@capacitor/App'
import { Clipboard } from '@capacitor/clipboard'
import { AppLauncher } from '@capacitor/app-launcher'
import evtEmitter from 'fwk-events'
console.log('fwk-quasar CONSTRUCTOR')
const state = reactive({
enableLog: !!localStorage.get('DEB_enableLog'),
authcode: !!localStorage.get('DEB_authcode'),
mockmode: !!localStorage.get('DEB_mockmode'),
loginMsgId: undefined,
isLaunched: false,
environment: {},
validatePendings: undefined,
isMobile: flagMobile(),
legacySAF: false,
urlDomain: '',
extWindow: undefined,
isRoot: false,
msg: undefined,
info: undefined,
payload: undefined,
userInfoMsg: undefined,
autologinFn: undefined,
notifyOpsInfo: undefined,
notifyOpsError: undefined,
logoutFn: async () => { console.log('logoutFn not set...') },
notifyInfoFn: () => { console.log('notifyInfoFn not set....') },
notifyCatchFn: () => { console.log('notifyCatchFn not set....') }
})
const actions = {
/////////////////////////////////////
// COMUNICATIONS
/////////////////////////////////////
async init (env, info) {
console.log('fwk-quasar init')
state.info = info
state.isRoot = !!info
state.urlDomain = evalEnvUrl(env)
state.environment = env
await bus.init({
isMobile: state.isMobile,
appName: state.environment.appName,
packageName: state.environment.apkTbx,
env: state.environment.environment
})
if (state.isRoot)
initRootApp()
else {
initChildApp()
}
},
getIsActive: async () => {
const { isActive } = await App.getState()
return isActive
},
setNotifyOpsInfo (ops) {
console.log('store setNotifyOpsInfo:', ops)
state.notifyOpsInfo = ops
},
setNotifyOpsError (ops) {
console.log('store setNotifyOpsError:', ops)
state.notifyOpsError = ops
},
setEnableLog (flag) {
console.log('store setEnableLog:', flag)
state.enableLog = flag
localStorage.set('DEB_enableLog', flag)
console.log = flag ? console.log : () => {}
},
setAuthcode (flag) {
console.log('store setAuthcode:', flag)
state.authcode = flag
localStorage.set('DEB_authcode', flag)
apiSrv.setAuthcode(flag)
},
setMockmode (flag) {
console.log('store setMockmode:', flag)
state.mockmode = flag
localStorage.set('DEB_mockmode', flag)
apiSrv.setMockFlag(flag)
},
setLogoutFn (fn) {
console.log('store setLogoutFn:')
state.logoutFn = async () => {
await deleteUserInfoMsg()
await fn()
}
apiSrv.setAuthExpFn(state.logoutFn)
},
setUserInfoMsg (o) {
console.log('store setUserInfoMsg:', o)
state.userInfoMsg = o
},
setLoginMsgId (id) {
console.log('store setLoginMsgId:', id)
state.loginMsgId = id
},
setMsg (msg) {
console.log('store setMsg:', msg)
state.msg = msg
},
setInfo (info) {
console.log('store setInfo:', info)
state.info = info
},
setPayload (pl) {
console.log('store setPayload:', pl)
state.payload = pl
},
async updateUserInfoMsg (user) {
actions.setUserInfoMsg(user)
//bus.updateMessage(state.userInfoMsg)
},
async sendBusMsg (obj) {
const datetime = await bus.insertMessage(obj)
if (obj.type === 'login') {
actions.setLoginMsgId(datetime)
}
},
async exitApplication () {
await bus.exitApplication(state.legacySAF)
},
async copyToClipboard (pl) {
if (state.isMobile) {
let clip = ''
try {
const { value } = await Clipboard.read()
clip = evalClip(value)
} catch (error) {
console.log('error en clipboard vacio:', error)
}
pl = { ...pl, clip }
const jsonStr = JSON.stringify(pl)
await Clipboard.write({ string: jsonStr })
} else {
const o = await window.navigator.clipboard.readText()
const clip = evalClip(o)
pl = { ...pl, clip }
const jsonStr = JSON.stringify(pl)
console.log('clipboard TBX:', jsonStr)
await window.navigator.clipboard.writeText(jsonStr)
}
},
/////////////////////////////////////
initBeforeRoutes (routes) {
routes.forEach(ch => {
console.log('initBeforeRoute:', ch)
ch.beforeEnter = (to, from, next) => {
console.log('beforeEnter event:', to.fullPath, from.fullPath)
if (state.validatePendings) {
state.validatePendings(to, from, next)
}
else
next()
}
})
},
setValidatePendings (fn) {
console.log('store main setValidatePendings.............')
state.validatePendings = fn
},
setNotifyInfoFn (fn) {
console.log('store setNotifyInfoFn')
state.notifyInfoFn = fn
},
setNotifyCatchFn (fn) {
console.log('store setNotifyCatchFn')
state.notifyCatchFn = fn
},
setAutologinFn (fn) {
console.log('store setAutologinFn')
state.autologinFn = fn
},
async launchApp (pkgName, url) {
if (state.isMobile) {
await AppLauncher.openUrl({ url: pkgName })
} else {
openUrl(url)
}
},
async updateVersion () {
const lastVersionTool = `FWK_lastVersionUpdate_${state.environment.appName}`
const lastVersionUpdate = await localStorage.get(lastVersionTool)
const today = new Date().getDate().toString()
if (today !== lastVersionUpdate) {
localStorage.set(lastVersionTool, today)
const payload = {
origen: flagMobile(),
tool: state.environment.appName,
version: state.environment.versionName
}
apiSrv.callSrv('POST', '/metricas/actualizaVersion', payload)
}
},
async callBackend (preCallback, ops) {
let options = {
noLoader: false,
type: 'spinner', //'progressBar'
color: 'white',
timeout: -1
}
if (ops) {
options = { ...options, ...ops }
}
let res
try {
if (!options.noLoader)
ui.actions.showLoading(options)
res = await preCallback()
if (res?.info?.msg) {
res = state.notifyInfoFn(res)
}
if (typeof (res) === 'string') {
const reg = /support ID is: ([^<]+)/gm
const evalSecurityError = res.match(reg)
if (evalSecurityError) {
state.notifyCatchFn({ message: `Ha ocurrido un error con seguridad informatica: ${evalSecurityError[0]}` })
res = false
}
}
} catch (error) {
state.notifyCatchFn(error)
} finally {
if (!options.noLoader)
ui.actions.hideLoading()
}
return res
}
}
export const main = {
state: readonly(state),
actions
}
actions.setNotifyInfoFn((res) => {
const m = res?.info?.msg || res?.info?.message
if (m) {
console.log('Notify INFO:', m)
ui.actions.notify(m, res.info.type, state.notifyOpsInfo)
res = (res.info.data) ? res.info.data : ((res.info.type !== 'error') && (res.info.type !== 'warning'))
}
return res
})
actions.setNotifyCatchFn((error) => {
console.log('Notify ERROR:', error)
ui.actions.notify(error.message, 'error', state.notifyOpsError)
})
async function deleteUserInfoMsg () {
if (state.loginMsgId)
await bus.deleteMessage(state.loginMsgId)
}
/////////////////////////////////////
// COMUNICATIONS
/////////////////////////////////////
async function initRootApp () { // INBOX/TBX || APKs Children localhost
App.addListener('appStateChange', async ({ isActive }) => {
if (isActive && state.userInfoMsg) {
evtEmitter.emit('onAppStateChange')
processMessages()
}
})
//apiSrv.setAuthExpFn(async () => {
// await deleteUserInfoMsg()
//})
const res = await processMessages('login')
if (state.info.origApp === state.info.appName) {
if (res.length === 0) {
await initApiRest()
state.isLaunched = true
evtEmitter.emit('onAppStateChange')
}
}
else { // localhost
if (res.length === 0) {
initLauncherInfo(state.info)
await initApiRest()
console.log('AUTOLOGIN:' + state.info)
await state.autologinFn()
}
}
}
async function initChildApp () {
const flag = await App.getState()
await initChildConfig(flag)
App.addListener('appStateChange', async ({ isActive }) => {
if (isActive) {
await initChildConfig(isActive)
processMessages()
}
})
}
async function initChildConfig (isActive) {
if (!state.isLaunched && isActive) {
const clipdata = await loadClipboardData()
const { isValidClipboard, value } = validateClipboardData(clipdata) // {} - {json valido} - {json NO valido}
state.legacySAF = isValidClipboard
if (isValidClipboard) { // ORIG TOOLBOX
apiSrv.setAuthExpFn(async () => {
const obj = { logout: true }
await actions.copyToClipboard(obj)
await actions.exitApplication()
})
initLauncherInfo(value.info)
await initApiRest({ authorization: value.payload.authorization, legajo: value.payload.username, legajoCSG: value.payload.usernameCSG })
initUserInfo(value.info)
}
else { // ORIG TBX/INBOX (apks satelites)
apiSrv.setAuthExpFn(async () => {
const obj = {
target: state.info.origApp,
payload: {},
type: 'logout'
}
await actions.sendBusMsg(obj)
await actions.exitApplication()
})
const res = await processMessages()
if (res.length === 0) {
ui.actions.notify('La aplicación debe ejecutarse desde TBX!', 'error')
actions.exitApplication()
}
}
}
}
function initLauncherInfo (nfo) {
state.info = nfo
let orig = state.info.origApp
//if (!orig) orig = 'toolbox'
const capOrig = orig.charAt(0).toUpperCase() + orig.slice(1)
bus.setOrigApk(state.legacySAF ? state.environment.apkToolbox : state.environment[`apk${capOrig}`])
bus.setOrigUrl(state.legacySAF ? state.environment.urlToolbox : state.environment[`url${capOrig}`])
bus.setOrigApp(orig)
}
function initUserInfo (usr) {
actions.setUserInfoMsg(usr)
actions.updateVersion()
state.isLaunched = true
}
async function callbackMessages (o) {
console.log('callbackMessages from CP or IDB:', o)
o.payload = (Object.keys(o.payload).length > 0) ? JSON.parse(o.payload) : {}
if (o.type === 'login') { // only roots
actions.setLoginMsgId(o.datetime)
await initApiRest({ authorization: o.payload.authorization, legajo: o.payload.username, legajoCSG: o.payload.usernameCSG })
initUserInfo(o.payload)
evtEmitter.emit('onAppStateChange')
}
if (o.type === 'launcher') {
initLauncherInfo(o.payload.info)
await initApiRest({ authorization: o.payload.info.authorization, legajo: o.payload.info.username, legajoCSG: o.payload.info.usernameCSG })
initUserInfo(o.payload.data)
}
if (o.type === 'saf') {
apiSrv.queueSAFMessages(o.payload)
}
if (o.type === 'logout') {
state.logoutFn()
//apiSrv.getAuthExpFn()
}
if (o.type === 'close') {
state.extWindow.close()
}
}
async function processMessages (type) {
const arr = await bus.getMyMessages(type)
if (arr.length) {
for (const o of arr) {
callbackMessages(o)
}
}
return arr
}
function openUrl (url) {
state.extWindow = window.open(url, 'nnn')
}
function evalClip (o) {
let result = ''
if (typeof (o) === 'string') {
if (o.length < 500)
result = o
}
return result
}
async function initApiRest (o) {
const headers = {
mockmode: state.info.mockmode,
legajo: o?.legajo || state.info.legajo,
legajoCSG: o?.legajoCSG || state.info.legajoCSG,
isMobile: state.isMobile,
authorization: o?.authorization || ''
}
await apiSrv.init({ url: state.urlDomain, headers, isSAFManager: state.isRoot })
actions.setEnableLog(localStorage.get('DEB_enableLog') || false)
actions.setAuthcode(localStorage.get('DEB_authcode') || true)
actions.setMockmode(localStorage.get('DEB_mockmode') || false)
}
///////////////////////////////////////////////////////////////////////////////////////////////
function validateClipboardData (src) {
try {
const obj = JSON.parse(src)
if (obj.info && obj.payload) {
postProcessInfo(obj)
return { isValidClipboard: true, value: obj }
}
else
return { isValidClipboard: false, value: obj }
} catch (error) {
console.log('error: Not a JSON')
return { isValidClipboard: false, value: src }
}
}
function evalEnvUrl (env) {
let addr = env.urlBase + env.wfx
if (state.isMobile) {
//window.screen.orientation.lock('portrait')
if (env.environment === 'DESA' || env.environment === 'INTE') {
addr = addr.substr(0, 4) + addr.substr(5)
}
}
console.log('addr mobile:', addr)
return addr
}
async function loadClipboardData () {
let src
try {
if (state.isMobile) {
const result = await Clipboard.read()
src = result?.value
console.log('Clipboard.read(): ', src)
}
else {
src = await navigator.clipboard.readText()
console.log('navigator.clipboard.readText(): ', src)
}
} catch (error) {
src = undefined
}
return src
}
async function postProcessInfo (source) {
if (state.isMobile) {
Clipboard.write({ string: source.clip })
delete source.clip
}
else {
await navigator.clipboard.writeText(source.clip)
delete source.clip
}
}
function flagMobile () {
const isAndroid = /Build/i.test(navigator.userAgent)
return isAndroid
//const flag =
// (Platform.is.android && Platform.is.capacitor &&
// !Platform.is.win &&
// !Platform.is.mac &&
// !Platform.is.linux) === true
//return flag
}