update project with new architecture
This commit is contained in:
		
							
								
								
									
										216
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/auth.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										216
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/auth.js
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,216 @@ | ||||
| "use strict"; | ||||
| var pwa = pwa || {}; | ||||
| /* | ||||
| Manage user authentification and registration | ||||
| ________________________ | ||||
| pwa.auth.route() | ||||
|   manage from state.json route if authenticated or not | ||||
|   redirect public page or app page | ||||
| ________________________ | ||||
| pwa.auth.screenlogin() | ||||
|   show login modal | ||||
| ________________________ | ||||
| pwa.auth.getlinkwithoutpsw() | ||||
|     special get with token and uuid workeable for 24h this link is une onetime | ||||
| _________________________ | ||||
| pwa.auth.isAuthenticate() | ||||
|   test if token is still ok or not return false/true | ||||
| _________________________ | ||||
| pwa.auth.authentification({LOGIN,PASSWORD}) | ||||
|   if ok => load pwa.state.data.app .headers .userlogin | ||||
| _________________________ | ||||
| pwa.auth.login() | ||||
|   Manage login modal to get login psw value and submit it to pwa.auth.authentification() | ||||
| _________________________ | ||||
| pwa.auth.logout() | ||||
|   Remove localstorage and reload | ||||
| _________________________ | ||||
| pwa.auth.register() | ||||
|    @TODO | ||||
| __________________________ | ||||
| pwa.auth.forgetpsw() | ||||
|   Request to send an email with a unique get link to access from this link to the app | ||||
|  | ||||
| */ | ||||
| /*MODULEJS*/ | ||||
| //--## | ||||
| pwa.auth = {}; | ||||
| // Refresh browser state if exist else get pwa.state defaults | ||||
| //pwa.state.ready( pwa.auth.check ); | ||||
|  | ||||
| pwa.auth.Checkjson = () => { | ||||
| 	if( pwa.state.data.login.isAuthenticated ) { | ||||
| 		if( !pwa.auth.isAuthenticate() ) { | ||||
| 			// Then reinit local storage and refresh page | ||||
| 			pwa.state.data.login.isAuthenticated = false; | ||||
| 			pwa.state.save(); | ||||
| 			//alert( 'reload page cause no more auth' ) | ||||
| 			window.location.reload(); | ||||
| 		}; | ||||
| 	} | ||||
| }; | ||||
| pwa.auth.route = ( destination ) => { | ||||
| 	console.log( 'auth.route to', destination ); | ||||
| 	//if check Authenticated && exist #signin button[data-routeto] then redirect browser to button[data-routeto] | ||||
| 	//else manage component action auth | ||||
| 	if( pwa.state && pwa.state.data && pwa.state.data.login && pwa.state.data.login.isAuthenticated ) { | ||||
| 		if( destination ) | ||||
| 			window.location.pathname = `${pwa.state.data.ctx.urlbase}/${destination}`; | ||||
| 	} else { | ||||
|     [ "#signin", "#resetpsw", "#register" ].forEach( e => { | ||||
| 			if( e == destination ) { | ||||
| 				document.querySelector( e ) | ||||
| 					.classList.remove( 'd-none' ); | ||||
| 			} else { | ||||
| 				document.querySelector( e ) | ||||
| 					.classList.add( 'd-none' ); | ||||
| 			} | ||||
| 		} ) | ||||
| 	} | ||||
| } | ||||
| pwa.auth.isAuthenticate = async function () { | ||||
| 	// in any request, if middleware isAuthenticated return false | ||||
| 	// then headers Xuuid is set to 1 | ||||
| 	// then try pwa.auth.isAuthenticate if rememberMe auto reconnect | ||||
| 	// if jwt is ok then return true in other case => false | ||||
| 	// this is the first test then depending of action see ACCESSRIGHTS of user | ||||
| 	console.log( 'lance isauth', { | ||||
| 		headers: pwa.state.data.headers.xpaganid | ||||
| 	} ) | ||||
| 	//alert( 'uuid ' + pwa.state.data.headers.xpaganid ) | ||||
| 	console.log( `https://${pwa.state.data.ctx.urlbackoffice}/users/isauth`, { | ||||
| 		headers: pwa.state.data.headers | ||||
| 	} ) | ||||
| 	try { | ||||
| 		const repisauth = await axios.get( `https://${pwa.state.data.ctx.urlbackoffice}/users/isauth`, { | ||||
| 			headers: pwa.state.data.headers | ||||
| 		} ) | ||||
| 		console.log( repisauth ) | ||||
| 		console.log( 'isAauthenticate: yes' ) | ||||
| 		return true; | ||||
| 	} catch ( err ) { | ||||
| 		if( err.response ) { console.log( "response err ", err.response.data ) } | ||||
| 		if( err.request ) { console.log( "request err", err.request ) } | ||||
| 		console.log( 'isAuthenticate: no' ) | ||||
| 		pwa.state.data.headers.xpaganid = "1"; | ||||
| 		if( pwa.state.data.login.rememberMe.login ) { | ||||
| 			if( await pwa.auth.authentification( pwa.state.data.login.rememberMe ) ) { | ||||
| 				return await pwa.auth.isAuthenticate(); | ||||
| 			}; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| }; | ||||
| pwa.auth.authentification = async function ( data ) { | ||||
| 	// Core client function to chech auth from login & psw | ||||
| 	// In case of 403 error lauch pwa.authentification(pwa.app.rememberMe) | ||||
| 	// in case of sucess update paw.state.data.login | ||||
| 	console.groupCollapsed( "Post Authentification for standard on :  https://" + pwa.state.data.ctx.urlbackoffice + "/users/login param data", data ) | ||||
|  | ||||
| 	console.log( 'header de login', pwa.state.data.headers ) | ||||
| 	let auth; | ||||
| 	try { | ||||
| 		auth = await axios.post( `https://${pwa.state.data.ctx.urlbackoffice }/users/login`, data, { | ||||
| 			headers: pwa.state.data.headers | ||||
| 		} ); | ||||
| 		console.log( "retour de login successfull ", auth ); | ||||
| 		//Maj variable globale authentifié | ||||
| 		pwa.state.data.headers.xpaganid = auth.data.payload.data.UUID; | ||||
| 		pwa.state.data.headers.xauth = auth.data.payload.data.TOKEN; | ||||
| 		pwa.state.data.headers.xtribe = auth.data.payload.data.tribeid; | ||||
| 		pwa.state.data.headers.xworkon = auth.data.payload.data.tribeid; | ||||
| 		// Save local authentification uuid/token info user | ||||
| 		pwa.state.data.login.user = auth.data.payload.data; | ||||
| 		//request a refresh after a login | ||||
| 		pwa.state.data.ctx.refreshstorage = true; | ||||
| 		pwa.state.save(); | ||||
| 		//alert( 'pwa.state.save() fait avec uuid' + pwa.state.data.headers.xpaganid ) | ||||
| 		console.groupEnd(); | ||||
| 		return true; | ||||
| 	} catch ( err ) { | ||||
| 		if( err.response ) { console.log( "resp", err.response.data ) } | ||||
| 		if( err.request ) { console.log( "req", err.request.data ) } | ||||
| 		console.log( 'erreur de login reinit de rememberMe', err ) | ||||
| 		pwa.state.data.login.rememberMe = {}; | ||||
| 		document.querySelector( "#signin p.msginfo" ) | ||||
| 			.innerHTML = document.querySelector( "#signin [data-msgko]" ) | ||||
| 			.getAttribute( 'data-msgko' ); | ||||
| 		console.groupEnd(); | ||||
| 		return false; | ||||
| 	} | ||||
| }; | ||||
| pwa.auth.logout = function () { | ||||
| 	console.log( "remove ", pwa.state.data.ctx.website ); | ||||
| 	localStorage.removeItem( pwa.state.data.ctx.website ); | ||||
| 	window.location.href = "/"; | ||||
| } | ||||
| pwa.auth.login = async function () { | ||||
| 	/* | ||||
| 	Check login/psw | ||||
| 	see auth.mustache & data_auth_lg.json for parameters | ||||
| 	Context info used: | ||||
| 	#signin p.msginfo contain message interaction with user | ||||
| 	#signin data-msgok data-msgko | ||||
| 	#signin button[data-routeto] is a redirection if authentification is successful | ||||
| 	*/ | ||||
| 	document.querySelector( '#signin p.msginfo' ) | ||||
| 		.innerHTML = ""; | ||||
| 	const data = { | ||||
| 		LOGIN: document.querySelector( "#signin input[name='login']" ) | ||||
| 			.value, | ||||
| 		PASSWORD: document.querySelector( "#signin input[name='password']" ) | ||||
| 			.value | ||||
| 	} | ||||
| 	console.log( 'check password', Checkjson.test.password( "", data.PASSWORD ) ) | ||||
| 	if( data.LOGIN.length < 4 || !Checkjson.test.password( "", data.PASSWORD ) ) { | ||||
| 		/*$("#loginpart p.msginfo") | ||||
| 		.html("") | ||||
| 		  .fadeOut(2000)*/ | ||||
| 		document.querySelector( '#signin p.msginfo' ) | ||||
| 			.innerHTML = document.querySelector( '#signin [data-msgko]' ) | ||||
| 			.getAttribute( 'data-msgko' ); | ||||
| 	} else { | ||||
| 		if( document.querySelector( "[name='rememberme']" ) | ||||
| 			.checked ) { | ||||
| 			pwa.state.data.login.rememberMe = data; | ||||
| 		} | ||||
| 		if( await pwa.auth.authentification( data ) ) { | ||||
| 			console.log( 'Authentification VALIDE' ) | ||||
| 			document.querySelector( '#signin p.msginfo' ) | ||||
| 				.innerHTML = document.querySelector( "#signin [data-msgok]" ) | ||||
| 				.getAttribute( 'data-msgok' ); | ||||
| 			//state l'état isAuthenticated et check la route | ||||
| 			pwa.state.data.login.isAuthenticated = true; | ||||
| 			pwa.state.save(); | ||||
| 			console.log( pwa.state.data.login ) | ||||
| 			console.log( 'Auth ok route to ', document.querySelector( '#signin button[data-routeto]' ) | ||||
| 				.getAttribute( 'data-routeto' ) ); | ||||
| 			pwa.auth.route( document.querySelector( '#signin button[data-routeto]' ) | ||||
| 				.getAttribute( 'data-routeto' ) ); | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
| pwa.auth.register = async function ( event ) { | ||||
| 	event.preventDefault(); | ||||
| 	// gérer la cration du user | ||||
| } | ||||
| pwa.auth.forgetpsw = async function ( event ) { | ||||
| 	event.preventDefault(); | ||||
| 	const tribeid = $( ".loginregister" ) | ||||
| 		.getAttribute( "data-tribeid" ); | ||||
| 	const email = $( '.forgetpsw .email' ) | ||||
| 		.val(); | ||||
| 	console.log( `Reinit email: ${email} for tribeid: ${tribeid}` ) | ||||
| 	try { | ||||
| 		console.log( `https://${pwa.state.data.ctx.urlbackoffice }/users/getlinkwithoutpsw/${email}` ) | ||||
| 		const reinit = await axios.get( `https://${pwa.state.data.ctx.urlbackoffice }/users/getlinkwithoutpsw/${email}`, { | ||||
| 			headers: pwa.state.data.headers | ||||
| 		} ) | ||||
| 		$( "#forgetpswpart p.msginfo" ) | ||||
| 			.html( "Regardez votre boite email" ); | ||||
| 		return true; | ||||
| 	} catch ( er ) { | ||||
| 		console.log( "Pb d'accès au back check apiamaildigit" ) | ||||
| 		return false; | ||||
| 	} | ||||
| }; | ||||
							
								
								
									
										9
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/axios.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										9
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/axios.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										5046
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/bootstrap.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										5046
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/bootstrap.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										184
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/checkdata.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										184
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/checkdata.js
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| /* | ||||
| This module have to be independant of any external package | ||||
| it is shared between back and front and is usefull | ||||
| to apply common check in front before sending it in back | ||||
| can be include in project with | ||||
|   <script src="https://apiback.maildigit.fr/js/Checkjson.js"></script> | ||||
| or with const Checkjson = require('../public/js/Checkjson.js') | ||||
|  | ||||
| */ | ||||
|  | ||||
| // --## | ||||
|  | ||||
| const Checkjson = {}; | ||||
| // each Checkjson.test. return true or false | ||||
| Checkjson.test = {}; | ||||
|  | ||||
| Checkjson.test.emailadress = ( ctx, email ) => { | ||||
| 	const regExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; | ||||
| 	return regExp.test( email ); | ||||
| }; | ||||
| /* | ||||
|  * @emaillist = "email1,email2, email3" | ||||
|  * it check if each eamil separate by , are correct | ||||
|  */ | ||||
| Checkjson.test.emailadresslist = ( ctx, emaillist ) => { | ||||
| 	//console.log(emaillist.split(',')) | ||||
| 	if( emaillist.length > 0 ) { | ||||
| 		const emails = emaillist.split( ',' ); | ||||
| 		for( var i in emails ) { | ||||
| 			//console.log(emails[i]) | ||||
| 			if( !Checkjson.test.emailadress( "", emails[ i ].trim() ) ) { | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| 	return true; | ||||
| }; | ||||
|  | ||||
| Checkjson.test.password = ( ctx, pwd ) => { | ||||
| 	const regExp = new RegExp( | ||||
| 		/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&.])[A-Za-z\d$@$!%*?&.{}:|\s]{8,}/ | ||||
| 	); | ||||
| 	return regExp.test( pwd ); | ||||
| }; | ||||
| Checkjson.test.required = ( ctx, val ) => | ||||
| 	val != null && val != 'undefined' && val.length > 0; | ||||
|  | ||||
| Checkjson.test.isNumber = ( ctx, n ) => typeof n === 'number'; | ||||
| Checkjson.test.isInt = ( ctx, n ) => n != '' && !isNaN( n ) && Math.round( n ) == n; | ||||
| Checkjson.test.isFloat = ( ctx, n ) => n != '' && !isNaN( n ) && Math.round( n ) != n; | ||||
| Checkjson.test.unique = ( ctx, val ) => { | ||||
| 	if( ctx.list[ ctx.currentfield ] ) { | ||||
| 		return !ctx.list[ ctx.currentfield ].includes( val ); | ||||
| 	} else { | ||||
| 		console.log( 'ERR no list for field:' + ctx.currentfield ); | ||||
| 		return false; | ||||
| 	} | ||||
| }; | ||||
| Checkjson.test.isDateDay = ( ctx, dateDay ) => true; | ||||
| /* Checkjson.test.filterInvalidInArray = (array, validate) => | ||||
|   array ? array.filter(el => !validate(el)) : true; | ||||
| // return true when every elements is valid | ||||
| */ | ||||
|  | ||||
| Checkjson.test.postalCode = ( ctx, postalCode ) => { | ||||
| 	if( postalCode.length == 0 ) return true; | ||||
| 	const regExp = new RegExp( /(^\d{5}$)|(^\d{5}-\d{4}$)/ ); | ||||
| 	return regExp.test( postalCode ); | ||||
| }; | ||||
| /** | ||||
|  * PHONE | ||||
|  */ | ||||
| Checkjson.test.phoneNumber = ( ctx, phoneNumber ) => { | ||||
| 	if( phoneNumber.length == 0 ) return true; | ||||
| 	phoneNumber = phoneNumber.trim() | ||||
| 		.replace( /[- .]/g, '' ) | ||||
| 	//french number | ||||
| 	const regExpfr = new RegExp( /^0[1-9][0-9]{9}$/ ); | ||||
| 	const regExpInternational = new RegExp( /^\+*(\d{3})*[0-9,\-]{8,}/ ); | ||||
| 	return regExpfr.test( phoneNumber ) || regExpInternational.test( phoneNumber ); | ||||
| }; | ||||
| /* | ||||
|  * @phonelist = "phone1,phone2,phone3" | ||||
|  * it check if each phone separate by , are correct | ||||
|  */ | ||||
| Checkjson.test.phoneNumberlist = ( ctx, phonelist ) => { | ||||
| 	//console.log(emaillist.split(',')) | ||||
| 	if( phonelist.length > 0 ) { | ||||
| 		const phones = phonelist.split( ',' ); | ||||
| 		for( var i in phones ) { | ||||
| 			//console.log(emails[i]) | ||||
| 			if( !Checkjson.test.phoneNumber( "", phones[ i ].trim() ) ) { | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| 	return true; | ||||
| }; | ||||
|  | ||||
| // Checkjson.normalize take a correct data then reformat it to harmonise it | ||||
| Checkjson.normalize = {}; | ||||
| Checkjson.normalize.phoneNumber = ( ctx, phone ) => { | ||||
| 	phone = phone.trim() | ||||
| 		.replace( /[- .]/g, '' ); | ||||
| 	if( Checkjson.test.phoneNumber( '', phone ) && phone.length == 10 && phone[ 0 ] == "0" ) { | ||||
| 		phone = '+33 ' + phone.substring( 1 ); | ||||
| 	} | ||||
| 	return phone; | ||||
| } | ||||
| Checkjson.normalize.upperCase = ( ctx, txt ) => txt.toUpperCase(); | ||||
| Checkjson.normalize.lowerCase = ( ctx, txt ) => txt.toLowerCase(); | ||||
| // fixe 10 position et complete par des 0 devant | ||||
| Checkjson.normalize.zfill10 = ( ctx, num ) => { | ||||
| 	let s = num + ''; | ||||
| 	while( s.length < 10 ) s = '0' + s; | ||||
| 	return s; | ||||
| }; | ||||
| /*let tt = "+33 1   02.03 04 05"; | ||||
| console.log(Checkjson.test.phoneNumber('', tt)) | ||||
| console.log(Checkjson.normalize.phoneNumber('', tt)) | ||||
| */ | ||||
| Checkjson.evaluate = ( contexte, referential, data ) => { | ||||
| 	/* | ||||
| 	* contexte object {} with full info for evaluation | ||||
| 	* file referential path to get object to apply | ||||
| 	* data related to object | ||||
| 	- return {validefor =[keyword of error] if empty no error, | ||||
| 	          clean data eventually reformated | ||||
| 	           updateDatabase} | ||||
| 	 */ | ||||
| 	console.log( 'contexte', contexte ); | ||||
| 	console.log( 'referentiel', referential ); | ||||
| 	console.log( 'data', data ); | ||||
| 	const invalidefor = []; | ||||
| 	const objectdef = {}; | ||||
| 	const listfield = referential.map( ch => { | ||||
| 		objectdef[ ch.idfield ] = ch; | ||||
| 		return ch.idfield; | ||||
| 	} ); | ||||
|  | ||||
| 	Object.keys( data ) | ||||
| 		.forEach( field => { | ||||
| 			if( !listfield.includes( field ) ) { | ||||
| 				// some data can be inside an object with no control at all | ||||
| 				// they are used for process only | ||||
| 				// i leave it in case it will become a non sens | ||||
| 				// invalidefor.push('ERRFIELD unknown of referentials ' + field); | ||||
| 			} else { | ||||
| 				if( objectdef[ field ].check ) { | ||||
| 					// check data with rule list in check | ||||
| 					objectdef[ field ].Checkjson.forEach( ctrl => { | ||||
| 						console.log( 'ctrl', ctrl ); | ||||
| 						contexte.currentfield = field; | ||||
| 						if( !Checkjson.test[ ctrl ] ) { | ||||
| 							invalidefor.push( 'ERR check function does not exist :' + ctrl + '___' + field ) | ||||
| 						} else { | ||||
| 							if( !Checkjson.test[ ctrl ]( contexte, data[ field ] ) ) | ||||
| 								invalidefor.push( 'ERR' + ctrl + '___' + field ); | ||||
| 						} | ||||
| 					} ); | ||||
| 				} | ||||
|  | ||||
| 				if( objectdef[ field ].nouserupdate ) { | ||||
| 					// check if user can modify this information | ||||
| 					console.log( | ||||
| 						'evaluation :' + field + ' -- ' + objectdef[ field ].nouserupdate, | ||||
| 						eval( objectdef[ field ].nouserupdate ) | ||||
| 					); | ||||
| 					const evalright = eval( objectdef[ field ].nouserupdate ); | ||||
| 					objectdef[ field ].nouserupdate = evalright; | ||||
| 				} | ||||
| 			} | ||||
| 		} ); | ||||
| 	console.log( { | ||||
| 		invalidefor, | ||||
| 		data | ||||
| 	} ); | ||||
| 	return { | ||||
| 		invalidefor, | ||||
| 		data | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| if( typeof module !== 'undefined' ) module.exports = Checkjson; | ||||
							
								
								
									
										13
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/feather.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/feather.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										150
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/main.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										150
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/main.js
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| /* | ||||
| After state.js / auth.js and all external js lib | ||||
| Load | ||||
|  | ||||
| */ | ||||
| var pwa = pwa || {}; | ||||
| pwa.main = pwa.main || {}; | ||||
| pwa.main.tpldata = pwa.main.tpldata || {}; | ||||
| pwa.main.tpl = pwa.main.tpl || {}; | ||||
| pwa.main.tpldata = pwa.main.tpldata || {}; | ||||
| pwa.main.ref = pwa.main.ref || {}; | ||||
|  | ||||
| pwa.main.tpl.appsidebarmenu = 'static/components/appmesa/appsidebarmenu.mustache'; | ||||
| pwa.main.tpl.apptopbarmenu = 'static/components/appmesa/apptopbarmenu.mustache'; | ||||
| pwa.main.tpldata.sidebar = `static/components/appmesa/data_sidebar`; | ||||
| pwa.main.tpldata.topbar = `static/components/appmesa/data_topbar`; | ||||
| pwa.main.tpldata.topbarLogin = `static/components/appmesa/data_topbarLogin`; | ||||
|  | ||||
| pwa.main.init = () => { | ||||
| 	const isempty = ( obj ) => { | ||||
| 		return obj && Object.keys( obj ) | ||||
| 			.length === 0 && obj.constructor === Object | ||||
| 	} | ||||
|  | ||||
| 	// Load public env tpl & tpldata | ||||
| 	//Manage action depending of html file currently show | ||||
| 	const currenthtml = location.pathname.split( '/' ) | ||||
| 		.at( -1 ); | ||||
| 	console.groupCollapsed( `pwa.main.init for ${currenthtml} html page` ); | ||||
| 	if( currenthtml.includes( 'app_' ) ) { | ||||
| 		pwa.main.loadmenu() | ||||
| 	} | ||||
| 	// To manage if authenticated or not in a simple way | ||||
| 	/* | ||||
| 		if( pwa.state.data.login.isAuthenticated ) { | ||||
| 			//authenticated | ||||
| 			// identity inside pwa.state.login.user | ||||
| 		}else{ | ||||
| 			//anonymous | ||||
| 			// can check if the url is relevant with isAuthenticated | ||||
| 			//route to app if exist data-routo into a signin | ||||
| 			//pwa.auth.route( document.querySelector( '#signin button[data-routeto]' ).getAttribute( 'data-routeto' ) ); | ||||
| 			// add and load dynamicaly the gui.js plugin if user that request it has access | ||||
| 		} | ||||
| 	*/ | ||||
| 	console.groupEnd(); | ||||
| }; | ||||
|  | ||||
| pwa.main.loadmenu = async () => { | ||||
| 	console.log( 'pwa.main.loadmenu running' ); | ||||
| 	console.log( 'Status of pwa.state.data.login.isAuthenticated =', pwa.state.data.login.isAuthenticated ); | ||||
| 	let datasidebar, datatopbar; | ||||
| 	/* Build datasidebar and datatopbar depending of list of module allowed by user in his ACCESSRIGHTS profil. | ||||
| 	 app[`${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}`].js; | ||||
|  | ||||
|   */ | ||||
| 	//console.log( 'List of tpldata', pwa.main.tpldata ) | ||||
| 	//console.log( 'List of tpl', pwa.main.tpl ) | ||||
| 	console.log( `run pwa.state.loadfile with pwa.state.data.ctx.refreshstorage = ${pwa.state.data.ctx.refreshstorage} if true=> refresh anyway, if false refresh only if dest.name does not exist` ); | ||||
| 	await pwa.state.loadfile( pwa.main.tpl, 'tpl' ); | ||||
| 	await pwa.state.loadfile( pwa.main.tpldata, 'tpldata' ); | ||||
| 	datasidebar = pwa.state.data.tpldata.sidebar; | ||||
| 	//any tpldata containing sidebar in pwa.state.data.tpldata is add to sbgroupmenu to be available | ||||
| 	Object.keys( pwa.state.data.tpldata ) | ||||
| 		.filter( m => ( m != 'sidebar' && m.includes( 'sidebar' ) ) ) | ||||
| 		.some( k => { | ||||
| 			datasidebar.sbgroupmenu.push( pwa.state.data.tpldata[ k ] ) | ||||
| 		} ); | ||||
| 	//merge les menu topbar | ||||
| 	datatopbar = pwa.state.data.tpldata.topbar; | ||||
| 	if( pwa.state.data.login.isAuthenticated ) { | ||||
| 		// update user information if needed | ||||
| 		datatopbar.name = pwa.state.data.login.user.LOGIN; | ||||
| 		datatopbar.avatarimg = pwa.state.data.login.user.AVATARIMG; | ||||
| 		delete pwa.state.data.tpldata.topbarLogin; | ||||
| 		pwa.state.save(); | ||||
| 	} | ||||
| 	datatopbar.menuprofil = []; | ||||
| 	Object.keys( pwa.state.data.tpldata ) | ||||
| 		.filter( m => ( m != 'topbar' && m.includes( 'topbar' ) ) ) | ||||
| 		.some( k => { | ||||
| 			datatopbar.menuprofil.push( pwa.state.data.tpldata[ k ] ) | ||||
| 		} ); | ||||
| 	if( pwa.state.data.tpl.appsidebarmenu ) { | ||||
| 		document.querySelector( "#sidebar" ) | ||||
| 			.innerHTML = Mustache.render( pwa.state.data.tpl.appsidebarmenu, datasidebar ) | ||||
| 		document.querySelector( "#navbar" ) | ||||
| 			.innerHTML = Mustache.render( pwa.state.data.tpl.apptopbarmenu, datatopbar ) | ||||
| 		//active les icones svg de feather | ||||
| 		feather.replace(); | ||||
| 		//active scroll presentation + sidebar animation | ||||
| 		pwa.main.simplebar(); | ||||
| 		pwa.main.clickactive(); | ||||
| 	}; | ||||
| }; | ||||
|  | ||||
| ////////////////////////////////////////////////////// | ||||
| // simplebar | ||||
| ////////////////////////////////////////////////////// | ||||
| pwa.main.simplebar = () => { | ||||
| 	const simpleBarElement = document.getElementsByClassName( "js-simplebar" )[ 0 ]; | ||||
|  | ||||
| 	if( simpleBarElement ) { | ||||
| 		/* Initialize simplebar */ | ||||
| 		new SimpleBar( document.getElementsByClassName( "js-simplebar" )[ 0 ] ) | ||||
|  | ||||
| 		const sidebarElement = document.getElementsByClassName( "sidebar" )[ 0 ]; | ||||
| 		const sidebarToggleElement = document.getElementsByClassName( "sidebar-toggle" )[ 0 ]; | ||||
|  | ||||
| 		sidebarToggleElement.addEventListener( "click", () => { | ||||
| 			sidebarElement.classList.toggle( "collapsed" ); | ||||
|  | ||||
| 			sidebarElement.addEventListener( "transitionend", () => { | ||||
| 				window.dispatchEvent( new Event( "resize" ) ); | ||||
| 			} ); | ||||
| 		} ); | ||||
| 	} | ||||
| } | ||||
| ///////////////////////////////////////////////////////// | ||||
| // manage click effect | ||||
| //////////////////////////////////////////////////////// | ||||
| pwa.main.clickactive = () => { | ||||
| 	const cleanactive = () => { | ||||
| 		const el = document.querySelectorAll( '.sidebar-item' ) | ||||
| 		for( var i = 0; i < el.length; i++ ) { | ||||
| 			//console.log( 'clean', el[ i ].classList ) | ||||
| 			el[ i ].classList.remove( 'active' ); | ||||
| 		} | ||||
| 	} | ||||
| 	document.addEventListener( "click", ( e ) => { | ||||
| 		console.log( 'click', e ); | ||||
| 		if( e.target.classList.contains( 'sidebar-link' ) ) { | ||||
| 			cleanactive(); | ||||
| 			e.target.closest( '.sidebar-item' ) | ||||
| 				.classList.add( 'active' ); | ||||
| 			// remonte au menu au dessus si existe | ||||
| 			e.target.closest( '.sidebar-item' ) | ||||
| 				.closest( '.sidebar-item' ) | ||||
| 				.classList.add( 'active' ); | ||||
| 		} | ||||
| 	} ); | ||||
| 	// If enter run the research | ||||
| 	document.getElementById( 'globalsearch' ) | ||||
| 		.addEventListener( 'keypress', ( e ) => { | ||||
| 			if( e.keyCode == 13 ) { | ||||
| 				pwa.search.req( 'globalsearch' ); | ||||
| 				e.preventDefault(); | ||||
| 			} | ||||
| 		} ) | ||||
| }; | ||||
							
								
								
									
										1
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/mustache.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/mustache.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										28
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/notification.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										28
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/notification.js
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| "use strict"; | ||||
| var pwa = pwa || {}; | ||||
| /* | ||||
| Manage notification | ||||
|  | ||||
| Get notification after tomenu was load | ||||
|  | ||||
| from /components/notification | ||||
| ____________________ | ||||
|  | ||||
| */ | ||||
| //--## | ||||
| pwa.notification = {}; | ||||
|  | ||||
| pwa.notification.update = () => { | ||||
| 	console.log( 'get notification update for a user' ); | ||||
| 	axios.get( `https://${pwa.state.data.ctx.urlbackoffice}/notifications/user`, { headers: pwa.state.data.headers } ) | ||||
| 		.then( rep => { | ||||
| 			console.log( "list des notifs", rep.data.payload.data ) | ||||
| 			rep.data.payload.data.number = rep.data.payload.data.notifs.length; | ||||
| 			document.getElementById( "topbarmenuright" ) | ||||
| 				.innerHTML = Mustache.render( pwa.state.data.tpl.notiflist, rep.data.payload.data ) + document.getElementById( "topbarmenuright" ) | ||||
| 				.innerHTML; | ||||
| 		} ) | ||||
| 		.catch( err => { | ||||
| 			console.log( `Err pwa.notification.update data for user into header ${pwa.state.data.headers}`, err ); | ||||
| 		} ); | ||||
| }; | ||||
							
								
								
									
										10
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/simplebar.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/simplebar.min.js
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										261
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/state.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										261
									
								
								asupsetup/data/domain/apixpress/www/app/webapp/js/state.js
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,261 @@ | ||||
| "use strict"; | ||||
| var pwa = pwa || {}; | ||||
| /* | ||||
| FROM ndda/plugins/maildigitcreator/appjs/state.js | ||||
| Manage state of the webapp | ||||
| author: Phil Colzy - yzlocp@gmail.com | ||||
| ____________________________ | ||||
| pwa.state.save(): save in localstorage pwa.state.data avec le Nom du projet | ||||
| ____________________________ | ||||
| pwa.state.update(): update localstorage data from referential version | ||||
| ____________________________ | ||||
| pwa.state.ready(callback): await DOM loaded before running the callback | ||||
| ____________________________ | ||||
| pwa.state.refresh(): check if newversion of webapp to refresh page for dev purpose (do not use to refresh data) | ||||
| ____________________________ | ||||
| pwa.state.route(); check url and reroute it to function(urlparameter) or hide show part into a onepage website. | ||||
| ____________________________ | ||||
| pwa.state.loadfile({key:url},'dest') store in pwa.state.data.dest.key= file from url await all key to store result | ||||
| ___________________________ | ||||
| pwa.state.confdev() if ENV is dev then change urlbase for axios to looking for relevant file and refresh at a frequency pwa.state.refresh() | ||||
|  | ||||
| */ | ||||
| //--## | ||||
| pwa.state = {}; | ||||
|  | ||||
| pwa.state.refresh = () => { | ||||
| 	//console.warn(`Lance le refresh de${pwa.state.env.page}`) | ||||
| 	//console.warn( 'ggg', pwa.state.data.ctx.urlbase ) | ||||
| 	const currenthtml = location.pathname.split( '/' ) | ||||
| 		.at( -1 ) | ||||
| 		.replace( '.html', '.json' ); | ||||
| 	//console.log( currenthtml ) | ||||
| 	axios.get( ` ${pwa.state.data.ctx.urlbase}/static/lastchange/${currenthtml}` ) | ||||
| 		.then( | ||||
| 			data => { | ||||
| 				//console.log( data.data.time, pwa.state.data.ctx.version ) | ||||
| 				if( data.data.time > pwa.state.data.ctx.version ) { | ||||
| 					//console.log( "reload la page pour cause de lastchange detecté" ); | ||||
| 					pwa.state.data.ctx.version = data.data.time; | ||||
| 					pwa.state.data.ctx.refreshstorage = true; | ||||
| 					pwa.state.save(); | ||||
| 					location.reload(); | ||||
| 				} else { | ||||
| 					//console.log( 'nothing change' ) | ||||
| 				} | ||||
| 			}, | ||||
| 			error => { | ||||
| 				console.log( error ); | ||||
| 			} | ||||
| 		); | ||||
| }; | ||||
| pwa.state.ready = callback => { | ||||
| 	// Equivalent of jquery Document.ready() | ||||
| 	// in case the document is already rendered | ||||
| 	if( document.readyState != "loading" ) callback(); | ||||
| 	// modern browsers | ||||
| 	else if( document.addEventListener ) | ||||
| 		document.addEventListener( "DOMContentLoaded", callback ); | ||||
| 	// IE <= 8 | ||||
| 	else | ||||
| 		document.attachEvent( "onreadystatechange", function () { | ||||
| 			if( document.readyState == "complete" ) callback(); | ||||
| 		} ); | ||||
| }; | ||||
| pwa.state.route = async () => { | ||||
| 	/* Allow to create dynamic content | ||||
|  ?action=pwa object&id=&hh& => pwa.action("?action=pwa object&id=&hh&") | ||||
|  ex: ?action=test.toto&id=1&t=123 | ||||
|  Each function that can be called have to start with | ||||
|  if (e[1]=="?"){ | ||||
|   const urlpar = new URLSearchParams( loc.search ); | ||||
| 	Then set param with urlpar.get('variable name') | ||||
|   } | ||||
| 	 OR ?pagemd=name used into .html (div) | ||||
|    Then it hide all <div class="pagemd" and show the one with <div id="page"+name | ||||
|  */ | ||||
| 	console.groupCollapsed( `pwa.state.route with window.location` ); | ||||
| 	console.log( 'List of pwa available ', Object.keys( pwa ) ); | ||||
| 	if( !pwa.auth ) { | ||||
| 		console.log( 'Warning, no auth.js, not a pb if no authentification need, if not check js order to be sur auth.js load before state.js' ) | ||||
| 	} else { | ||||
| 		// check if still authenticated | ||||
| 		if( pwa.state.data.login.isAuthenticated ) { | ||||
| 			pwa.state.data.login.isAuthenticated = await pwa.auth.isAuthenticate(); | ||||
| 		} | ||||
| 		//check if need authentification to show this page | ||||
| 		if( pwa.state.data.ctx.pageneedauthentification && !pwa.state.data.login.isAuthenticated ) { | ||||
| 			console.log( 'reload page cause not auth and page require an auth' ) | ||||
| 			window.location = `${pwa.state.data.ctx.pageredirectforauthentification}_${pwa.state.data.ctx.lang}.html`; | ||||
| 		} | ||||
| 	} | ||||
| 	const loc = window.location; | ||||
| 	if( loc.search ) { | ||||
| 		console.log( Object.keys( pwa ) ) | ||||
| 		const urlpar = new URLSearchParams( loc.search ); | ||||
| 		if( urlpar.get( 'action' ) ) { | ||||
| 			const act = 'pwa.' + urlpar.get( 'action' ) + '("' + loc.search + '")'; | ||||
| 			try { | ||||
| 				eval( act ); | ||||
| 				console.log( 'Specific action request to pwa.' + act ) | ||||
| 			} catch ( err ) { | ||||
| 				console.log( err ) | ||||
| 				console.error( `You request ${act}, this action does not exist ` ); | ||||
| 				alert( `Sorry but you have no access to ${act}, ask your admin` ); | ||||
| 			} | ||||
| 		} | ||||
| 		let pgid = "pageindex" | ||||
| 		if( urlpar.get( 'pagemd' ) ) { | ||||
| 			pgid = "page" + urlpar.get( 'pagemd' ) | ||||
| 		} | ||||
| 		//route to page content | ||||
| 		Array.from( document.getElementsByClassName( "pagemd" ) ) | ||||
| 			.forEach( e => { | ||||
| 				console.log( "detect pagemd", e.getAttribute( 'data-url' ) ); | ||||
| 				e.classList.add( "d-none" ); | ||||
| 			} ); | ||||
| 		if( document.getElementById( pgid ) ) { | ||||
| 			document.getElementById( pgid ) | ||||
| 				.classList.remove( 'd-none' ); | ||||
| 		} | ||||
| 	} | ||||
| 	console.groupEnd(); | ||||
| 	// If pwa.main exist then start pwa.main.init(); | ||||
| 	if( pwa.main ) pwa.main.init(); | ||||
| } | ||||
| pwa.state.loadfile = async ( list, dest ) => { | ||||
| 	// load external file if flag pwa.state.data.ctx.refreshstorage is true from pwa.state.refresh(); | ||||
| 	//from list = {name:url} request are done with ctx.urlbase/url and store in localstorage pwa.state.data[dest][name]=data | ||||
| 	// if dest=='js' then it eval the js and store origin in pwa.state.data.js={name:url} | ||||
| 	//For at true refreshstorage if destination pwa.state.dest does not exist | ||||
|  | ||||
| 	//console.log( 'list', list ) | ||||
| 	//console.log( 'pwa.state.data.ctx.refreshstorage', pwa.state.data.ctx.refreshstorage ) | ||||
| 	if( pwa.state.data.ctx.refreshstorage || !pwa.state.data[ dest ] || Object.keys( pwa.state.data[ dest ] ) | ||||
| 		.length == 0 ) { | ||||
| 		if( !pwa.state.data[ dest ] ) pwa.state.data[ dest ] = {}; | ||||
| 		try { | ||||
| 			let reqname = []; | ||||
| 			let reqload = []; | ||||
| 			for( const [ k, v ] of Object.entries( list ) ) { | ||||
| 				if( !pwa.state.data[ dest ][ k ] || pwa.state.data.ctx.refreshstorage ) { | ||||
| 					// if still not exist or refresstorage is set to true then add to load | ||||
| 					//@TODO check it works well on production | ||||
| 					reqname.push( k ); | ||||
| 					reqload.push( v ); | ||||
| 				} | ||||
| 			}; | ||||
| 			//console.log( pwa.state.data.ctx.urlbase, reqload ) | ||||
| 			let resload = await Promise.all( reqload.map( r => { | ||||
| 				if( dest == 'tpldata' ) r = `${r}_${pwa.state.data.ctx.lang}.json`; | ||||
| 				return axios.get( `${pwa.state.data.ctx.urlbase}/${r}`, { headers: pwa.state.data.headers } ) | ||||
| 			} ) ); | ||||
| 			resload.forEach( ( d, i ) => { | ||||
| 				pwa.state.data[ dest ][ reqname[ i ] ] = d.data; | ||||
| 				pwa.state.save(); | ||||
| 			} ) | ||||
| 		} catch ( err ) { | ||||
| 			console.error( 'FATAL ERROR check that list exist remove if not', list, err.message ) | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| pwa.state.save = function () { | ||||
| 	localStorage.setItem( pwa.state.data.ctx.website, JSON.stringify( pwa.state.data ) ); | ||||
| }; | ||||
| pwa.state.update = async function () { | ||||
| 	const domhtml = document.querySelector( "html" ); | ||||
| 	const ctx = { | ||||
| 		tribeid: domhtml.getAttribute( 'data-tribeid' ), | ||||
| 		website: domhtml.getAttribute( "data-website" ), | ||||
| 		nametpl: domhtml.getAttribute( "data-nametpl" ), | ||||
| 		pagename: domhtml.getAttribute( "data-pagename" ), | ||||
| 		urlbackoffice: domhtml.getAttribute( "data-urlbackoffice" ), | ||||
| 		pageneedauthentification: true, | ||||
| 		pageredirectforauthentification: "", | ||||
| 		lang: domhtml.getAttribute( "lang" ), | ||||
| 		env: domhtml.getAttribute( "data-env" ), | ||||
| 		version: domhtml.getAttribute( "data-version" ), | ||||
| 		refreshstorage: false | ||||
| 	} | ||||
| 	if( !domhtml.getAttribute( 'data-pageneedauthentification' ) || domhtml.getAttribute( 'data-pageneedauthentification' ) == 'false' ) { | ||||
| 		ctx.pageneedauthentification = false; | ||||
| 	} | ||||
| 	if( domhtml.getAttribute( 'data-pageforauthentification' ) ) { | ||||
| 		ctx.pageforauthentification = domhtml.getAttribute( 'data-pageforauthentification' ); | ||||
| 	} | ||||
| 	console.groupCollapsed( `update pwa.state with html attribut or from localstorage into ${ctx.website}` ); | ||||
| 	console.log( 'html context:', ctx ); | ||||
| 	if( localStorage.getItem( ctx.website ) ) { | ||||
| 		pwa.state.data = JSON.parse( localStorage.getItem( ctx.website ) ); | ||||
| 		//alert( 'recupere pwa.state.data xpaganid:' + pwa.state.data.headers.xpaganid ) | ||||
| 	} | ||||
| 	if( !( pwa.state.data && pwa.state.data.ctx.tribeid == ctx.tribeid && pwa.state.data.ctx.website == ctx.website ) ) { | ||||
| 		console.log( " reinitialise localstorage cause work on a different project or first access" ); | ||||
| 		delete pwa.state.data; | ||||
| 		localStorage.removeItem( ctx.website ) | ||||
| 	} | ||||
| 	/* | ||||
| 	if( pwa.state.data && statejson.data.app.version && ( parseInt( pwa.state.data.app.version ) < parseInt( statejson.data.app.version ) ) ) { | ||||
| 		// le numero de version en mémoire est < au numero disponible sur le serveur | ||||
| 		// force un logout pour reinitialiser les menus | ||||
| 		delete pwa.state.data; | ||||
| 		localStorage.removeItem( pwa.PROJET ) | ||||
| 	} | ||||
| 	*/ | ||||
| 	if( !pwa.state.data ) { | ||||
| 		// No localstorage available et one by default | ||||
| 		pwa.state.data = { | ||||
| 			ctx, | ||||
| 			login: { | ||||
| 				isAuthenticated: false, | ||||
| 				user: {}, | ||||
| 				rememberMe: {} | ||||
| 			}, | ||||
| 			headers: { | ||||
| 				'xauth': '1', | ||||
| 				'xpaganid': '1', | ||||
| 				'xtribe': ctx.tribeid, | ||||
| 				'xlang': ctx.lang, | ||||
| 				'xworkon': ctx.tribeid, | ||||
| 				'xapp': `${ctx.tribeid}:${ctx.website}` | ||||
| 			} | ||||
| 		} | ||||
| 		console.log( 'load new state.data', pwa.state.data ) | ||||
| 	} | ||||
| 	// Check if external component need to be load | ||||
| 	const app = `${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}`; | ||||
| 	if( pwa.state.data.login.isAuthenticated && | ||||
| 		pwa.state.data.login.user.ACCESSRIGHTS.app[ app ] && | ||||
| 		pwa.state.data.login.user.ACCESSRIGHTS.app[ app ].js | ||||
| 	) { | ||||
| 		console.log( 'tttt', pwa.state.data.login.isAuthenticated, pwa.state.data.login.user.ACCESSRIGHTS.app[ app ].js ) | ||||
| 		pwa.state.data.login.user.ACCESSRIGHTS.app[ app ].js.some( ( u ) => { | ||||
| 			console.log( `load from user ACCESSRIGHTS app[${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}].js  : ${u}` ) | ||||
| 			const script = document.createElement( 'script' ); | ||||
| 			script.src = u; | ||||
| 			script.async = false; | ||||
| 			document.body.appendChild( script ); | ||||
| 		} ); | ||||
| 	} | ||||
| 	//Check dev to set parameter to simplify dev app | ||||
| 	//check in confdev version and set pwa.state.data.ctx.refreshstorage at true if new version | ||||
| 	pwa.state.confdev(); | ||||
| 	console.groupEnd(); | ||||
| 	pwa.state.route(); | ||||
| 	pwa.state.save(); | ||||
| }; | ||||
| pwa.state.confdev = () => { | ||||
| 	if( pwa.state.data.ctx.env == 'dev' ) { | ||||
| 		pwa.state.data.ctx.urlbase = `/space/${pwa.state.data.ctx.tribeid}/${pwa.state.data.ctx.website}/dist`; | ||||
| 		// check each 3 sec if new version to reload | ||||
| 		setInterval( "pwa.state.refresh()", 3000 ); | ||||
| 	} else { | ||||
| 		//pwa.state.axios = axios.create(); | ||||
| 		pwa.state.data.ctx.urlbase = "/"; | ||||
| 		// check and refresh if new version only one time | ||||
| 		pwa.state.refresh(); | ||||
| 	} | ||||
| } | ||||
| // Refresh browser state if exist else get pwa.state defaults | ||||
| pwa.state.ready( pwa.state.update ); | ||||
		Reference in New Issue
	
	Block a user