fixed css
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* Default app color palette */
|
||||
:root,:after,:before {
|
||||
--app-color-primary: var(--eicui-base-color-primary-100);
|
||||
--app-color-primary: #473;
|
||||
--app-color-secondary: var(--eicui-base-color-grey-100);
|
||||
--app-color-success: var(--eicui-base-color-success-100);
|
||||
--app-color-danger: var(--eicui-base-color-danger-100);
|
||||
@@ -24,18 +24,20 @@
|
||||
--app-header-height: var(--eicui-app-top-message-height);
|
||||
|
||||
--app-menu-collapsed-width: 50px;
|
||||
--app-menu-expanded-width: 240px;
|
||||
--app-menu-expanded-width: 160px;
|
||||
|
||||
--app-menu-width: var(--app-menu-expanded-width);
|
||||
|
||||
}
|
||||
|
||||
body[eicapp] {
|
||||
all: unset;
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
grid-template-columns: min-content auto;
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
background: repeating-linear-gradient( -45deg, #000, #555 10px, #000 10px, #555 20px );
|
||||
}
|
||||
|
||||
[eicapp] [eicapptoolbar] {
|
||||
@@ -101,6 +103,7 @@ body[eicapp] {
|
||||
[eicapp] .app-workspace .window.active {
|
||||
z-index: 3;
|
||||
background: var(--app-color-primary);
|
||||
border-radius: .3rem;
|
||||
}
|
||||
[eicapp] .app-workspace .window > header { display: grid; }
|
||||
[eicapp] .app-workspace .window > header h1 {
|
||||
@@ -123,7 +126,7 @@ body[eicapp] {
|
||||
[eicapp] .app-workspace .window > header .controls button.shrink { display: none; }
|
||||
[eicapp] .app-workspace .window > section {
|
||||
padding: var(--eicui-base-spacing-xs) var(--eicui-base-spacing-s);
|
||||
background: var(--app-bg-color);
|
||||
/*background: var(--app-bg-color);*/
|
||||
cursor: default;
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
@@ -140,7 +143,7 @@ body[eicapp] {
|
||||
width: 100%;
|
||||
max-width:none;
|
||||
padding: 0 var(--eicui-base-spacing-2xs) var(--eicui-base-spacing-3xl) var(--eicui-base-spacing-2xs);
|
||||
background-color: var(--app-bg-color);
|
||||
background: repeating-linear-gradient( -45deg, #000, #555 10px, #000 10px, #555 20px );
|
||||
cursor: default;
|
||||
margin: 0;
|
||||
overflow: visible;
|
||||
@@ -192,6 +195,7 @@ body[eicapp] {
|
||||
[eicapp] .app-content-thesaurus [eicchip] {
|
||||
box-shadow: 0px 0px 14px 0px #00000066;
|
||||
cursor: pointer;
|
||||
background: var(--app-color-primary);
|
||||
}
|
||||
[eicapp] .app-content-thesaurus [eicchip] label { cursor: pointer; }
|
||||
|
||||
@@ -213,6 +217,9 @@ body[eicapp] {
|
||||
[eicapp] [device="mobile"] article[eiccard] {
|
||||
margin: 0;
|
||||
}
|
||||
article[eiccard][media] > header {
|
||||
padding: var(--eicui-base-spacing-l) var(--eicui-base-spacing-m) var(--eicui-base-spacing-s) var(--eicui-base-spacing-m);
|
||||
}
|
||||
|
||||
.eic-session {
|
||||
padding: 0;
|
||||
@@ -256,3 +263,8 @@ body[eicapp] {
|
||||
[device="mobile"] .cols-8 {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
div.window > section:first-of-type > article[eiccard]:first-of-type{
|
||||
border: 2px solid var(--app-color-primary);
|
||||
border-radius: .5rem;
|
||||
}
|
||||
+17
-11
@@ -81,11 +81,11 @@ body {
|
||||
}
|
||||
|
||||
.glowing span:nth-child(3n + 2) {
|
||||
animation: rotatedots-reverse 5s alternate infinite;
|
||||
animation: rotatedots-reverse 9s alternate infinite;
|
||||
}
|
||||
|
||||
.glowing span:nth-child(3n + 3) {
|
||||
animation: rotatedots1 11s alternate infinite;
|
||||
animation: rotatedots1 15s alternate infinite;
|
||||
}
|
||||
|
||||
@keyframes fadeaway {
|
||||
@@ -95,17 +95,23 @@ body {
|
||||
}
|
||||
|
||||
@keyframes rotatedots1 {
|
||||
0% { transform: rotate(calc(180deg * var(--i))); }
|
||||
50% { transform: rotate(calc(0deg * var(--i))); }
|
||||
100% { transform: rotate(calc(360deg * var(--i))); }
|
||||
0% { transform: rotate(calc(180deg * var(--i))); scale:20%;}
|
||||
25% { transform: rotate(calc(90deg * var(--i))); scale:100%;}
|
||||
50% { transform: rotate(calc(0deg * var(--i))); scale:80%;}
|
||||
100% { transform: rotate(calc(360deg * var(--i))); scale:50%;}
|
||||
}
|
||||
|
||||
|
||||
@keyframes rotatedots-reverse {
|
||||
0% { transform: rotate(calc(135deg * var(--i))); }
|
||||
50% { transform: rotate(calc(-45deg * var(--i))); }
|
||||
100% { transform: rotate(calc(315deg * var(--i))); }
|
||||
0% { transform: rotate(calc(135deg * var(--i))); scale:20%;}
|
||||
25% { transform: rotate(calc(45deg * var(--i))); scale:100%;}
|
||||
50% { transform: rotate(calc(-45deg * var(--i))); scale:80%;}
|
||||
100% { transform: rotate(calc(315deg * var(--i))); scale:50%;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.logointro{
|
||||
filter: blur(14px);
|
||||
opacity: 0;
|
||||
@@ -133,7 +139,7 @@ body {
|
||||
bottom: 15vh;
|
||||
color: aliceblue;
|
||||
font-style: italic;
|
||||
font-size: 40px;
|
||||
font-size: 2rem;
|
||||
border-radius: 100px;
|
||||
padding: 5px 40px;
|
||||
background: radial-gradient(#82cc50, #0a8200);
|
||||
@@ -177,11 +183,11 @@ body {
|
||||
width: 15rem;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
font-size: 1.3rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
#login-dialog button{
|
||||
justify-self: end;
|
||||
font-size: 1.3rem;
|
||||
font-size: 1rem;
|
||||
float: right;
|
||||
}
|
||||
#login-dialog div.loginerr{
|
||||
|
||||
@@ -11,10 +11,15 @@
|
||||
"controller" : "/common/errorController",
|
||||
"method": "_401"
|
||||
},
|
||||
{
|
||||
"url": "/dashboard",
|
||||
"role": [ "admin" ],
|
||||
"controller" : "/dashboard/DashboardsController"
|
||||
},
|
||||
{
|
||||
"url": "/",
|
||||
"role": "Org_Member",
|
||||
"exturl": "/applicant"
|
||||
"role": "admin",
|
||||
"exturl": "/dashboard"
|
||||
},
|
||||
{
|
||||
"url": "/",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"enabled": true,
|
||||
"levels": ["err","warn"],
|
||||
"latestErrsMax": 20,
|
||||
"postUrl": "xxxhttps://api.dev.eismea.eu/logger"
|
||||
"postUrl": "xxxhttps://a42.internike.com/api/logger"
|
||||
},
|
||||
"userLib": {
|
||||
"className": "myUser",
|
||||
@@ -33,13 +33,9 @@
|
||||
"messageBus":{
|
||||
"enabled": true,
|
||||
"debug": true,
|
||||
"tokenUrl": "https://api.dev.eismea.eu/stable/msgBusToken",
|
||||
"pathToWorker": "/core/libs/MessageBusWorker.js",
|
||||
"protocol": "wss://",
|
||||
"host": "bus.dev.eismea.eu",
|
||||
"port": "",
|
||||
"XdevotpToken": "qhsdfkjhqsgdfkqhs",
|
||||
"Xhost": "eismea.internike.com",
|
||||
"host": "42.internike.com",
|
||||
"Xport": "4443",
|
||||
"path": "/msgbus",
|
||||
"connectTimeout": 5,
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
class DashboardsController extends EICController {
|
||||
|
||||
constructor(params) {
|
||||
super(params)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
index() {
|
||||
let models = {
|
||||
// mailings: new MailingsModel(payload['/mailings'].permissions)
|
||||
}
|
||||
// await app.Assets.loadHtml({name:'mailing/tile.html'})
|
||||
this.loadWindow(
|
||||
'dashboards/MainDashboardView',
|
||||
{
|
||||
title: 'Main dashboard',
|
||||
static: true,
|
||||
expanded: true
|
||||
},
|
||||
{
|
||||
models: models
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
app.registerClass('DashboardsController', DashboardsController);
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"routes": [
|
||||
{
|
||||
"url": "/",
|
||||
"role": [ "admin" ],
|
||||
"controller" : "/dashboard/DashboardsController",
|
||||
"method": "index"
|
||||
}
|
||||
],
|
||||
"models": [
|
||||
],
|
||||
"views": [
|
||||
"dashboards/MainDashboardView"
|
||||
],
|
||||
"controllerDependencies": [
|
||||
"/helpers/basicDialogs",
|
||||
"/helpers/validators",
|
||||
"/helpers/activeAttributes",
|
||||
"/thirdparty/Snaptobus/snap.svg-min",
|
||||
"/thirdparty/Snaptobus/snaptobus"
|
||||
],
|
||||
"assets": {
|
||||
"styles": [
|
||||
],
|
||||
"json": [
|
||||
]
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -126,6 +126,8 @@ class myUser extends app.LoadedClasses.User {
|
||||
} else {
|
||||
console.log('authenticated!')
|
||||
this.isAuthenticated = true
|
||||
this.identity = jsonresp.payload.userInfos.identity
|
||||
this.roles = jsonresp.payload.userInfos.roles
|
||||
callBack()
|
||||
}
|
||||
|
||||
@@ -136,7 +138,7 @@ class myUser extends app.LoadedClasses.User {
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
getMessageBusUserInfo() { return(this.identity.uuid) }
|
||||
getMessageBusUserInfo() { return(this.identity.username) }
|
||||
|
||||
async login(){
|
||||
const response = await fetch(app.config.userLib.loginEndpoint+'?'+crypto.randomUUID(), {
|
||||
@@ -154,7 +156,8 @@ class myUser extends app.LoadedClasses.User {
|
||||
if(jsonresp && jsonresp.success && jsonresp.payload){
|
||||
if(jsonresp.payload.authenticated){
|
||||
this.isAuthenticated = true
|
||||
this.userInfos = jsonresp.payload.userInfos
|
||||
this.identity = jsonresp.payload.userInfos.identity
|
||||
this.roles = jsonresp.payload.userInfos.roles
|
||||
return(true)
|
||||
} else {
|
||||
document.querySelector('div.loginerr').classList.add('show')
|
||||
@@ -172,7 +175,7 @@ class myUser extends app.LoadedClasses.User {
|
||||
}
|
||||
}
|
||||
this.isAuthenticated = false
|
||||
this.userInfos = null
|
||||
this.identity = null
|
||||
return(false)
|
||||
}
|
||||
|
||||
@@ -260,6 +263,8 @@ class myUser extends app.LoadedClasses.User {
|
||||
setPreference(path, value) {
|
||||
if(app.MessageBus) {
|
||||
let segments = path.split('.');
|
||||
|
||||
console.log('=====>',this, this.preferences)
|
||||
let pointer = this.preferences;
|
||||
|
||||
for(let i = 0; i < segments.length - 1; i++) {
|
||||
|
||||
+21
File diff suppressed because one or more lines are too long
+104
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* @classdesc The main Snaptobus class
|
||||
* @author Nike
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
class Snaptobus{
|
||||
constructor(config){
|
||||
this.config = this.observeObject(config, this.configChange.bind(this))
|
||||
}
|
||||
|
||||
observeObject(obj, onChange) {
|
||||
const wrap = (value) =>
|
||||
(value && typeof value === 'object')
|
||||
? this.observeObject(value, onChange)
|
||||
: value
|
||||
|
||||
const handler = {
|
||||
set: (target, prop, value) => {
|
||||
const oldValue = target[prop]
|
||||
target[prop] = wrap(value)
|
||||
onChange(prop, value, oldValue, target)
|
||||
return true
|
||||
},
|
||||
deleteProperty: (target, prop) => {
|
||||
const oldValue = target[prop]
|
||||
delete target[prop]
|
||||
onChange(prop, undefined, oldValue, target)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Walk initial keys/elements (construction time)
|
||||
for (const key of Object.keys(obj)) {
|
||||
obj[key] = wrap(obj[key])
|
||||
}
|
||||
|
||||
return new Proxy(obj, handler)
|
||||
}
|
||||
|
||||
configChange(prop, newval, oldval){
|
||||
//TODO subscribe new chans
|
||||
//TODO unsubscribe removed chans
|
||||
//TODO update event filters
|
||||
//
|
||||
console.log(prop, oldval, newval)
|
||||
}
|
||||
|
||||
getValueByPath(obj, path) {
|
||||
return(path.split('.').reduce((acc, key) => acc?.[key], obj))
|
||||
}
|
||||
|
||||
assignFromConfig(chan, event) {
|
||||
const result = {}
|
||||
for (const [key, rule] of Object.entries(this.config.assign)) {
|
||||
if (typeof rule === 'string') { // plain path
|
||||
result[key] = this.getValueByPath(event, rule)
|
||||
} else if((typeof(rule) == 'object') && (typeof(rule.transformer) == 'function')) { // transformer
|
||||
const fnargs = (rule.arguments || []).map(arg => this.getValueByPath(event,arg))
|
||||
result[key] = rule.transformer(...fnargs)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
/*
|
||||
const s2bConfig = [
|
||||
{ chan: 'gps:agents', // What to subscribe to
|
||||
events: [ // What to select on this chan
|
||||
{ eventName: 'moving',
|
||||
snaps: [
|
||||
{
|
||||
// selector will be used as css selector for a snap element / group,
|
||||
// with LAST MINUTE template resolving of event properties (with eventual dots)
|
||||
selector: '#${aid}',
|
||||
assign: {
|
||||
x: 'coords.x', // type string: event property, eventual dots to go down object
|
||||
y: 'coords.y',
|
||||
},
|
||||
animate: true
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{ chan: 'agent:*', // wildcards allowed
|
||||
events: [
|
||||
{ eventName: 'aging',
|
||||
snaps: [
|
||||
{
|
||||
selector: '#{aid}',
|
||||
assign: {
|
||||
fill: { // transformer function
|
||||
arguments: [ 'age' ], // What to give from the event as function's params
|
||||
transformer: i => `rgb(${Math.round(255 * i / 10)},0,${Math.round(255 * (1 - i / 10))})`
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
*/
|
||||
@@ -0,0 +1,8 @@
|
||||
<article eiccard media class="mainDashboard">
|
||||
<header>
|
||||
<h1>Simulation Main dashboard</h1>
|
||||
</header>
|
||||
<section>
|
||||
hello world
|
||||
</section>
|
||||
</article>
|
||||
@@ -0,0 +1,28 @@
|
||||
class MainDashboardView extends EICDomContent {
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
Object.assign(this, app.helpers.activeAttributes)
|
||||
//this.tileMarkup = app.Assets.Store.html['/app/assets/html/mailing/tile.html']
|
||||
}
|
||||
|
||||
DOMContentLoaded(options) {
|
||||
for(let model in options.models) this[model] = options.models[model]
|
||||
const components = ui.eicfy(this.el)
|
||||
this.setupTriggers(components)
|
||||
this.setupRefs(components)
|
||||
|
||||
}
|
||||
|
||||
DOMContentFocused(options) {
|
||||
// Avoid 2nd refesh on DomContentLoaded
|
||||
if(this.wasBlured){
|
||||
//this.refreshSearch()
|
||||
}
|
||||
this.wasBlured = false
|
||||
}
|
||||
|
||||
DOMContentBlured(options) { this.wasBlured = true }
|
||||
}
|
||||
|
||||
app.registerClass('MainDashboardView', MainDashboardView)
|
||||
@@ -36,38 +36,7 @@ class MessageBusWorker {
|
||||
this.token = false
|
||||
this.stateMachine = 'DISCONNECTED'
|
||||
this.noReconnect = false
|
||||
// 'DISCONNECTED'
|
||||
// -> 'LOGIN' (receive challenge & answer to it)
|
||||
// -> 'READY' (received logged=true)
|
||||
this.getToken()
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getToken() {
|
||||
if(!this.config.devotpToken){
|
||||
fetch(this.config.tokenUrl+'?'+crypto.randomUUID(),{
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(response => response.json(), (err => {console.log('ERROR IN FETCH:',err)}))
|
||||
.then(data => {
|
||||
if(data.success && data.payload && data.payload.token) {
|
||||
this.token = data.payload.token
|
||||
if(this.config.debug && ''=='sensitive-even-for-debug') console.log(`Received Token : ${this.token}`)
|
||||
this.connect();
|
||||
} else {
|
||||
console.warn('Could not get messagebus token !')
|
||||
//TODO retry once in a while / integrate in the whole connect process
|
||||
// to be part of retrials...
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.warn('!!! Using dev token for bus !!!')
|
||||
this.token = this.config.devotpToken
|
||||
this.connect();
|
||||
}
|
||||
|
||||
this.connect();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,23 +72,11 @@ class MessageBusWorker {
|
||||
* @param {*} e
|
||||
*/
|
||||
WSonOpen(e){
|
||||
this.stateMachine = 'LOGIN'
|
||||
this.stateMachine = 'READY'
|
||||
clearTimeout( this.ConnectTimeout);
|
||||
console.log('Websocket connection established');
|
||||
this.curReconnectTime = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {*} challenge
|
||||
*/
|
||||
async login(challenge) {
|
||||
let data = new TextEncoder().encode(this.token+challenge)
|
||||
let bytesBuf = await crypto.subtle.digest("SHA-512", data)
|
||||
let arrayBuf = Array.from(new Uint8Array(bytesBuf))
|
||||
let response = arrayBuf.map((b) => b.toString(16).padStart(2, "0")).join("")
|
||||
if(this.config.debug && ''=='sensitive-even-for-debug') console.log(`Answering to challenge, with userinfo:`, response, this.userInfo)
|
||||
this.clientActionDispatch({'action':'LOGIN', 'userInfo': this.userInfo , 'otp': response});
|
||||
postMessage({'event': 'connected' });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,29 +98,6 @@ class MessageBusWorker {
|
||||
return;
|
||||
}
|
||||
|
||||
//if(this.config.debug) console.log(`Received MSG (in state:${this.stateMachine}) :`, data, this.stateMachine)
|
||||
// LOGIN messages
|
||||
if(this.stateMachine == 'LOGIN'){
|
||||
if(data.action!='LOGIN') { // Non LOGIN messages in a LOGIN state are garbage
|
||||
console.warn('WSS: Non-login message in a LOGIN state',data.action)
|
||||
return
|
||||
}
|
||||
if(data.challenge) { // step1: challenge to reply
|
||||
if(this.config.debug && ''=='sensitive-even-for-debug') console.log(`Got challenge ${data.challenge}...`)
|
||||
this.login(data.challenge)
|
||||
return
|
||||
} else if(data.logged===true){ // step2 logged !
|
||||
if(this.config.debug) console.log(`Logged !`)
|
||||
this.stateMachine = 'READY'
|
||||
postMessage({'event': 'connected' });
|
||||
return
|
||||
} else if(data.logged===false){ // step2 bad login !
|
||||
this.noReconnect = true
|
||||
console.warn('WSS-Login: challenge-response refused. (session lost?)')
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if((data.action=='PING') && this.keepAlive){ // Keep Alive is managed here
|
||||
this.clientActionDispatch({'action':'PONG'});
|
||||
return
|
||||
@@ -196,8 +130,8 @@ class MessageBusWorker {
|
||||
}
|
||||
var rjit = (Math.random()*reconnectJitterPercent)-(reconnectJitterPercent/2);
|
||||
this.curReconnectTime += (this.curReconnectTime*(rjit/100));
|
||||
// Reconnect in curReconnectTime (=>getToken THEN connect)
|
||||
setTimeout(this.getToken.bind(this), Math.floor(1000*this.curReconnectTime));
|
||||
// Reconnect in curReconnectTime
|
||||
setTimeout(this.connect.bind(this), Math.floor(1000*this.curReconnectTime));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user