From db3d10539a21549aa39b6bbcad475691c2a2fa53 Mon Sep 17 00:00:00 2001 From: STEINNI Date: Tue, 7 Oct 2025 19:57:58 +0000 Subject: [PATCH] user preferences via API --- app/assets/json/agents/basic3D.json | 15 ++++ app/config/config.json | 3 +- app/controllers/EICAppController.js | 3 - app/libs/myUser.js | 76 +++++-------------- app/models/myUserModel.js | 28 +++++++ .../Threetobus/threetobus.module.js | 17 ++++- core/Sparc-core-1.0.js | 2 +- 7 files changed, 79 insertions(+), 65 deletions(-) create mode 100644 app/models/myUserModel.js diff --git a/app/assets/json/agents/basic3D.json b/app/assets/json/agents/basic3D.json index f1bc933..8c2db51 100644 --- a/app/assets/json/agents/basic3D.json +++ b/app/assets/json/agents/basic3D.json @@ -2,6 +2,7 @@ "molecule1": { "type": "Mesh", "geometry": { "type": "BoxGeometry", "args": [1, 1, 1] }, + "position": [0, 0.5, 0], "material": { "type": "MeshStandardMaterial", "color": "orange" }, "children": [ { @@ -10,6 +11,20 @@ "geometry": { "type": "SphereGeometry", "args": [0.3, 16, 16] }, "material": { "type": "MeshStandardMaterial", "color": "blue" }, "position": [0, 0.5, 0] + }, + { + "type": "Mesh", + "childSuffix": "head", + "geometry": { "type": "CylinderGeometry", "args": [1, 1, 0.5] }, + "material": { "type": "MeshBasicMaterial", + "color": "0x9090F0", + "transparent": true, + "opacity": 0.3, + "blending": "AdditiveBlending", + "side": "BackSide" + }, + "scale": [1.5, 2, 1], + "position": [0, 0, 0] } ] }, diff --git a/app/config/config.json b/app/config/config.json index 5313ce5..da92fc7 100644 --- a/app/config/config.json +++ b/app/config/config.json @@ -12,7 +12,7 @@ "path": "/EIC", "classes": [ "EICController", "EICDomContent", "EICDialogContent", "EICMetaData", "EICModel", "EICPluralModel", "EICBusModel" ], "dependencies" : { "EICPluralModel": [ "EICModel" ] } - } + } ], "masterController": "EICAppController", "defaultMasterTemplate": "templates/EICAppTemplate" @@ -25,6 +25,7 @@ }, "userLib": { "className": "myUser", + "modelPath": "/app/models/myUserModel", "checkauthEndpoint": "/api/checkauth", "loginEndpoint": "/api/login", "logoutEndpoint": "/api/logout", diff --git a/app/controllers/EICAppController.js b/app/controllers/EICAppController.js index 7870da2..6de1690 100755 --- a/app/controllers/EICAppController.js +++ b/app/controllers/EICAppController.js @@ -28,9 +28,6 @@ class EICAppController extends MasterController { app.User.logout() } ) - - app.User.loadPreferences(); - //if('ChatModule' in app.LoadedClasses) this.chat = new ChatModule(this.content); } } diff --git a/app/libs/myUser.js b/app/libs/myUser.js index b7f5fcd..087a261 100755 --- a/app/libs/myUser.js +++ b/app/libs/myUser.js @@ -35,55 +35,6 @@ class myUser extends app.LoadedClasses.User { */ getRoles() { return(app.User.roles); } - /** - * @async - * @returns {string} - * - */ - fetchServices() { - let host = new URL(app.config.userLib.apiDiscoveryEndpoint).host - let stage = (host.split('.')[1] != 'eismea') ? '.'+host.split('.')[1] : '' - - return(fetch('/app/assets/json/global/services.json?'+crypto.randomUUID(), { - method: 'GET' - }) - .then(response=>response.text()) - .then(response=>JSON.parse(response.replace(/__host__/g, host).replace(/__stage__/g, stage))) - ) - } - - /** - * Candidate for deprecation - * @returns {Promise} - */ - getApiServices() { - return( - this.fetchServices() - .then(response => { - if(response.success) { - // Was to much to ask to respect existing code & existing contract, so do the cleanup here - let api = {}; - for(let entry of response.payload){ - api[entry.resource] = entry.actions.reduce( (acc, v)=>{ - acc[v.action]=v.availableMethod; - return(acc); }, {} - ); - } - - // Now override with exceptions from config. (also creates from exceptions) - for(let resource in app.config.userLib.apiStageExceptions){ - if(!api.hasOwnProperty(resource)) api[resource] = []; - for(let action in app.config.userLib.apiStageExceptions[resource]) { - api[resource][action] = app.config.userLib.apiStageExceptions[resource][action]; - console.warn(`Replacing / adding existing API with exception for resource: ${resource} action: ${action}`) - } - } - app.config.api = api; - } - } - ) - ) - } /** * @@ -123,6 +74,7 @@ class myUser extends app.LoadedClasses.User { this.isAuthenticated = true this.identity = jsonresp.payload.userInfos.identity this.roles = jsonresp.payload.userInfos.roles + this.loadUserModel() callBack() } @@ -136,12 +88,24 @@ class myUser extends app.LoadedClasses.User { if(await this.login()) { document.querySelector('div.loginerr').classList.remove('show') console.log('Successful login !!!') + this.loadUserModel() callBack() } else { gobtn.disabled = false } } + loadUserModel(){ + app.events.addEvent('core.mvcReady', async () => { + await Loader.loadScripts({ + 'scripts':[app.config.userLib.modelPath], + 'dependencies':[], + }) + this.model = new MyUserModleModel() + this.loadPreferences() + }, 'myUser') + } + /** * * @returns {string} @@ -226,23 +190,19 @@ class myUser extends app.LoadedClasses.User { } loadPreferences() { - if(app.MessageBus) { - app.MessageBus.requestWssGwAction('GET', { key: `${this.identity.uuid}:userPrefs`}) - .then(settings => { + console.log('Loading prefs...') + this.model.getPreferences().then(settings => { console.log("Prefs received from bus:", settings) this.preferences = settings.value || {} - }) - } - + }) } savePreferences() { - if(app.MessageBus) { - app.MessageBus.requestWssGwAction('SET', { + console.log('Saving prefs...') + this.model.setPreferences({ key: `${this.identity.uuid}:userPrefs`, value: this.preferences }) - } } getPreference(path) { diff --git a/app/models/myUserModel.js b/app/models/myUserModel.js new file mode 100644 index 0000000..29234ef --- /dev/null +++ b/app/models/myUserModel.js @@ -0,0 +1,28 @@ +class MyUserModleModel extends Model { + + constructor(privileges) { + super('', privileges) + } + + async getPreferences(){ + // let endpoint = this.getApiEndpoint('read') + // endpoint.uri = endpoint.uri.replace('{mid}', mid) + return ( + this.request('/api/preferences', 'get') + .then( async serverData => serverData.payload) + ) + } + + + async setPreferences(prefs){ + // let endpoint = this.getApiEndpoint('read') + // endpoint.uri = endpoint.uri.replace('{mid}', mid) + return ( + this.request('/api/preferences', 'put', prefs) + .then( async serverData => serverData.payload) + ) + } +} + + +app.registerClass('MyUserModleModel', MyUserModleModel) \ No newline at end of file diff --git a/app/thirdparty/Threetobus/threetobus.module.js b/app/thirdparty/Threetobus/threetobus.module.js index a5f2196..f13b0e7 100644 --- a/app/thirdparty/Threetobus/threetobus.module.js +++ b/app/thirdparty/Threetobus/threetobus.module.js @@ -213,12 +213,25 @@ export class Threetobus{ return(renderEngine) } - agentFromJSON(id, desc){ let obj if(desc.type === 'Mesh') { const geom = new THREE[desc.geometry.type](...(desc.geometry.args || [])) - const mat = new THREE[desc.material.type]( desc.material.color ? { color: desc.material.color } : {} ) + + const matType = desc.material.type + const matProps = { ...desc.material } + for (const key in matProps) { + if (key === 'type') continue + if (typeof matProps[key] === 'string' && THREE[matProps[key]] !== undefined) { + matProps[key] = THREE[matProps[key]] + } + } + // convert color strings like "0xffffaa" to numbers + if (typeof matProps.color === 'string' && matProps.color.startsWith('0x')) { + matProps.color = parseInt(matProps.color) + } + const mat = new THREE[matType](matProps) + obj = new THREE.Mesh(geom, mat) } else if(desc.type === 'Group') { obj = new THREE.Group() diff --git a/core/Sparc-core-1.0.js b/core/Sparc-core-1.0.js index 92c4344..3e3189a 100755 --- a/core/Sparc-core-1.0.js +++ b/core/Sparc-core-1.0.js @@ -193,7 +193,7 @@ class Sparc { onMVCReady() { // Now that we are authenticated, we have the config and the MVC // load the top routes and then route ! - + app.events.trigger('core.mvcReady') this.Assets.loadJson({ 'name': 'baseRoutes.json', 'path': '/app/config/' }) .then( (topRoutes) =>{