update project with new architecture
This commit is contained in:
111
asupsetup/ASUPconfig.jsold
Executable file
111
asupsetup/ASUPconfig.jsold
Executable file
@@ -0,0 +1,111 @@
|
||||
'use strict';
|
||||
const path = require( 'path' );
|
||||
const fs = require( 'fs' );
|
||||
const config = {};
|
||||
if( !process.env.NODE_ENV ) process.env.NODE_ENV = "dev"
|
||||
console.log( 'apxtrib process.env.NODE_ENV: ', process.env.NODE_ENV );
|
||||
// VOIR l'ancien fichier de cnfig au cas ou il manque des chemins dans config
|
||||
// voir la doc http://gitlab.ndda.fr/philc/apiamaildigitfr/wikis/InstallConf
|
||||
config.prod = {
|
||||
mainDir: __dirname,
|
||||
tmp: path.join( __dirname, '/tmp' ),
|
||||
public: path.join( __dirname, '/public' ),
|
||||
archivefolder: path.join( __dirname, '/archive' ),
|
||||
rootURL: '{{setupdns}}',
|
||||
domain: path.join( __dirname, '/data/tribee' ),
|
||||
withssl: "{{withssl}}",
|
||||
SSLCredentials: {
|
||||
key: path.join( __dirname, '/data/certs/{{setupdns}}.key' ),
|
||||
cert: path.join( __dirname, '/data/certs/{{setupdns}}.crt' ),
|
||||
ca: path.join( __dirname, '/data/certs/{{setupdns}}.csr' )
|
||||
},
|
||||
port: {
|
||||
http: "{{httpport}}",
|
||||
https: "{{httpsport}}"
|
||||
},
|
||||
jwtSecret: '{{jwtsecretkey}}',
|
||||
saltRounds: 10,
|
||||
languagesAvailable: [ 'fr', 'en', 'it', 'de', 'ru' ],
|
||||
lg: {},
|
||||
exposedHeaders: {
|
||||
'x-auth': 'xauth',
|
||||
'x-uuid': 'xuuid',
|
||||
'x-language': 'xlang',
|
||||
'x-client-id': 'xtribeid',
|
||||
'x-workOn': 'xworkOn',
|
||||
'x-app': 'xapp'
|
||||
},
|
||||
bodyparse: {
|
||||
urlencoded: {
|
||||
limit: '50mb',
|
||||
extended: true
|
||||
},
|
||||
json: { limit: '500mb' }
|
||||
}
|
||||
};
|
||||
// Development and test config
|
||||
// apxtrib.local.fr
|
||||
|
||||
config.dev = {
|
||||
mainDir: __dirname,
|
||||
tmp: path.join( __dirname, '/tmp' ),
|
||||
public: path.join( __dirname, '/public' ),
|
||||
//public allow to serve on /public file into folder /public with or without login
|
||||
archivefolder: path.join( __dirname, '/archive' ),
|
||||
rootURL: 'apxtrib.local.fr',
|
||||
domain: path.join( __dirname, '/data/tribee' ),
|
||||
withssl: "YES",
|
||||
SSLCredentials: {
|
||||
key: path.join( __dirname, '/setup/data/certs/apxtrib.local.fr.key' ),
|
||||
cert: path.join( __dirname, '/setup/data/certs/apxtrib.local.fr.crt' ),
|
||||
ca: path.join( __dirname, '/setup/data/certs/apxtrib.local.fr.csr' )
|
||||
},
|
||||
port: {
|
||||
http: "{{httpport}}",
|
||||
https: "{{httpsport}}"
|
||||
},
|
||||
jwtSecret: 'dnsqd515+npsc^dsqdsqd^d$qdd$$$dŝqdze154615ae.Dsd:sqd!',
|
||||
// Avoid authentification for uuid2 and this auth token
|
||||
// Always remove this from production
|
||||
devnoauthxuuid: "2",
|
||||
devnoauthxauth: "autoriserparlapatrouille",
|
||||
saltRounds: 10,
|
||||
languagesAvailable: [ 'fr', 'en', 'it', 'de', 'ru' ],
|
||||
lg: {},
|
||||
exposedHeaders: {
|
||||
'x-auth': 'xauth',
|
||||
'x-uuid': 'xuuid',
|
||||
'x-language': 'xlang',
|
||||
'x-client-id': 'xtribeid',
|
||||
'x-workOn': 'xworkOn',
|
||||
'x-app': 'xapp'
|
||||
},
|
||||
bodyparse: {
|
||||
urlencoded: {
|
||||
limit: '50mb',
|
||||
extended: true
|
||||
},
|
||||
json: { limit: '500mb' }
|
||||
}
|
||||
};
|
||||
if( !config[ process.env.NODE_ENV ] ) {
|
||||
console.log( 'config.js -> Exit setup due to node_ENV have to be set as prod or dev instead of ', process.env.NODE_ENV )
|
||||
process.exit();
|
||||
}
|
||||
const confuse = config[ process.env.NODE_ENV ];
|
||||
if( confuse.withssl == "YES" ) {
|
||||
if( !fs.existsSync( confuse.SSLCredentials.key ) ) {
|
||||
const prompt = require( 'prompt-sync' )( { sigint: true } );
|
||||
//const repdata = ( process.NODE_ENV == "dev" ) ? 'devdata' : 'data';
|
||||
const reinit = prompt( `Missing file to ssl ${confuse.SSLCredentials.key}, please run the process letsencrypt to get a ssl certificat or reinit project (type reinit will erase ) and answer no to question: Do you want to manage ssl : ` );
|
||||
if( reinit == 'reinit' ) {
|
||||
fs.removeSync( `${__dirname}/config.js` );
|
||||
fs.removeSync( `${__dirname}/data` )
|
||||
}
|
||||
process.exit();
|
||||
}
|
||||
confuse.SSLCredentials.key = fs.readFileSync( confuse.SSLCredentials.key, 'utf8' );
|
||||
confuse.SSLCredentials.cert = fs.readFileSync( confuse.SSLCredentials.cert, 'utf8' );
|
||||
confuse.SSLCredentials.ca = fs.readFileSync( confuse.SSLCredentials.ca, 'utf8' );
|
||||
}
|
||||
module.exports = confuse;
|
37
asupsetup/apixtribe.crabdance.com.mustache
Executable file
37
asupsetup/apixtribe.crabdance.com.mustache
Executable file
@@ -0,0 +1,37 @@
|
||||
server {
|
||||
server_name {{config.apxtribDNS}};
|
||||
add_header X-Request-ID $request_id; # Return to client
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Max-Age 3600;
|
||||
add_header Access-Control-Expose-Headers Content-Length;
|
||||
add_header Access-Control-Allow-Headers Range;
|
||||
|
||||
access_log /media/phil/usbfarm/apxtrib/tmp/nginx/apxtrib.crabdance.access.log main;
|
||||
|
||||
#location = /app {
|
||||
# return 302 /app/;
|
||||
#}
|
||||
location /app/ {
|
||||
rewrite /app/(.*$) /$1 break;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
client_max_body_size 10m;
|
||||
client_body_buffer_size 128k;
|
||||
proxy_connect_timeout 90;
|
||||
proxy_send_timeout 90;
|
||||
proxy_read_timeout 90;
|
||||
proxy_buffers 32 4k;
|
||||
proxy_set_header X-NginX-Proxy true;
|
||||
proxy_pass http://localhost:3017;
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /media/phil/usbfarm/apxtrib/nationchains/;
|
||||
index apxtrib.html;
|
||||
}
|
||||
error_page 404 /media/phil/usbfarm/apxtrib/nationchains/error/404.html;
|
||||
error_page 500 502 503 504 /media/phil/usbfarm/apxtrib/nationchains/error/50x.html;
|
||||
}
|
||||
|
26
asupsetup/config.mustache
Executable file
26
asupsetup/config.mustache
Executable file
@@ -0,0 +1,26 @@
|
||||
const path = require( 'path' );
|
||||
const config = {
|
||||
loglevel:"{{consoleloglevel}}",
|
||||
linuxuser:"{{linuxuser}}",
|
||||
druidid:"{{druidid}}",
|
||||
dnsapxtrib:"{{subdomain}}.{{domain}}",
|
||||
mainDir: __dirname,
|
||||
tmp: path.join( __dirname, '/tmp' ),
|
||||
public: path.join( __dirname, 'data/tribe/{{druidid}}/www/cdn' ),
|
||||
//(@TODO ASUP mettre /cdn de apxtrib) public allow to serve on /public file into folder /public with or without login
|
||||
archivefolder: path.join( __dirname, '/archive' ),
|
||||
domain: path.join( __dirname, '/data/tribe' ),
|
||||
porthttp:{{porthttp}} ,
|
||||
jwtSecret: '{{jwtsecret}}',
|
||||
saltRounds: 10,
|
||||
languagesAvailable: [ {{#language}}'{{.}}',{{/language}} ],
|
||||
exposedHeaders:[ 'xauth', 'xpaganid', 'xlang', 'xtribe', 'xworkon', 'xapp' ],
|
||||
bodyparse: {
|
||||
urlencoded: {
|
||||
limit: '50mb',
|
||||
extended: true
|
||||
},
|
||||
json: { limit: '500mb' }
|
||||
}
|
||||
};
|
||||
module.exports = config;
|
13
asupsetup/configsetup.json
Executable file
13
asupsetup/configsetup.json
Executable file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"linuxuser": "phil",
|
||||
"mode": "dev",
|
||||
"domain": "local.fr",
|
||||
"subdomain": "dev",
|
||||
"consoleloglevel": "quiet",
|
||||
"porthttp": 3018,
|
||||
"language": ["fr", "en"],
|
||||
"jwtsecret": "longsentenceusedtoencryptionChangethisforproduction",
|
||||
"druidid": "test",
|
||||
"login": "testadmin",
|
||||
"genericpsw": "@12ABab@"
|
||||
}
|
9
asupsetup/data/domain/apixpress/blockchains/blocks/0.json
Executable file
9
asupsetup/data/domain/apixpress/blockchains/blocks/0.json
Executable file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"hash": "",
|
||||
"previousblockhash": "",
|
||||
"nextblockhash": "",
|
||||
"info": "txt:freedomandthefuturofinternet##",
|
||||
"time": 1643763742,
|
||||
"size": "",
|
||||
"difficulty": ""
|
||||
}
|
10
asupsetup/data/domain/apixpress/blockchains/nodes/apixpress.ndda.fr
Executable file
10
asupsetup/data/domain/apixpress/blockchains/nodes/apixpress.ndda.fr
Executable file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"fixedIP":"",
|
||||
"firsttimeping":0,
|
||||
"lastimeping":0,
|
||||
"positifping":0,
|
||||
"negatifping":0,
|
||||
"pubkeyadmin":"",
|
||||
"tribeids":[],
|
||||
"logins":[]
|
||||
}
|
28
asupsetup/data/domain/apixpress/clientconf.mustache
Executable file
28
asupsetup/data/domain/apixpress/clientconf.mustache
Executable file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"tribeid": "{{tribeid}}",
|
||||
"genericpsw": "{{genericpsw}}",
|
||||
"saltRounds": "tomakeitharderbetterstronger",
|
||||
"website": {
|
||||
"webapp": "{{subdomain}}.{{domain}}"
|
||||
},
|
||||
"allowedDOMs": ["{{domain}}"],
|
||||
"customization": {
|
||||
"claim": "Be a Producer, not a product.",
|
||||
"name": "apxtrib",
|
||||
"logo": "https://{{subdomain}}.{{domain}}/cdn/{{druidid}}/img/logo/apxtrib.png",
|
||||
"favicon": "https://{{subdomain}}.{{domain}}/cdn/{{druidid}}/img/iconX74x74.png",
|
||||
"colors": {
|
||||
"primary": "#01717B",
|
||||
"secondary": "#CA5F00",
|
||||
"success": "",
|
||||
"info": "",
|
||||
"warning": "",
|
||||
"danger": "",
|
||||
"light": "#fff",
|
||||
"dark": "#222"
|
||||
}
|
||||
},
|
||||
"smtp": {},
|
||||
"accepted-language": "fr,en",
|
||||
"langueReferential": ["fr"]
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
[{
|
||||
"uuid": "ERRcritical",
|
||||
"desc": {
|
||||
"fr": "Erreur critique",
|
||||
"en": "Critical Error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "failtoWritefs",
|
||||
"desc": {
|
||||
"fr": "Impossible d'enregistrer cette information",
|
||||
"en": "Fail to write on system"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulCreate",
|
||||
"desc": {
|
||||
"fr": "Création réussie",
|
||||
"en": "Creation is successful"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulUpdate",
|
||||
"desc": {
|
||||
"fr": "Mise à jour réussie",
|
||||
"en": "Succesfull update"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulDelete",
|
||||
"desc": {
|
||||
"fr": "Suppression effectuée",
|
||||
"en": "The user has been deleted"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "forbiddenAccess",
|
||||
"desc": {
|
||||
"fr": "Accès non autorisé",
|
||||
"en": "Forbidden access"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoCreate",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authorisé à créer un nouvel utilisateur",
|
||||
"en": "Pagans is not allowed to create a new user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoUpdate",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authorisé à mettre à jour cet utilisateur",
|
||||
"en": "Pagans is not allowed to update this user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoDelete",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authrisé à supprimer utilisateur",
|
||||
"en": "Pagans is not allowed to delete a user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "invalidData",
|
||||
"desc": {
|
||||
"fr": "Vérifiez vos données",
|
||||
"en": "Check your data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ERRemail",
|
||||
"desc": {
|
||||
"fr": "Vérifiez votre email",
|
||||
"en": "Check your email"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "Reservationplandoesnotexist",
|
||||
"desc": {
|
||||
"fr": "Il n'y a pas de Planning de réservation",
|
||||
"en": "No reservation plan at this adress"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "Reservationitemwelldone",
|
||||
"desc": {
|
||||
"fr": "Votre reservation a bien été enregistrée",
|
||||
"en": "Registration well done."
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "Nomoreavailability",
|
||||
"desc": {
|
||||
"fr": "Désolé, la place n'est plus disponible",
|
||||
"en": "Unavailable."
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "CatalogdoesnotExist",
|
||||
"desc": {
|
||||
"fr": "Désolé, ce catagoue n'existe pas",
|
||||
"en": "This catalog does not exist."
|
||||
}
|
||||
}
|
||||
]
|
@@ -0,0 +1,170 @@
|
||||
[
|
||||
{
|
||||
"uuid": "ERRcritical",
|
||||
"desc": {
|
||||
"fr": "Erreur critique",
|
||||
"en": "Critical Error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "msgsentok",
|
||||
"desc": {
|
||||
"fr": "L'email a bien été envoyé",
|
||||
"en": "email sent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "emailAlreadyExist",
|
||||
"desc": {
|
||||
"fr": "Cet email a déjà un compte",
|
||||
"en": "Email already exists"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "failtoWritefs",
|
||||
"desc": {
|
||||
"fr": "Impossible d'enregistrer cette information",
|
||||
"en": "Fail to write on system"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulCreate",
|
||||
"desc": {
|
||||
"fr": "Création réussie",
|
||||
"en": "Creation is successful"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulUpdate",
|
||||
"desc": {
|
||||
"fr": "Mise à jour réussie",
|
||||
"en": "Succesfull update"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulDelete",
|
||||
"desc": {
|
||||
"fr": "Suppression effectuée",
|
||||
"en": "The user has been deleted"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "serverNeedAuthentification",
|
||||
"desc": {
|
||||
"fr": "Ce serveur nécessite une authentification",
|
||||
"en": "This server needs authentification"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "forbiddenAccess",
|
||||
"desc": {
|
||||
"fr": "Accès non autorisé",
|
||||
"en": "Forbidden access"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoCreate",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authorisé à créer un nouvel utilisateur",
|
||||
"en": "Pagans is not allowed to create a new user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoUpdate",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authorisé à mettre à jour cet utilisateur",
|
||||
"en": "Pagans is not allowed to update this user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoDelete",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authrisé à supprimer utilisateur",
|
||||
"en": "Pagans is not allowed to delete a user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "useridNotfound",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur {{uuid}} n'existe pas sur {{tribeid}}",
|
||||
"en": "Pagans {{uuid}} not found for {{tribeid}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "useremailNotfound",
|
||||
"desc": {
|
||||
"fr": "L'email n'existe pas",
|
||||
"en": "Email not found"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "loginDoesNotExist",
|
||||
"desc": {
|
||||
"fr": "Ce login n'existe pas",
|
||||
"en": "This login doesn't exist"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "checkCredentials",
|
||||
"desc": {
|
||||
"fr": "Vérifiez vos identifiants",
|
||||
"en": "Check your credentials"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "wrongPassword",
|
||||
"desc": {
|
||||
"fr": "Vérifiez votre mot de passe",
|
||||
"en": "Check your password"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "invalidData",
|
||||
"desc": {
|
||||
"fr": "Vérifiez vos données",
|
||||
"en": "Check your data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "pswTooSimple",
|
||||
"desc": {
|
||||
"fr": "Le mot de passe doit faire au moins 8 caractéres comporter au moins un chiffre, une lettre minuscule, une lettre majuscule et un caractere spécial type @ !...",
|
||||
"en": "Password too simple, need to contain at least 8 caracters lower and uppercase, number and @! ..."
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ERRemail",
|
||||
"desc": {
|
||||
"fr": "Vérifiez votre email",
|
||||
"en": "Check your email"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ERRnewnewbisdiff",
|
||||
"desc": {
|
||||
"fr": "Le mot de passe de confirmation ne correspond pas",
|
||||
"en": "Check your confirmation password"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ERRnotemplate",
|
||||
"desc": {
|
||||
"fr": "il n'y a pas de template d'email dans la demande template.html est vide et pas de htmlfile présent.",
|
||||
"en": "Check your email template conf tribeid no msg.template.htmlfile and msg.html==''"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "wellPdfGenerated",
|
||||
"desc": {
|
||||
"fr": "Le pdf: {{filename}} a ete genere correctement.",
|
||||
"en": "Pdf well generated"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "pdfGenerationError",
|
||||
"desc": {
|
||||
"fr": "Erreur dans la generation de pdf, verifiez le json",
|
||||
"en": "Error in pdf generation, check the json"
|
||||
}
|
||||
}
|
||||
]
|
@@ -0,0 +1,23 @@
|
||||
[
|
||||
{
|
||||
"uuid": "fileUnknown",
|
||||
"desc": {
|
||||
"fr": "Fichier inconnu",
|
||||
"en": "File unknown"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "wellUpload",
|
||||
"desc": {
|
||||
"fr": "Fichier bien récupéré dans {{destination}}/{{filename}}",
|
||||
"en": "File well uploaded in {{destination}}/{{filename}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "savingError",
|
||||
"desc": {
|
||||
"fr": "Impossible de sauvegarder",
|
||||
"en": "Saving file is impossible"
|
||||
}
|
||||
}
|
||||
]
|
@@ -0,0 +1,149 @@
|
||||
[
|
||||
{
|
||||
"uuid": "ERRcritical",
|
||||
"desc": {
|
||||
"fr": "Erreur critique",
|
||||
"en": "Critical Error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "loginAlreadyExist",
|
||||
"desc": {
|
||||
"fr": "Ce login est déjà attribué",
|
||||
"en": "Login already exists"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "emailAlreadyExist",
|
||||
"desc": {
|
||||
"fr": "Cet email a déjà un compte",
|
||||
"en": "Email already exists"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "failtoWritefs",
|
||||
"desc": {
|
||||
"fr": "Impossible d'enregistrer cette information",
|
||||
"en": "Fail to write on system"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulCreate",
|
||||
"desc": {
|
||||
"fr": "Création réussie",
|
||||
"en": "Creation is successful"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulUpdate",
|
||||
"desc": {
|
||||
"fr": "Mise à jour réussie",
|
||||
"en": "Succesfull update"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "successfulDelete",
|
||||
"desc": {
|
||||
"fr": "Suppression effectuée",
|
||||
"en": "The user has been deleted"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "serverNeedAuthentification",
|
||||
"desc": {
|
||||
"fr": "Ce serveur nécessite une authentification",
|
||||
"en": "This server needs authentification"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "forbiddenAccess",
|
||||
"desc": {
|
||||
"fr": "Accès non autorisé",
|
||||
"en": "Forbidden access"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoCreate",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authorisé à créer un nouvel utilisateur",
|
||||
"en": "Pagans is not allowed to create a new user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoUpdate",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authorisé à mettre à jour cet utilisateur",
|
||||
"en": "Pagans is not allowed to update this user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "userNotAllowtoDelete",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur n'est pas authrisé à supprimer utilisateur",
|
||||
"en": "Pagans is not allowed to delete a user account"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "useridNotfound",
|
||||
"desc": {
|
||||
"fr": "L'utilisateur {{uuid}} n'existe pas sur {{tribeid}}",
|
||||
"en": "Pagans {{uuid}} not found for {{tribeid}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "useremailNotfound",
|
||||
"desc": {
|
||||
"fr": "L'email n'existe pas",
|
||||
"en": "Email not found"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "loginDoesNotExist",
|
||||
"desc": {
|
||||
"fr": "Ce login n'existe pas",
|
||||
"en": "This login doesn't exist"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "checkCredentials",
|
||||
"desc": {
|
||||
"fr": "Vérifiez vos identifiants",
|
||||
"en": "Check your credentials"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "wrongPassword",
|
||||
"desc": {
|
||||
"fr": "Vérifiez votre mot de passe",
|
||||
"en": "Check your password"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "invalidData",
|
||||
"desc": {
|
||||
"fr": "Vérifiez vos données",
|
||||
"en": "Check your data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "pswTooSimple",
|
||||
"desc": {
|
||||
"fr": "Le mot de passe doit faire au moins 8 caractéres comporter au moins un chiffre, une lettre minuscule, une lettre majuscule et un caractere spécial type @ !...",
|
||||
"en": "Password too simple, need to contain at least 8 caracters lower and uppercase, number and @! ..."
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ERRemail",
|
||||
"desc": {
|
||||
"fr": "Vérifiez votre email",
|
||||
"en": "Check your email"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ERRnewnewbisdiff",
|
||||
"desc": {
|
||||
"fr": "Le mot de passe de confirmation ne correspond pas",
|
||||
"en": "Check your confirmation password"
|
||||
}
|
||||
}
|
||||
]
|
12
asupsetup/data/domain/apixpress/referentials/dataManagement/data/gender.json
Executable file
12
asupsetup/data/domain/apixpress/referentials/dataManagement/data/gender.json
Executable file
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"uuid": 0,
|
||||
"desclong": { "fr": "Monsieur", "en": "Mister" },
|
||||
"desc": { "fr": "M.", "en": "M." }
|
||||
},
|
||||
{
|
||||
"uuid": 1,
|
||||
"desclong": { "fr": "Madame", "en": "Miss" },
|
||||
"desc": { "fr": "Mme", "en": "Miss" }
|
||||
}
|
||||
]
|
314
asupsetup/data/domain/apixpress/referentials/dataManagement/data/missionpos.json
Executable file
314
asupsetup/data/domain/apixpress/referentials/dataManagement/data/missionpos.json
Executable file
@@ -0,0 +1,314 @@
|
||||
[
|
||||
{
|
||||
"uuid": "AMDTA",
|
||||
"desc": { "fr": "Amiante (DTA)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_01 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#449245"
|
||||
},
|
||||
{
|
||||
"uuid": "AMVENT",
|
||||
"desc": { "fr": "Amiante (Vente)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_02 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#136202"
|
||||
},
|
||||
{
|
||||
"uuid": "AMTRAV",
|
||||
"desc": { "fr": "Amiante (Travaux)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_03 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#865694"
|
||||
},
|
||||
{
|
||||
"uuid": "AMDEMOL",
|
||||
"desc": { "fr": "Amiante (Démol)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_04 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#086446"
|
||||
},
|
||||
{
|
||||
"uuid": "DIAGTERM",
|
||||
"desc": { "fr": "Diag.Termites" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_05 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#036034"
|
||||
},
|
||||
{
|
||||
"uuid": "DIAGPARA",
|
||||
"desc": { "fr": "Diag.Parasites" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_06 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#116801"
|
||||
},
|
||||
{
|
||||
"uuid": "CARREZ",
|
||||
"desc": { "fr": "Mesurage (Carrez)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_07 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#341770"
|
||||
},
|
||||
{
|
||||
"uuid": "CREP",
|
||||
"desc": { "fr": "Constat des risques d'exposition au plomb (CREP)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_08 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#303924"
|
||||
},
|
||||
{
|
||||
"uuid": "ASSAINISS",
|
||||
"desc": { "fr": "Assainissement" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_09 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#279573"
|
||||
},
|
||||
{
|
||||
"uuid": "PISCINE",
|
||||
"desc": { "fr": "Piscine" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_10 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#450176"
|
||||
},
|
||||
{
|
||||
"uuid": "GAZ",
|
||||
"desc": { "fr": "Gaz" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_11 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#763822"
|
||||
},
|
||||
{
|
||||
"uuid": "ELEC",
|
||||
"desc": { "fr": "Electricité" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_12 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#873048"
|
||||
},
|
||||
{
|
||||
"uuid": "SRU",
|
||||
"desc": { "fr": "D.Technique SRU" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_13 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#279870"
|
||||
},
|
||||
{
|
||||
"uuid": "DPE",
|
||||
"desc": { "fr": "DPE" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_14 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#862302"
|
||||
},
|
||||
{
|
||||
"uuid": "TX0",
|
||||
"desc": { "fr": "Prêt à taux zéro" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_15 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#279050"
|
||||
},
|
||||
{
|
||||
"uuid": "ERNT",
|
||||
"desc": { "fr": "ERNT" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_16 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#870447"
|
||||
},
|
||||
{
|
||||
"uuid": "ROBIEN",
|
||||
"desc": { "fr": "Robien" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_17 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#238577"
|
||||
},
|
||||
{
|
||||
"uuid": "ETATLIEU",
|
||||
"desc": { "fr": "Etat des lieux" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_18 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#159488"
|
||||
},
|
||||
{
|
||||
"uuid": "DIAGPBEAU",
|
||||
"desc": { "fr": "Diag. plomb dans l'eau" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_19 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#210836"
|
||||
},
|
||||
{
|
||||
"uuid": "ASCENSE",
|
||||
"desc": { "fr": "Ascenseur" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_20 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#702852"
|
||||
},
|
||||
{
|
||||
"uuid": "RADON",
|
||||
"desc": { "fr": "Radon" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_21 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#851497"
|
||||
},
|
||||
{
|
||||
"uuid": "INCENDIE",
|
||||
"desc": { "fr": "Incendie" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_22 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#329688"
|
||||
},
|
||||
{
|
||||
"uuid": "HANDICAP",
|
||||
"desc": { "fr": "Handicapé" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_23 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#752339"
|
||||
},
|
||||
{
|
||||
"uuid": "BOUTIN",
|
||||
"desc": { "fr": "Mesurage (Boutin)" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_24 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#645556"
|
||||
},
|
||||
{
|
||||
"uuid": "AMDAPP",
|
||||
"desc": { "fr": "Amiante DAPP" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_25 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#594067"
|
||||
},
|
||||
{
|
||||
"uuid": "DRIPP",
|
||||
"desc": { "fr": "DRIPP" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_26 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#135691"
|
||||
},
|
||||
{
|
||||
"uuid": "DPN",
|
||||
"desc": { "fr": "DPN Performance numérique" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_27 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#659536"
|
||||
},
|
||||
{
|
||||
"uuid": "INFILTRO",
|
||||
"desc": { "fr": "Infiltrométrie" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_28 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#931708"
|
||||
},
|
||||
{
|
||||
"uuid": "AMAPTVX",
|
||||
"desc": { "fr": "Amiante Examun Visuel APTVX" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_29 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#165812"
|
||||
},
|
||||
{
|
||||
"uuid": "DECHET",
|
||||
"desc": { "fr": "Dechet" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_30 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#682853"
|
||||
},
|
||||
{
|
||||
"uuid": "PBAPTVX",
|
||||
"desc": { "fr": "Plomb APTVX" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_31 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#051199"
|
||||
},
|
||||
{
|
||||
"uuid": "AMCTRLPERIO",
|
||||
"desc": { "fr": "Amiante Contrôl périodique" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_32 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#726364"
|
||||
},
|
||||
{
|
||||
"uuid": "AMEMPOUSS",
|
||||
"desc": { "fr": "Amiante Empoussièrement" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_33 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#053460"
|
||||
},
|
||||
{
|
||||
"uuid": "DEVINTERNE",
|
||||
"desc": { "fr": "Module developpement Interne" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_34 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#687134"
|
||||
},
|
||||
{
|
||||
"uuid": "HOMEINSPECT",
|
||||
"desc": { "fr": "Home Inspection" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_35 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#574776"
|
||||
},
|
||||
{
|
||||
"uuid": "4PTINSPECTION",
|
||||
"desc": { "fr": "4PT Inspection" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_36 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#729909"
|
||||
},
|
||||
{
|
||||
"uuid": "WINDMITIG",
|
||||
"desc": { "fr": "Wind Mitigation Inspection" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_37 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#646189"
|
||||
},
|
||||
{
|
||||
"uuid": "PBAVTVX",
|
||||
"desc": { "fr": "Plomb Av Tvx" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ diag_37 DIAG_38 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#971402"
|
||||
},
|
||||
{
|
||||
"uuid": "HAP",
|
||||
"desc": { "fr": "HAP" },
|
||||
"desclong": {
|
||||
"fr": "correspond au champ DIAG_39 dans le modèle de rapport Ordre de mission"
|
||||
},
|
||||
"color": "#577844"
|
||||
}
|
||||
]
|
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"uuid": "USER",
|
||||
"desc": {
|
||||
"fr": "USER - Utilisateur interne",
|
||||
"en": "USER - User profil"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Utilisateur interne à l'organisation",
|
||||
"en": "User profil"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "CLIENT",
|
||||
"desc": {
|
||||
"fr": "CLIENT - Utilisateur externe",
|
||||
"en": "CLIENT - User profil"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Utilisateur externe type client",
|
||||
"en": "User profil"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "MANAGER",
|
||||
"desc": {
|
||||
"fr": "MANAGER - Gestionnaire de données",
|
||||
"en": "MANAGER - Data Manager"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Gestionnaire de données avec des accès sensible",
|
||||
"en": "Data Manager with sensible data access"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "ADMIN",
|
||||
"desc": {
|
||||
"fr": "ADMIN - Admininstrateur",
|
||||
"en": "ADMIN - Admin profil"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Admininstrateur avec accès complet aux comptes",
|
||||
"en": "Admin profil with full access"
|
||||
}
|
||||
}
|
||||
]
|
17
asupsetup/data/domain/apixpress/referentials/dataManagement/data/role.json
Executable file
17
asupsetup/data/domain/apixpress/referentials/dataManagement/data/role.json
Executable file
@@ -0,0 +1,17 @@
|
||||
[
|
||||
{
|
||||
"uuid": "OTHER",
|
||||
"desclong": { "fr": "Autre", "en": "Other" },
|
||||
"desc": { "fr": "Aut.", "en": "Oth." }
|
||||
},
|
||||
{
|
||||
"uuid": "DIAG",
|
||||
"desclong": { "fr": "Diagnostiqueur", "en": "Diag" },
|
||||
"desc": { "fr": "Diag", "en": "DIAG" }
|
||||
},
|
||||
{
|
||||
"uuid": "GEST",
|
||||
"desclong": { "fr": "Gestion", "en": "Management" },
|
||||
"desc": { "fr": "Gest", "en": "Manag" }
|
||||
}
|
||||
]
|
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"commentaire": "Parametrage permettant de mettre à jour le cataloguecatBoutiquefixe.json",
|
||||
"nomcatalogue": "",
|
||||
"objet": "companies",
|
||||
"optioncatalogcsv": {
|
||||
"retln": "\n",
|
||||
"sep": ";",
|
||||
"seplevel": "__",
|
||||
"replacespecialcarCsv2Json": "[[/Semicolon/g,';']]",
|
||||
"replacespecialcarJson2Csv": "[[/;/g, 'Semicolon']]"
|
||||
},
|
||||
"removeforPublic": "",
|
||||
"templates": {
|
||||
"templateidintro": "",
|
||||
"menu": "",
|
||||
"header": "",
|
||||
"section": "",
|
||||
"filtre": "bdcfiltercateg",
|
||||
"card": "bdccard"
|
||||
},
|
||||
"vendeur": {
|
||||
"nom": "Commune d’Igny",
|
||||
"siret": "333 951 978 00050",
|
||||
"responsable": "Marie Faujas (Directrice de la Communication, Culture et Evènementiel)",
|
||||
"adressesociale": "23, avenue de la division Leclerc",
|
||||
"CP": "91430",
|
||||
"ville": "IGNY",
|
||||
"logo": "logo.png",
|
||||
"email": "mairie@igny.fr",
|
||||
"tel": "01 69 33 11 19",
|
||||
"telinter": "33169331119",
|
||||
"cartegmap": "",
|
||||
"reseauxociaux": [],
|
||||
"horaire": "",
|
||||
"horairedata": "",
|
||||
"IBAN": "",
|
||||
"tribunalRCS": "",
|
||||
"ScanKbis": "",
|
||||
"RIBSociete": "",
|
||||
"ScanIdcardResp1": "",
|
||||
"JustifDomicileResp1": "",
|
||||
"ScanIdcardResp2": "",
|
||||
"JustifDomicileResp2": ""
|
||||
},
|
||||
"hebergeur": {
|
||||
"nom": "SAS Need-Data",
|
||||
"adresse": "6 Avenue des Andes",
|
||||
"CP": "91940",
|
||||
"Ville": "Les Ulis",
|
||||
"site": "https://need-data.com"
|
||||
},
|
||||
"page": {
|
||||
"objettype": "page",
|
||||
"nom": "",
|
||||
"urlsite": "https://shop.igny.fr",
|
||||
"couleurprimaire": "",
|
||||
"couleursecondaire": "",
|
||||
"description": "",
|
||||
"metaauthor": "",
|
||||
"keywords": "",
|
||||
"ogtitle": "",
|
||||
"ogvignette": "",
|
||||
"title": "",
|
||||
"ordre": []
|
||||
},
|
||||
"header": {
|
||||
"objettype": "html",
|
||||
"photopleinepage": "",
|
||||
"TITREpage": "",
|
||||
"SSTITREpage": "",
|
||||
"inscriptionemailbouton": "S'inscrire",
|
||||
"TEXTpage": ""
|
||||
},
|
||||
"edito": {
|
||||
"objettype": "html",
|
||||
"tmpl": "sectionmaildigit",
|
||||
"contenthtml": "static/data/staticContentwebsite/edito.html"
|
||||
},
|
||||
"referencer": {
|
||||
"objettype": "html",
|
||||
"tmpl": "sectionmaildigit",
|
||||
"contenthtml": "static/data/staticContentwebsite/referencer.html"
|
||||
},
|
||||
"footer": {
|
||||
"objettype": "html",
|
||||
"tmpl": "sectionmaildigit",
|
||||
"classsection": "footer text-center bg-primary text-white",
|
||||
"contenthtml": "static/data/staticContentwebsite/footer.html"
|
||||
},
|
||||
"catalogue": {
|
||||
"objettype": "catalogueCards",
|
||||
"tmpl": "sectionmaildigit",
|
||||
"tpl": "",
|
||||
"titre": "",
|
||||
"sstitre": "",
|
||||
"text": "",
|
||||
"youtube": "",
|
||||
"youtubesmallscreen": "",
|
||||
"youtubebtn": "",
|
||||
"filtrecatalog": {
|
||||
"tpl": "bdcfiltercateg",
|
||||
"btnlist": true,
|
||||
"seleclist": false,
|
||||
"classbtn": "btn-outline-primary",
|
||||
"modalbutton": "video pour passer commande",
|
||||
"modalcontent": "",
|
||||
"modalcontentsmallscreen": "",
|
||||
"classcolfiltre": "text-left",
|
||||
"titrefiltre": "",
|
||||
"message": " <p><b>La livraison est offerte à partir de <s>6 cartons</s> 2 cartons (pendant la période de confinement)</b></p>",
|
||||
"categorie": "Nos Gammes",
|
||||
"btncategorie": "btn-outline-primary",
|
||||
"item": []
|
||||
},
|
||||
"cards": {
|
||||
"tpl": "bdccard",
|
||||
"devise": "€",
|
||||
"buttonajoutpanier": true,
|
||||
"showAvailibility": false,
|
||||
"masqueitemifnomoreavailable": true,
|
||||
"buttonBookwithemail": false,
|
||||
"buttonBookaddForm": true,
|
||||
"cardClass": "col-12",
|
||||
"btndesc": "Ajouter cette réservation",
|
||||
"cardbtn": "btn-primary",
|
||||
"objet": {}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"commentaire": "Spécification permettant d'importer et d'exporter en csv des companies, pour documentation voir gitlab",
|
||||
"object": "companies",
|
||||
"cardscsv": "compagniesIGNY.csv",
|
||||
"ASUPPcatalogPerso": "catalogueCommerceIGNY.csv",
|
||||
"optioncardscsv": {
|
||||
"retln": "\n",
|
||||
"sep": ";",
|
||||
"champs": ["UUID", "TYPE", "STATUT", "CATEGORIE", "TITRE", "SSTITRE", "KEYWORD", "MOTHTMLDUMAGASIN", "MOTTXTDUMAGASIN", "ADRESSE_PRO", "CP_PRO", "VILLE_PRO", "PHONE_PRO", "HORAIRESDESC", "HORAIREDATA", "URL", "FACEBOOK", "INSTA", "YOUTUBE", "LINKEDIN", "EMAIL_PRO", "IMG_VIGNETTE", "DATEOUVERTURE", "DATEFERMETURE", "HTML", "COMMENTPOSTTRT", "DATE_CREATE", "DATE_UPDATE"],
|
||||
"array": ["CATEGORIE", "PHONE_PRO", "EMAIL_PRO"],
|
||||
"arraysplitsep": ",",
|
||||
"numericfield": [],
|
||||
"search": "(fiche.UUID && fiche.UUID == data.UUID) || (fiche.EMAIL_PRO && utils.testinarray(fiche.EMAIL_PRO,data.EMAIL_PRO)) || (fiche.PHONE_PRO && utils.testinarray(fiche.PHONE_PRO,data.PHONE_PRO))",
|
||||
"merge": [],
|
||||
"replacespecialcarCsv2Json": "[[/Semicolon/g,';']]",
|
||||
"replacespecialcarJson2Csv": "[[/;/g, 'Semicolon']]"
|
||||
}
|
||||
}
|
134
asupsetup/data/domain/apixpress/referentials/dataManagement/json/menuAdmin.json
Executable file
134
asupsetup/data/domain/apixpress/referentials/dataManagement/json/menuAdmin.json
Executable file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"fr": {
|
||||
"menuleft": {
|
||||
"sbbrandlink": "app.html",
|
||||
"sbtitle": "YES",
|
||||
"sbgroupmenu": [{
|
||||
"groupheader": "Suivi",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Reporting",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.reporting.init()"
|
||||
}, {
|
||||
"name": "Test sous niveau",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.reporting.init()",
|
||||
"iditemmenus": "suivitest",
|
||||
"itemmenus": [{
|
||||
"name": "sousmenu",
|
||||
"actionclick": "pwa.reporting.init()"
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Admin",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Pagans",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.users.init()"
|
||||
}, {
|
||||
"name": "Referentiels",
|
||||
"icon": "sliders",
|
||||
"iditemmenus": "adminreferentiel",
|
||||
"itemmenus": [{
|
||||
"name": "Offre",
|
||||
"actionclick": "pwa.referential.setting('offre')"
|
||||
}, {
|
||||
"name": "return action",
|
||||
"actionclick": "pwa.referential.setting('returnaction')"
|
||||
}, {
|
||||
"name": "data",
|
||||
"actionclick": "pwa.referential.setting('data')"
|
||||
}, {
|
||||
"name": "json",
|
||||
"actionclick": "pwa.referential.setting('json')"
|
||||
}, {
|
||||
"name": "Objects",
|
||||
"actionclick": "pwa.referential.setting('object')"
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Teacher",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Evaluation",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.evaluation.init()"
|
||||
}, {
|
||||
"name": "ScheduleOnce",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.scheduleonce.init()"
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Operation",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Action Learner",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.actionlearner.init()"
|
||||
}, {
|
||||
"name": "Action teacher",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.actionteacher.init()"
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Marketing",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Gestion l'offre",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.offers.init()"
|
||||
}, {
|
||||
"name": "Action teacher",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.actionteacher.init()"
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Learner",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Mes evaluations",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.learner.init()"
|
||||
},
|
||||
{
|
||||
"name": "Actions learner",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.learner.action()"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
"menutop": {
|
||||
"withsearch": true,
|
||||
"searchtxt": "Recherche...",
|
||||
"withnotification": true,
|
||||
"notificationheader": "Vos notifications",
|
||||
"notificationfooter": "Voir toutes les notifications",
|
||||
"href": "?action=notification.view",
|
||||
"withmessage": false,
|
||||
"messageheader": "Vos messages non lus",
|
||||
"messagefooter": "Voir tous les messages",
|
||||
"avatarimg": "",
|
||||
"name": "",
|
||||
"menuprofil": [{
|
||||
"icon": "user",
|
||||
"desc": "Profile",
|
||||
"href": "?action=user.settings",
|
||||
"menubreaker": false
|
||||
},
|
||||
{
|
||||
"icon": "pie-chart",
|
||||
"desc": "Activity",
|
||||
"href": "?action=user.activity",
|
||||
"menubreaker": true
|
||||
},
|
||||
{
|
||||
"icon": "settings",
|
||||
"desc": "Log out",
|
||||
"href": "?action=userauth.logout",
|
||||
"menubreaker": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"en": {
|
||||
"menuleft": {},
|
||||
"menutop": {}
|
||||
}
|
||||
}
|
134
asupsetup/data/domain/apixpress/referentials/dataManagement/json/menuUser.json
Executable file
134
asupsetup/data/domain/apixpress/referentials/dataManagement/json/menuUser.json
Executable file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"fr": {
|
||||
"menuleft": {
|
||||
"sbbrandlink": "app.html",
|
||||
"sbtitle": "YES",
|
||||
"sbgroupmenu": [{
|
||||
"groupheader": "Suivi",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Reporting",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.reporting.init()"
|
||||
}, {
|
||||
"name": "Test sous niveau",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.reporting.init()",
|
||||
"iditemmenus": "suivitest",
|
||||
"itemmenus": [{
|
||||
"name": "sousmenu",
|
||||
"actionclick": "pwa.reporting.init()"
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Admin",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Pagans",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.users.init()"
|
||||
}, {
|
||||
"name": "Referentiels",
|
||||
"icon": "sliders",
|
||||
"iditemmenus": "adminreferentiel",
|
||||
"itemmenus": [{
|
||||
"name": "Offre",
|
||||
"actionclick": "pwa.referential.setting('offre')"
|
||||
}, {
|
||||
"name": "return action",
|
||||
"actionclick": "pwa.referential.setting('returnaction')"
|
||||
}, {
|
||||
"name": "data",
|
||||
"actionclick": "pwa.referential.setting('data')"
|
||||
}, {
|
||||
"name": "json",
|
||||
"actionclick": "pwa.referential.setting('json')"
|
||||
}, {
|
||||
"name": "Objects",
|
||||
"actionclick": "pwa.referential.setting('object')"
|
||||
}]
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Teacher",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Evaluation",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.evaluation.init()"
|
||||
}, {
|
||||
"name": "ScheduleOnce",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.scheduleonce.init()"
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Operation",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Action Learner",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.actionlearner.init()"
|
||||
}, {
|
||||
"name": "Action teacher",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.actionteacher.init()"
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Marketing",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Gestion l'offre",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.offers.init()"
|
||||
}, {
|
||||
"name": "Action teacher",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.actionteacher.init()"
|
||||
}]
|
||||
}, {
|
||||
"groupheader": "Learner",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Mes evaluations",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.learner.init()"
|
||||
},
|
||||
{
|
||||
"name": "Actions learner",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.learner.action()"
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
"menutop": {
|
||||
"withsearch": true,
|
||||
"searchtxt": "Recherche...",
|
||||
"withnotification": true,
|
||||
"notificationheader": "Vos notifications",
|
||||
"notificationfooter": "Voir toutes les notifications",
|
||||
"href": "?action=notification.view",
|
||||
"withmessage": false,
|
||||
"messageheader": "Vos messages non lus",
|
||||
"messagefooter": "Voir tous les messages",
|
||||
"avatarimg": "",
|
||||
"name": "",
|
||||
"menuprofil": [{
|
||||
"icon": "user",
|
||||
"desc": "Profile",
|
||||
"href": "?action=user.settings",
|
||||
"menubreaker": false
|
||||
},
|
||||
{
|
||||
"icon": "pie-chart",
|
||||
"desc": "Activity",
|
||||
"href": "?action=user.activity",
|
||||
"menubreaker": true
|
||||
},
|
||||
{
|
||||
"icon": "settings",
|
||||
"desc": "Log out",
|
||||
"href": "?action=userauth.logout",
|
||||
"menubreaker": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"en": {
|
||||
"menuleft": {},
|
||||
"menutop": {}
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"fr": {
|
||||
"titre": "Gestion des référentiels Administrateur",
|
||||
"submenutitre": "Liste",
|
||||
"btnsave": "Sauvegarder",
|
||||
"btndelete": "Supprimer",
|
||||
"btncopy": "Dupliquer",
|
||||
"copyplaceholder": "avec le nom de referentiel",
|
||||
"submenuitems": [{
|
||||
"active": "active",
|
||||
"groupinfo": "menuAdmin",
|
||||
"id": "referentialmenuadmin",
|
||||
"optionjsoneditor": {
|
||||
"theme": "tailwind"
|
||||
},
|
||||
"onclick": "pwa.referential.save(event,'referentialmenuadmin')"
|
||||
}, {
|
||||
"active": "",
|
||||
"id": "referentialmenuteacher",
|
||||
"optionjsoneditor": {},
|
||||
"groupinfo": "menuTeacher",
|
||||
"onclick": "pwa.referential.save(event,'referentialmenuteacher')"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "referentialusersetting",
|
||||
"groupinfo": "usersetting",
|
||||
"optionjsoneditor": {},
|
||||
"btnsave": "Sauvegarder",
|
||||
"onclick": "pwa.referential.save(event,'referentialmenuteacher')"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "referentialreferentialsettting",
|
||||
"optionjsoneditor": {},
|
||||
"groupinfo": "referentialsetting",
|
||||
"btnsave": "Sauvegarder",
|
||||
"onclick": "pwa.referential.save(event,'referentialmenuteacher')"
|
||||
}
|
||||
]
|
||||
},
|
||||
"en": {
|
||||
"titre": "Gestion des référentiels",
|
||||
"submenutitre": "Liste",
|
||||
"submenuitems": [{
|
||||
"active": "active",
|
||||
"groupinfo": "menuAdmin.json",
|
||||
"id": "referentialmenuadmin",
|
||||
"btnsave": "Sauvegarder",
|
||||
"onclick": "pwa.form.submit(event,'referentialmenuadmin',pwa.referentials.save)"
|
||||
}, {
|
||||
"active": "",
|
||||
"id": "referentialmenuTeacher",
|
||||
"groupinfo": "menuTeacher.json",
|
||||
"btnsave": "Sauvegarder",
|
||||
"onclick": "pwa.form.submit(event,'referentialmenuteacher',pwa.referentials.save)"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "referentialusersetting",
|
||||
"groupinfo": "usersetting.json"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "referentialreferentialsettting",
|
||||
"groupinfo": "referentialsetting.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
{"fr":{"niv1":1,"niv2":12222222},"en":{"niv1":1,"niv2":2}}
|
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"fr": {
|
||||
"titre": "Information",
|
||||
"submenutitre": "Vos paramétres",
|
||||
"submenuitems": [{
|
||||
"active": "active",
|
||||
"id": "usersettingaccount",
|
||||
"groupinfo": "Compte",
|
||||
"publicinfo": "Informations publiques",
|
||||
"pseudoplaceholder": "Votre pseudo",
|
||||
"pseudodesc": "Votre pseudo",
|
||||
"biographyplaceholder": "Quelque chose qui vous décrit",
|
||||
"biographydesc": "Biographie",
|
||||
"imguserupload": "Charger votre avatar",
|
||||
"infoimgavatar": "Pour un bon résultat, utiliser une image carrée de 128px au format .jpg",
|
||||
"btnsave": "Sauvegarder",
|
||||
"onclick": "pwa.form.submit(event,'userpublicinfo',pwa.user.save)"
|
||||
}, {
|
||||
"active": "",
|
||||
"id": "usersettingpassword",
|
||||
"groupinfo": "Mot de passe"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "usersettingprivacy",
|
||||
"groupinfo": "Protection des données"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "usersettingdelete",
|
||||
"groupinfo": "Supprimer son compte"
|
||||
}
|
||||
]
|
||||
},
|
||||
"en": {
|
||||
"titre": "Information",
|
||||
"submenutitre": "Vos paramétres",
|
||||
"submenuitems": [{
|
||||
"active": "active",
|
||||
"id": "usersettingaccount",
|
||||
"groupinfo": "Compte"
|
||||
|
||||
}, {
|
||||
"active": "",
|
||||
"id": "usersettingpassword",
|
||||
"groupinfo": "Mot de passe"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "usersettingprivacy",
|
||||
"groupinfo": "Protection des données"
|
||||
},
|
||||
{
|
||||
"active": "",
|
||||
"id": "usersettingdelete",
|
||||
"groupinfo": "Supprimer son compte"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"idfield": "uuid",
|
||||
"desc": { "fr": "identifiant de l'action", "en": "action id" },
|
||||
"multilangue": false,
|
||||
"required": true,
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "desc",
|
||||
"required": true,
|
||||
"multilangue": true,
|
||||
"desc": {
|
||||
"fr": "Description courte de cette modalité d'action",
|
||||
"en": "Short Modality Description"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
}
|
||||
]
|
@@ -0,0 +1,40 @@
|
||||
[
|
||||
{
|
||||
"idfield": "uuid",
|
||||
"desc": { "fr": "identifiant de l'objet", "en": "object id" },
|
||||
"multilangue": false,
|
||||
"required": true,
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "desc",
|
||||
"required": true,
|
||||
"multilangue": true,
|
||||
"desc": {
|
||||
"fr": "Description courte de cette modalité d'objet",
|
||||
"en": "Short Modality Description"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "desclong",
|
||||
"multilangue": true,
|
||||
"desc": {
|
||||
"fr": "Description de cette modalité d'objet",
|
||||
"en": "Modality Description"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "deschtml",
|
||||
"desc": {
|
||||
"fr": "Description en bloc html de cette modalité d'objet",
|
||||
"en": "Html description of this object"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionTextarea"
|
||||
}
|
||||
]
|
@@ -0,0 +1,41 @@
|
||||
[
|
||||
{
|
||||
"idfield": "uuid",
|
||||
"desc": { "fr": "identifiant de l'objet", "en": "object id" },
|
||||
"multilangue": false,
|
||||
"required": true,
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "desc",
|
||||
"required": true,
|
||||
"multilangue": false,
|
||||
"desc": {
|
||||
"fr": "Description courte de cette modalité d'objet",
|
||||
"en": "Short Modality Description"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "desclong",
|
||||
"multilangue": true,
|
||||
"desc": {
|
||||
"fr": "Description de cette modalité d'objet",
|
||||
"en": "Modality Description"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "deschtml",
|
||||
"multilangue": true,
|
||||
"desc": {
|
||||
"fr": "Description en bloc html de cette modalité d'objet",
|
||||
"en": "Html description of this object"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionTextarea"
|
||||
}
|
||||
]
|
@@ -0,0 +1,96 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"nouservisible": true,
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"check": ["required", "unique"],
|
||||
"desc": {
|
||||
"fr": "login",
|
||||
"en": "login"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "EMAIL",
|
||||
"desc": {
|
||||
"fr": "email",
|
||||
"en": "email"
|
||||
},
|
||||
"type": "email",
|
||||
"check": ["email", "unique"],
|
||||
"placeholder": "@",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "NAME",
|
||||
"desc": {
|
||||
"fr": "Nom",
|
||||
"en": "Name"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "NICKNAME",
|
||||
"desc": {
|
||||
"fr": "Prénom",
|
||||
"en": "Nickname"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "PSEUDO",
|
||||
"desc": {
|
||||
"fr": "pseudo",
|
||||
"en": "pseudo"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": {
|
||||
"fr": "Date de création",
|
||||
"en": "Create Date"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": {
|
||||
"fr": "Date mise à jour",
|
||||
"en": "Update date"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_LASTLOGIN",
|
||||
"desc": {
|
||||
"fr": "Date de derniére connexion",
|
||||
"en": "Last date login"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
}
|
||||
]
|
@@ -0,0 +1,54 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"nouservisible": true,
|
||||
"check": ["required"],
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"desc": {
|
||||
"fr": "Login",
|
||||
"en": "Login"
|
||||
},
|
||||
"multilangue": false,
|
||||
"required": true,
|
||||
"nouserupdate": true,
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "PASSWORD",
|
||||
"required": true,
|
||||
"desc": {
|
||||
"fr": "Mot de passe actuel",
|
||||
"en": "Current password"
|
||||
},
|
||||
"type": "password",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "PSNEW",
|
||||
"required": true,
|
||||
"check": ["password"],
|
||||
"desc": {
|
||||
"fr": "Nouveau mot de passe",
|
||||
"en": "New password"
|
||||
},
|
||||
"type": "password",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "PSWNEWBIS",
|
||||
"desc": {
|
||||
"fr": "Confirmation de mot de passe",
|
||||
"en": "Password confirmation"
|
||||
},
|
||||
"type": "password",
|
||||
"tpl": "questionInputVertical"
|
||||
}
|
||||
]
|
@@ -0,0 +1,96 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"nouservisible": true,
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"check": ["required", "unique"],
|
||||
"desc": {
|
||||
"fr": "login",
|
||||
"en": "login"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "EMAIL",
|
||||
"desc": {
|
||||
"fr": "email",
|
||||
"en": "email"
|
||||
},
|
||||
"type": "email",
|
||||
"check": ["email", "unique"],
|
||||
"placeholder": "@",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "NAME",
|
||||
"desc": {
|
||||
"fr": "Nom",
|
||||
"en": "Name"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "NICKNAME",
|
||||
"desc": {
|
||||
"fr": "Prénom",
|
||||
"en": "Nickname"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "PSEUDO",
|
||||
"desc": {
|
||||
"fr": "pseudo",
|
||||
"en": "pseudo"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": {
|
||||
"fr": "Date de création",
|
||||
"en": "Create Date"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": {
|
||||
"fr": "Date mise à jour",
|
||||
"en": "Update date"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_LASTLOGIN",
|
||||
"desc": {
|
||||
"fr": "Date de derniére connexion",
|
||||
"en": "Last date login"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
}
|
||||
]
|
108
asupsetup/data/domain/apixpress/referentials/dataManagement/object/item.json
Executable file
108
asupsetup/data/domain/apixpress/referentials/dataManagement/object/item.json
Executable file
@@ -0,0 +1,108 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"desc": {
|
||||
"fr": "identifiant de l'items",
|
||||
"en": "item id"
|
||||
},
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"questioncollecte": "questioninput"
|
||||
},
|
||||
{
|
||||
"idfield": "ETAT",
|
||||
"check": ["required"],
|
||||
"desc": {
|
||||
"fr": "Etat",
|
||||
"en": "Stat"
|
||||
},
|
||||
"type": "text",
|
||||
"questioncollect": "questionselect",
|
||||
"options": [{
|
||||
"uuid": "available",
|
||||
"desc": {
|
||||
"fr": "Disponible",
|
||||
"en": "Available"
|
||||
}
|
||||
},
|
||||
{
|
||||
"uuid": "unavailable",
|
||||
"desc": {
|
||||
"fr": "Indisponible",
|
||||
"en": "Unavailable"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"idfield": "DESC",
|
||||
"desc": {
|
||||
"fr": "Description courte",
|
||||
"en": "Short description"
|
||||
},
|
||||
"questioncollecte": "questioninput"
|
||||
},
|
||||
{
|
||||
"idfield": "DESCLONG",
|
||||
"desc": {
|
||||
"fr": "Descrition longue",
|
||||
"en": "Long description"
|
||||
},
|
||||
"questioncollecte": "questioninput"
|
||||
},
|
||||
{
|
||||
"idfield": "URL",
|
||||
"desc": {
|
||||
"fr": "URL",
|
||||
"en": "URL"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Lien vers une page de détail de l'items",
|
||||
"en": "Link to a web page that describe item"
|
||||
},
|
||||
"questioncollecte": "questioninput"
|
||||
},
|
||||
{
|
||||
"idfield": "PRICETTC",
|
||||
"desc": {
|
||||
"fr": "Prix TTC en cents",
|
||||
"en": "VAT Price in cents"
|
||||
},
|
||||
"check": ["isInt"],
|
||||
"desclong": {
|
||||
"fr": "Prix TTC exprimé en cents Prix x 100",
|
||||
"en": "Price including Tax x 100"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "CARACTERES",
|
||||
"desc": {
|
||||
"fr": "Objet contennat des caractéres pour mettre une mise en forme",
|
||||
"en": " Contain list of characteristics to style "
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Stockage d'information pour décricre des formulaires",
|
||||
"en": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": {
|
||||
"fr": "Date de création",
|
||||
"en": "Create Date"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"questioncollecte": "questioninput"
|
||||
}, {
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": {
|
||||
"fr": "Date mise à jour",
|
||||
"en": "Update date"
|
||||
},
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"questioncollecte": "questioninput"
|
||||
}
|
||||
]
|
@@ -0,0 +1,48 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"nouservisible": true,
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": "!(['ADMIN','MANAGER'].includes(contexte.profil))",
|
||||
"check": ["required"],
|
||||
"idfield": "appsdiagimmoprofil",
|
||||
"desc": {
|
||||
"fr": "Droits"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "USER ne peut voir que ses informations, MANAGER voit tout le monde et peut modifier les informations, ADMIN accede à tout et peut modifier "
|
||||
},
|
||||
"default": "USER",
|
||||
"values": "profile",
|
||||
"type": "text",
|
||||
"tpl": "questionSelect"
|
||||
},
|
||||
{
|
||||
"idfield": "role",
|
||||
"desc": {
|
||||
"fr": "Rôle",
|
||||
"en": "Role"
|
||||
},
|
||||
"default": "Autre",
|
||||
"values": "role",
|
||||
"tpl": "questionSelect"
|
||||
},
|
||||
{
|
||||
"idfield": "manypseudo",
|
||||
"desc": {
|
||||
"fr": "Liste des noms touvés dans liciel séparé par , "
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Permet de regrouper plusieurs noms sous ce login"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
}
|
||||
]
|
231
asupsetup/data/domain/apixpress/referentials/dataManagement/object/users.json
Executable file
231
asupsetup/data/domain/apixpress/referentials/dataManagement/object/users.json
Executable file
@@ -0,0 +1,231 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"nouserupdate": true,
|
||||
"nouservisible": true,
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Identifiant unique généré via UUID v4",
|
||||
"en": "unique Id from a UUID v4"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p> L'usage d'UUID v4 permet de générer un code unique sans centralisation, car il est basé sur un timestamp et une clé crypto ce qui donne un code du type 7d8291c0-e137-11e8-9f7b-1dc8e57bed33 </p>",
|
||||
"en": "<p> UUID v4 allow a client to generate a unique code without centralisation, base on a timestamp and a salt it looks like 7d8291c0-e137-11e8-9f7b-1dc8e57bed33</p>"
|
||||
},
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"tpl": "input"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"nouserupdate": true,
|
||||
"check": ["required", "unique"],
|
||||
"desc": {
|
||||
"fr": "login",
|
||||
"en": "login"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "input",
|
||||
"info": {
|
||||
"fr": "<p>Le login doit être unique sur une instance d'apxtrib.</p><p> Pour échanger en dehors d'une instance apxtrib on utilise la clé public du user ou pour un humain login@apxtrib.domain.xx avec le nom du domaine qui heberge l'instance</p><p> Ou encore login@domain.xx tout domain.xx utilisé pour heberger un espace web client /tribeid/www/</p>",
|
||||
"en": "<p>Login have to be unique into an apxtrib instance</p><p> To exchange outside of an apxtrib instance, we use PublicKey or login@apxtrib.domain.xx or login@domainclient.xx where domain.xx is a apxtrib name server on internet and domain.xx is a tribeid name where a /tribeid/www is available on the net.</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "BIOGRAPHY",
|
||||
"desc": {
|
||||
"fr": "Vous en quelques mots",
|
||||
"en": "Few words"
|
||||
},
|
||||
"placeholder": {
|
||||
"fr": "",
|
||||
"en": ""
|
||||
},
|
||||
"rows": 2,
|
||||
"tpl": "textarea"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "PUBLICKEY",
|
||||
"desc": {
|
||||
"fr": "Votre clé public pour ce compte",
|
||||
"en": "Your public key for this uuid"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p>Cette clé est générée par votre navigateur, garder précisuesement votre clé privée que seule vous connaissez. En cas de perte de cette clé tous vos actifs seront perdus.</p><p>Cette méthode nous permet de vous garantir un contrôle total décentralisé.</p>",
|
||||
"en": "<p>This key was generated by your browser, keep the private key related to this public key.</p><p>We garanty your total control by this way</p>."
|
||||
},
|
||||
"tpl": "textarea"
|
||||
},
|
||||
{
|
||||
"idfield": "IMGAVATAR",
|
||||
"tpl": "inputimg",
|
||||
"altimg": "image avatar",
|
||||
"classimg": "rounded-circle img-responsive mt-2",
|
||||
"width": 128,
|
||||
"height:"
|
||||
128,
|
||||
"classdivupload": "mt-2",
|
||||
"classbtn": "btn-primary",
|
||||
"desc": {
|
||||
"fr": "changer votre avatar",
|
||||
"en": "upload an avatar"
|
||||
},
|
||||
"info": {
|
||||
"fr": "Pour un meilleur rendu, une mage carré de 128pc en foat jpg",
|
||||
"en": "For best results, use an image at least 128px by 128px in .jpg format"
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
"idfield": "EMAIL",
|
||||
"desc": {
|
||||
"fr": "email",
|
||||
"en": "email"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "email",
|
||||
"check": ["emailadress", "unique"],
|
||||
"placeholder": {
|
||||
"fr": "#@",
|
||||
"en": "@"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "NAME",
|
||||
"desc": {
|
||||
"fr": "Nom",
|
||||
"en": "Name"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "NICKNAME",
|
||||
"desc": {
|
||||
"fr": "Prénom",
|
||||
"en": "Nickname"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "PSEUDO",
|
||||
"desc": {
|
||||
"fr": "pseudo",
|
||||
"en": "pseudo"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p>Nom avec lequel vous souhaitez qu'on vous reconnaisse sur l'instance de l'apxtrib </p><p>Attention ce nom n'est unique que sur une instance d'apxtrib. Un même speudo peut-être utilisé sur un autre serveur pour garantir l'identité vérifié pseudo@ domaine de rattachement.</p>",
|
||||
"en": "<p>Carrefull a pseudo is unique into an instance of apxtrib to be sure to contact the right person check pseudo@ domain</p>.<p> Pseudo can be changed that is not the case of login.</p>"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "ADDRESS1",
|
||||
"desc": {
|
||||
"fr": "Adresse",
|
||||
"en": "Address"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "1 chemin du paradis",
|
||||
"123 Main St"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "ADDRESS2",
|
||||
"desc": {
|
||||
"fr": "Adresse 2",
|
||||
"en": "Address 2"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "Appartement B",
|
||||
"Apt B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "CITY",
|
||||
"desc": {
|
||||
"fr": "Ville ",
|
||||
"en": "CITY"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
{
|
||||
"idfield": "ZIP",
|
||||
"desc": {
|
||||
"fr": "Code Postal",
|
||||
"en": "ZIP"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "COUNTRY",
|
||||
"desc": {
|
||||
"fr": "Pays",
|
||||
"en": "Country"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": {
|
||||
"fr": "Date de création",
|
||||
"en": "Create Date"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": {
|
||||
"fr": "Date mise à jour",
|
||||
"en": "Update date"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_LASTLOGIN",
|
||||
"desc": {
|
||||
"fr": "Date de derniére connexion",
|
||||
"en": "Last date login"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},
|
||||
{
|
||||
"idfield": "ACCESSRIGHTS",
|
||||
"nouserupdate": true,
|
||||
"desc": {
|
||||
"fr": "Vos droits d'accès",
|
||||
"en": "Your access rights"
|
||||
},
|
||||
"default": {
|
||||
"app": {},
|
||||
"data": {
|
||||
"tribeidname": {
|
||||
"users": "O"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tpl": "jsoneditor"
|
||||
}
|
||||
]
|
@@ -0,0 +1,231 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"nouserupdate": true,
|
||||
"nouservisible": true,
|
||||
"desc": {
|
||||
"fr": "identifiant utilisateur",
|
||||
"en": "user id"
|
||||
},
|
||||
"desclong": {
|
||||
"fr": "Identifiant unique généré via UUID v4",
|
||||
"en": "unique Id from a UUID v4"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p> L'usage d'UUID v4 permet de générer un code unique sans centralisation, car il est basé sur un timestamp et une clé crypto ce qui donne un code du type 7d8291c0-e137-11e8-9f7b-1dc8e57bed33 </p>",
|
||||
"en": "<p> UUID v4 allow a client to generate a unique code without centralisation, base on a timestamp and a salt it looks like 7d8291c0-e137-11e8-9f7b-1dc8e57bed33</p>"
|
||||
},
|
||||
"check": ["required", "unique"],
|
||||
"type": "text",
|
||||
"tpl": "input"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"nouserupdate": true,
|
||||
"check": ["required", "unique"],
|
||||
"desc": {
|
||||
"fr": "login",
|
||||
"en": "login"
|
||||
},
|
||||
"type": "text",
|
||||
"tpl": "input",
|
||||
"info": {
|
||||
"fr": "<p>Le login doit être unique sur une instance d'apxtrib.</p><p> Pour échanger en dehors d'une instance apxtrib on utilise la clé public du user ou pour un humain login@apxtrib.domain.xx avec le nom du domaine qui heberge l'instance</p><p> Ou encore login@domain.xx tout domain.xx utilisé pour heberger un espace web client /tribeid/www/</p>",
|
||||
"en": "<p>Login have to be unique into an apxtrib instance</p><p> To exchange outside of an apxtrib instance, we use PublicKey or login@apxtrib.domain.xx or login@domainclient.xx where domain.xx is a apxtrib name server on internet and domain.xx is a tribeid name where a /tribeid/www is available on the net.</p>"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "BIOGRAPHY",
|
||||
"desc": {
|
||||
"fr": "Vous en quelques mots",
|
||||
"en": "Few words"
|
||||
},
|
||||
"placeholder": {
|
||||
"fr": "",
|
||||
"en": ""
|
||||
},
|
||||
"rows": 2,
|
||||
"tpl": "textarea"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "PUBLICKEY",
|
||||
"desc": {
|
||||
"fr": "Votre clé public pour ce compte",
|
||||
"en": "Your public key for this uuid"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p>Cette clé est générée par votre navigateur, garder précisuesement votre clé privée que seule vous connaissez. En cas de perte de cette clé tous vos actifs seront perdus.</p><p>Cette méthode nous permet de vous garantir un contrôle total décentralisé.</p>",
|
||||
"en": "<p>This key was generated by your browser, keep the private key related to this public key.</p><p>We garanty your total control by this way</p>."
|
||||
},
|
||||
"tpl": "textarea"
|
||||
},
|
||||
{
|
||||
"idfield": "IMGAVATAR",
|
||||
"tpl": "inputimg",
|
||||
"altimg": "image avatar",
|
||||
"classimg": "rounded-circle img-responsive mt-2",
|
||||
"width": 128,
|
||||
"height:"
|
||||
128,
|
||||
"classdivupload": "mt-2",
|
||||
"classbtn": "btn-primary",
|
||||
"desc": {
|
||||
"fr": "changer votre avatar",
|
||||
"en": "upload an avatar"
|
||||
},
|
||||
"info": {
|
||||
"fr": "Pour un meilleur rendu, une mage carré de 128pc en foat jpg",
|
||||
"en": "For best results, use an image at least 128px by 128px in .jpg format"
|
||||
},
|
||||
|
||||
},
|
||||
{
|
||||
"idfield": "EMAIL",
|
||||
"desc": {
|
||||
"fr": "email",
|
||||
"en": "email"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "email",
|
||||
"check": ["emailadress", "unique"],
|
||||
"placeholder": {
|
||||
"fr": "#@",
|
||||
"en": "@"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "NAME",
|
||||
"desc": {
|
||||
"fr": "Nom",
|
||||
"en": "Name"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "NICKNAME",
|
||||
"desc": {
|
||||
"fr": "Prénom",
|
||||
"en": "Nickname"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "PSEUDO",
|
||||
"desc": {
|
||||
"fr": "pseudo",
|
||||
"en": "pseudo"
|
||||
},
|
||||
"info": {
|
||||
"fr": "<p>Nom avec lequel vous souhaitez qu'on vous reconnaisse sur l'instance de l'apxtrib </p><p>Attention ce nom n'est unique que sur une instance d'apxtrib. Un même speudo peut-être utilisé sur un autre serveur pour garantir l'identité vérifié pseudo@ domaine de rattachement.</p>",
|
||||
"en": "<p>Carrefull a pseudo is unique into an instance of apxtrib to be sure to contact the right person check pseudo@ domain</p>.<p> Pseudo can be changed that is not the case of login.</p>"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "ADDRESS1",
|
||||
"desc": {
|
||||
"fr": "Adresse",
|
||||
"en": "Address"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "1 chemin du paradis",
|
||||
"123 Main St"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "ADDRESS2",
|
||||
"desc": {
|
||||
"fr": "Adresse 2",
|
||||
"en": "Address 2"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text",
|
||||
"placeholder": {
|
||||
"fr": "Appartement B",
|
||||
"Apt B"
|
||||
}
|
||||
},
|
||||
{
|
||||
"idfield": "CITY",
|
||||
"desc": {
|
||||
"fr": "Ville ",
|
||||
"en": "CITY"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
|
||||
{
|
||||
"idfield": "ZIP",
|
||||
"desc": {
|
||||
"fr": "Code Postal",
|
||||
"en": "ZIP"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"idfield": "COUNTRY",
|
||||
"desc": {
|
||||
"fr": "Pays",
|
||||
"en": "Country"
|
||||
},
|
||||
"tpl": "input",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": {
|
||||
"fr": "Date de création",
|
||||
"en": "Create Date"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": {
|
||||
"fr": "Date mise à jour",
|
||||
"en": "Update date"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_LASTLOGIN",
|
||||
"desc": {
|
||||
"fr": "Date de derniére connexion",
|
||||
"en": "Last date login"
|
||||
},
|
||||
"tpl": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')"
|
||||
},
|
||||
{
|
||||
"idfield": "ACCESSRIGHTS",
|
||||
"nouserupdate": true,
|
||||
"desc": {
|
||||
"fr": "Vos droits d'accès",
|
||||
"en": "Your access rights"
|
||||
},
|
||||
"default": {
|
||||
"app": {},
|
||||
"data": {
|
||||
"tribeidname": {
|
||||
"users": "O"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tpl": "jsoneditor"
|
||||
}
|
||||
]
|
93
asupsetup/data/domain/apixpress/referentials/fr/object/users.json
Executable file
93
asupsetup/data/domain/apixpress/referentials/fr/object/users.json
Executable file
@@ -0,0 +1,93 @@
|
||||
[{
|
||||
"idfield": "UUID",
|
||||
"desc": "identifiant utilisateur",
|
||||
"nouservisible": true,
|
||||
"check": [
|
||||
"required",
|
||||
"unique"
|
||||
],
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "LOGIN",
|
||||
"check": [
|
||||
"required",
|
||||
"unique"
|
||||
],
|
||||
"desc": "login",
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "EMAIL",
|
||||
"desc": "email",
|
||||
"type": "email",
|
||||
"check": [
|
||||
"emailadress",
|
||||
"unique"
|
||||
],
|
||||
"placeholder": "@",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "NAME",
|
||||
"desc": "Nom",
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "NICKNAME",
|
||||
"desc": "Prénom",
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "PSEUDO",
|
||||
"desc": "pseudo",
|
||||
"type": "text",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_CREATE",
|
||||
"desc": "Date de création",
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_UPDATE",
|
||||
"desc": "Date mise à jour",
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"nouserupdate": true,
|
||||
"idfield": "DATE_LASTLOGIN",
|
||||
"desc": "Date de derniére connexion",
|
||||
"type": "date",
|
||||
"format": "YYYY-MM-DD",
|
||||
"default": "moment(new Date()).format('YYYY-MM-DD')",
|
||||
"tpl": "questionInputVertical"
|
||||
},
|
||||
{
|
||||
"idfield": "accessrights",
|
||||
"type": "json",
|
||||
"nouserupdate": true,
|
||||
"desc": "Vos droits d'accès",
|
||||
"default": {
|
||||
"app": {},
|
||||
"data": {
|
||||
"tribeidname": {
|
||||
"users": "O"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tpl": "jsoneditor"
|
||||
}
|
||||
]
|
3
asupsetup/data/domain/apixpress/users/searchindex/emails.json
Executable file
3
asupsetup/data/domain/apixpress/users/searchindex/emails.json
Executable file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"phc@ndda.fr": "admin"
|
||||
}
|
3
asupsetup/data/domain/apixpress/users/searchindex/logins.json
Executable file
3
asupsetup/data/domain/apixpress/users/searchindex/logins.json
Executable file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"admin": "admin"
|
||||
}
|
19
asupsetup/data/domain/apixpress/users/searchindex/uids.json
Executable file
19
asupsetup/data/domain/apixpress/users/searchindex/uids.json
Executable file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"admin": [
|
||||
"admin",
|
||||
"phc@ndda.fr",
|
||||
"$2b$10$hFV/33UixB3Cn.XzLIhmTeRYU2XThnxYuwCVIifwQ7v/yCtRLIsuq",
|
||||
{
|
||||
"app": {
|
||||
"apxtrib:webapp": "admin"
|
||||
},
|
||||
"data": {
|
||||
"apxtrib": {
|
||||
"users": "CRUDO",
|
||||
"referentials": "CRUDO"
|
||||
}
|
||||
}
|
||||
},
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHBpcmF0aW9uIjoiMjAyMS0wOS0wMlQxMjo0ODowMS41OTNaIiwiVVVJRCI6IjEyM2FiYyJ9.4daX42iXqoblGL0c1Ga-hs5tGIoJEuWBSKqCayA-qNk"
|
||||
]
|
||||
}
|
48
asupsetup/data/domain/apixpress/www/app/webapp/app_index_fr.html
Executable file
48
asupsetup/data/domain/apixpress/www/app/webapp/app_index_fr.html
Executable file
@@ -0,0 +1,48 @@
|
||||
|
||||
<html data-tribeid="apxtrib" data-website="webapp" data-nametpl="app" data-pagename="index_fr" data-pageneedauthentification="false" data-pageredirectforauthentification="fullscreen_auth" data-urlbackoffice="apxtrib.ndda.fr" lang="fr" data-env="prod" data-version="1640518264045">
|
||||
<head><!--head -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="author" content="">
|
||||
<meta name="email" content="">
|
||||
<meta name="keywords" content="">
|
||||
<title>Need-Data manager></title>
|
||||
<link rel="icon" type="image/png" href="static/img/icons/iconX74x74.png">
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<link rel="stylesheet" type="text/css" href="static/fonts/icofont/icofont.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/app/styles.css">
|
||||
<!-- /head-->
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper"> <!-- div class="wrapper" -->
|
||||
<nav id="sidebar" class="sidebar"></nav>
|
||||
<div class="main">
|
||||
<nav id ="navbar" class="navbar navbar-expand navbar-light navbar-bg"></nav>
|
||||
<main class="content">
|
||||
|
||||
<div class="container-fluid p-0" id="maincontent"> <!-- div id="maincontent" class="container-fluid p-0" -->
|
||||
|
||||
<p>Content when js is desactivated</p>
|
||||
|
||||
<!--/div-->
|
||||
</div>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="container-fluid">
|
||||
<div class="row text-muted">
|
||||
<div class="col-6 text-start">
|
||||
<p class="mb-0">
|
||||
<a href="" class="text-muted"><strong></strong></a> ©
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<ul class="list-inline">
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<!-- /div -->
|
||||
</div>
|
||||
<script src='js/simplebar.min.js'></script><script src='js/feather.min.js'></script><script src='js/bootstrap.js'></script><script src='js/axios.min.js'></script><script src='js/mustache.min.js'></script><script src='js/Checkjson.js'></script><script src='js/auth.js'></script><script src='js/state.js'></script><script src='js/main.js'></script><script src='js/notification.js'></script></body></html>
|
14213
asupsetup/data/domain/apixpress/www/app/webapp/css/app/styles.css
Executable file
14213
asupsetup/data/domain/apixpress/www/app/webapp/css/app/styles.css
Executable file
File diff suppressed because it is too large
Load Diff
14213
asupsetup/data/domain/apixpress/www/app/webapp/css/fullscreen/styles.css
Executable file
14213
asupsetup/data/domain/apixpress/www/app/webapp/css/fullscreen/styles.css
Executable file
File diff suppressed because it is too large
Load Diff
1
asupsetup/data/domain/apixpress/www/app/webapp/css/simplebar.min.css
vendored
Executable file
1
asupsetup/data/domain/apixpress/www/app/webapp/css/simplebar.min.css
vendored
Executable file
@@ -0,0 +1 @@
|
||||
[data-simplebar]{position:relative;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;left:0;top:0;bottom:0;right:0;width:auto!important;height:auto!important;z-index:0}.simplebar-offset{direction:inherit!important;box-sizing:inherit!important;resize:none!important;position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.simplebar-content-wrapper{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:auto;max-width:100%;max-height:100%;scrollbar-width:none;-ms-overflow-style:none}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{width:0;height:0}.simplebar-content:after,.simplebar-content:before{content:' ';display:table}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;height:100%;width:100%;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0}.simplebar-height-auto-observer{box-sizing:inherit;display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden}[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;user-select:none;-webkit-user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{position:absolute;left:0;right:0;min-height:10px}.simplebar-scrollbar:before{position:absolute;content:'';background:#000;border-radius:7px;left:2px;right:2px;opacity:0;transition:opacity .2s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;transition:opacity 0s linear}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-track.simplebar-vertical .simplebar-scrollbar:before{top:2px;bottom:2px}.simplebar-track.simplebar-horizontal{left:0;height:11px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before{height:100%;left:2px;right:2px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{right:auto;left:0;top:2px;height:7px;min-height:0;min-width:10px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{right:auto;left:0}.hs-dummy-scrollbar-size{direction:rtl;position:fixed;opacity:0;visibility:hidden;height:500px;width:500px;overflow-y:hidden;overflow-x:scroll}.simplebar-hide-scrollbar{position:fixed;left:0;visibility:hidden;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none}
|
169
asupsetup/data/domain/apixpress/www/app/webapp/fullscreen_auth_fr.html
Executable file
169
asupsetup/data/domain/apixpress/www/app/webapp/fullscreen_auth_fr.html
Executable file
@@ -0,0 +1,169 @@
|
||||
|
||||
<html data-tribeid="apxtrib" data-website="webapp" data-nametpl="fullscreen" data-pagename="auth_fr" data-pageneedauthentification="false" data-pageredirectforauthentification="fullscreen_auth" data-urlbackoffice="apxtrib.ndda.fr" lang="fr" data-env="prod" data-version="1640518263426">
|
||||
<head><!--head -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="author" content="">
|
||||
<meta name="email" content="">
|
||||
<meta name="keywords" content="">
|
||||
<title>apxtrib></title>
|
||||
<link rel="stylesheet" type="text/css" href="static/fonts/icofont/icofont.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="css/fullscreen/styles.css">
|
||||
<!-- /head-->
|
||||
</head>
|
||||
<body data-theme="dark" data-layout="fluid" data-sidebar-position="left" data-sidebar-layout="default">
|
||||
<main class="d-flex w-100 h-100"><!-- main class="d-flex w-100 h-100" -->
|
||||
<div class="container d-flex flex-column">
|
||||
<div class="row vh-100">
|
||||
<div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
|
||||
|
||||
<div class="d-table-cell align-middle"><!--div class="d-table-cell align-middle"-->
|
||||
<div id="signin">
|
||||
<div class="text-center mt-4">
|
||||
<h1 class="h2">Need-Data</h1>
|
||||
<p class="lead">
|
||||
Votre hébergement apxtrib en toute confidentialité.
|
||||
</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="m-sm-4">
|
||||
<div class="text-center">
|
||||
<img src="static/img/logo/ndda.png" alt="logo apxtrib" class="img-fluid" width="132" height="132" />
|
||||
</div>
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Identifiant</label>
|
||||
<input class="form-control form-control-lg" type="text" name="login" value="adminapxtrib" placeholder="Votre identifiant (login ou clé public)" />
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Mot de passe</label>
|
||||
<input class="form-control form-control-lg" type="password" name="password"
|
||||
value="Trze3aze!" placeholder="Mot de passe ou hash sur clé public" />
|
||||
<small>
|
||||
<a onclick="pwa.auth.route('#resetpsw');return false;">Mot de passe oublié?</a>
|
||||
</small>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="rememberme" name="rememberme" checked>
|
||||
<span class="form-check-label">
|
||||
Se souvenir de moi sur ce navigateur
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="text-center mt-3">
|
||||
<button
|
||||
class="btn btn-lg btn-primary"
|
||||
onclick="pwa.auth.login();return false;"
|
||||
data-msgok="Bienvenu dans votre espace."
|
||||
data-msgko="Désolé, vos identifiants ne sont pas valides! Au bout de 3 echecs, vous devrez attendre 1 minute entre chaque tentative."
|
||||
data-routeto="app_index_fr.html"
|
||||
>S'authentifier
|
||||
</button>
|
||||
<p class="msginfo"></p>
|
||||
</div>
|
||||
</form>
|
||||
<p class="text-center">
|
||||
<small>
|
||||
<a onclick="pwa.auth.route('#register');return false;" >Rejoindre un espace</a>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="resetpsw" class="d-none">
|
||||
<div class="text-center mt-4">
|
||||
<h1 class="h2">Mot de passe oublié</h1>
|
||||
<p class="lead">
|
||||
Indiquez votre email. Si vous n'avez pas indiqué d'email, vos données sont definitivement perdues, c'est le prix de votre anonymat.
|
||||
</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="m-sm-4">
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Email</label>
|
||||
<input class="form-control form-control-lg" type="email" name="email" placeholder="indiquez votre email">
|
||||
</div>
|
||||
<div class="text-center mt-3">
|
||||
<button
|
||||
onclick="pwa.auth.forget();return false;"
|
||||
data-msgok="Une email vous a été envoyé"
|
||||
data-msgko="Lien impossible à envoyer "
|
||||
class="btn btn-lg btn-primary">
|
||||
Recevoir un lien temporaire
|
||||
</button>
|
||||
<p class="msginfo"></p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="register" class="d-none">
|
||||
<div class="d-table-cell align-middle">
|
||||
<div class="text-center mt-4">
|
||||
<h1 class="h2">S'inscrire à votre communauté</h1>
|
||||
<p class="lead">
|
||||
Vous devez disposez du nom de la communauté qui vous invite à ouvrir un compte chez elle.<br> Pour créer une communauté, sur cet hébergement: <a href='mailto:contact@need-data.com'>contact@need-data.com</a>.<br> En savoir plus sur <a href='https://apxtrib.org/anonymat_avec_apixppress.html'>Anomymat & apxtrib</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="m-sm-4">
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Nom de communauté</label>
|
||||
<input class="form-control form-control-lg" type="text" name="company" placeholder="Nom communiqué par la personne qui vous invite.">
|
||||
</div>
|
||||
<div class="text-center mt-3">
|
||||
<button
|
||||
onclick="pwa.auth.autologin();return false;"
|
||||
class="btn btn-lg btn-primary">
|
||||
Génerer une paire<br> de clé public/privée
|
||||
</button>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Votre identifiant</label>
|
||||
<input class="form-control form-control-lg" type="text" name="login" placeholder="login ou clé public">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Mot de passe</label>
|
||||
<input class="form-control form-control-lg" type="password" name="password" placeholder="Mot de passe ou hash sur clé public">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Email (optionel)</label>
|
||||
<input class="form-control form-control-lg" type="email" name="email" placeholder="Sans email impossible de ré-initialiser son compte">
|
||||
</div>
|
||||
<div class="text-center mt-3">
|
||||
<button
|
||||
onclick="pwa.auth.register();return false;"
|
||||
data-msgok="Votre compte a bien été créé"
|
||||
data-msgko="Désolé impossible de créer le compte"
|
||||
class="btn btn-lg btn-primary">
|
||||
S'enregistrer
|
||||
</button>
|
||||
<p class="msginfo"></p>
|
||||
<p class="text-center">
|
||||
<small>
|
||||
<a onclick="pwa.auth.route('#signin');return false;" >S'authentifier</a>
|
||||
</small>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /div-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /main -->
|
||||
</main>
|
||||
<script src='js/simplebar.min.js'></script><script src='js/feather.min.js'></script><script src='js/bootstrap.js'></script><script src='js/axios.min.js'></script><script src='js/mustache.min.js'></script><script src='js/Checkjson.js'></script><script src='js/auth.js'></script><script src='js/state.js'></script><script src='js/main.js'></script><script src='js/notification.js'></script><script src='js/auth.js'></script></body></html>
|
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 );
|
1
asupsetup/data/domain/apixpress/www/app/webapp/manifest.json
Executable file
1
asupsetup/data/domain/apixpress/www/app/webapp/manifest.json
Executable file
@@ -0,0 +1 @@
|
||||
{"name":"apxtrib Need-Data","short_name":"apxtrib","start_url":"app_index_fr.html","background_color":"purple","description":"Webapp to manage an apxtrib server.","display":"fullscreen","icons":[{"src":"static/img/icons/iconX74x74.png","sizes":"74x74","type":"image/png"}]}
|
2
asupsetup/data/domain/apixpress/www/app/webapp/scss/main.scss
Executable file
2
asupsetup/data/domain/apixpress/www/app/webapp/scss/main.scss
Executable file
@@ -0,0 +1,2 @@
|
||||
/*Automaticaly generated do not change*/
|
||||
@import "../../src/scss/app.scss";
|
@@ -0,0 +1,34 @@
|
||||
pwa = pwa || {};
|
||||
pwa.main = pwa.main || {};
|
||||
pwa.main.tpldata = pwa.main.tpldata || {};
|
||||
pwa.main.tpl = pwa.main.tpl || {};
|
||||
//menu
|
||||
pwa.main.tpldata.sidebarAdminapxtrib = `static/components/adminapxtrib/sidebaradminapxtrib`;
|
||||
// Custom data in user lang
|
||||
|
||||
//tremplate to store
|
||||
pwa.main.tpl.adminapxtrib = 'static/components/adminapxtrib/adminapxtrib.mustache';
|
||||
pwa.main.tpl.adminapxtribsysinfo = 'static/components/adminapxtrib/adminapxtribsysinfo.mustache';
|
||||
pwa.main.tpl.adminapxtribactivity = 'static/components/adminapxtrib/adminapxtribactivity.mustache';
|
||||
|
||||
pwa.adminapxtrib = {};
|
||||
|
||||
pwa.adminapxtrib.init = () => {
|
||||
// Run back stuff to update data
|
||||
}
|
||||
pwa.adminapxtrib.sysinfoview = () => {
|
||||
const datasysinfo = {}; //request to get info and push them in template
|
||||
document.getElementById( 'maincontent' )
|
||||
.innerHTML = Mustache.render( pwa.state.data.tpl.adminapxtribsysinfo, datasysinfo );
|
||||
}
|
||||
pwa.adminapxtrib.activityview = () => {
|
||||
const dataactivity = {}; //request to get info and push them in template
|
||||
document.getElementById( 'maincontent' )
|
||||
.innerHTML = Mustache.render( pwa.state.data.tpl.adminapxtribactivity, dataactivity );
|
||||
}
|
||||
|
||||
pwa.adminapxtrib.tribeidview = () => {
|
||||
const datatribeid = {}; //request to get info and push them in template
|
||||
document.getElementById( 'maincontent' )
|
||||
.innerHTML = Mustache.render( pwa.state.data.tpl.adminapxtrib, datatribeid );
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,234 @@
|
||||
<div class="mb-3">
|
||||
<h1 class="h3 d-inline align-middle">tribeids</h1><a class="badge bg-primary ms-2" href="" target="_blank">120 <i class="fas fa-fw fa-external-link-alt"></i></a>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-8">
|
||||
<div class="card">
|
||||
<div class="card-header pb-0">
|
||||
<div class="card-actions float-end">
|
||||
<div class="dropdown position-relative">
|
||||
<a href="#" data-bs-toggle="dropdown" data-bs-display="static" aria-expanded="false" class="">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-more-horizontal align-middle"><circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle></svg>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="card-title mb-0">Tribes</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-striped" style="width:100%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th>Company</th>
|
||||
<th>Email</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Garrett Winters</td>
|
||||
<td>Good Guys</td>
|
||||
<td>garrett@winters.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Ashton Cox</td>
|
||||
<td>Levitz Furniture</td>
|
||||
<td>ashton@cox.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Sonya Frost</td>
|
||||
<td>Child World</td>
|
||||
<td>sonya@frost.com</td>
|
||||
<td><span class="badge bg-danger">Deleted</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Jena Gaines</td>
|
||||
<td>Helping Hand</td>
|
||||
<td>jena@gaines.com</td>
|
||||
<td><span class="badge bg-warning">Inactive</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-2.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Charde Marshall</td>
|
||||
<td>Price Savers</td>
|
||||
<td>charde@marshall.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-2.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Haley Kennedy</td>
|
||||
<td>Helping Hand</td>
|
||||
<td>haley@kennedy.com</td>
|
||||
<td><span class="badge bg-danger">Deleted</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-2.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Tatyana Fitzpatrick</td>
|
||||
<td>Good Guys</td>
|
||||
<td>tatyana@fitzpatrick.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-3.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Michael Silva</td>
|
||||
<td>Red Robin Stores</td>
|
||||
<td>michael@silva.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-3.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Angelica Ramos</td>
|
||||
<td>The Wiz</td>
|
||||
<td>angelica@ramos.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-4.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Jennifer Chang</td>
|
||||
<td>Helping Hand</td>
|
||||
<td>jennifer@chang.com</td>
|
||||
<td><span class="badge bg-warning">Inactive</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-4.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Brenden Wagner</td>
|
||||
<td>The Wiz</td>
|
||||
<td>brenden@wagner.com</td>
|
||||
<td><span class="badge bg-warning">Inactive</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-4.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Fiona Green</td>
|
||||
<td>The Sample</td>
|
||||
<td>fiona@green.com</td>
|
||||
<td><span class="badge bg-warning">Inactive</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-5.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Prescott Bartlett</td>
|
||||
<td>The Sample</td>
|
||||
<td>prescott@bartlett.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-5.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Gavin Cortez</td>
|
||||
<td>Red Robin Stores</td>
|
||||
<td>gavin@cortez.com</td>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="img/avatars/avatar-5.jpg" width="32" height="32" class="rounded-circle my-n1" alt="Avatar"></td>
|
||||
<td>Howard Hatfield</td>
|
||||
<td>Price Savers</td>
|
||||
<td>howard@hatfield.com</td>
|
||||
<td><span class="badge bg-warning">Inactive</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="card-actions float-end">
|
||||
<div class="dropdown position-relative">
|
||||
<a href="#" data-bs-toggle="dropdown" data-bs-display="static">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-more-horizontal align-middle"><circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle></svg>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
<a class="dropdown-item" href="#">Action</a>
|
||||
<a class="dropdown-item" href="#">Another action</a>
|
||||
<a class="dropdown-item" href="#">Something else here</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="card-title mb-0">Angelica Ramos</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-0">
|
||||
<div class="col-sm-3 col-xl-12 col-xxl-3 text-center">
|
||||
<img src="img/avatars/avatar-3.jpg" width="64" height="64" class="rounded-circle mt-2" alt="Angelica Ramos">
|
||||
</div>
|
||||
<div class="col-sm-9 col-xl-12 col-xxl-9">
|
||||
<strong>About me</strong>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore
|
||||
magna aliqua.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-sm mt-2 mb-4">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<td>Angelica Ramos</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Company</th>
|
||||
<td>The Wiz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td>angelica@ramos.com</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Phone</th>
|
||||
<td>+1234123123123</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<td><span class="badge bg-success">Active</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<strong>Activity</strong>
|
||||
|
||||
<ul class="timeline mt-2 mb-0">
|
||||
<li class="timeline-item">
|
||||
<strong>Signed out</strong>
|
||||
<span class="float-end text-muted text-sm">30m ago</span>
|
||||
<p>Nam pretium turpis et arcu. Duis arcu tortor, suscipit...</p>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<strong>Created invoice #1204</strong>
|
||||
<span class="float-end text-muted text-sm">2h ago</span>
|
||||
<p>Sed aliquam ultrices mauris. Integer ante arcu...</p>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<strong>Discarded invoice #1147</strong>
|
||||
<span class="float-end text-muted text-sm">3h ago</span>
|
||||
<p>Nam pretium turpis et arcu. Duis arcu tortor, suscipit...</p>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<strong>Signed in</strong>
|
||||
<span class="float-end text-muted text-sm">3h ago</span>
|
||||
<p>Curabitur ligula sapien, tincidunt non, euismod vitae...</p>
|
||||
</li>
|
||||
<li class="timeline-item">
|
||||
<strong>Signed up</strong>
|
||||
<span class="float-end text-muted text-sm">2d ago</span>
|
||||
<p>Sed aliquam ultrices mauris. Integer ante arcu...</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"groupheader": "Admin apxtrib",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Activité",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.adminapxtrib.init()",
|
||||
"iditemmenus": "adminxpress",
|
||||
"itemmenus": [{
|
||||
"name": "Info activités",
|
||||
"actionclick": "pwa.adminapxtrib.activityview()"
|
||||
},
|
||||
{
|
||||
"name": "Admin des tribeid",
|
||||
"actionclick": "pwa.adminapxtrib.tribeidview()"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"name": "System Info",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.adminapxtrib.sysinfoview()"
|
||||
}]
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"groupheader": "Admin apxtrib",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Tribes",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.tribeids.init()",
|
||||
"iditemmenus": "admintribeid",
|
||||
"itemmenus": [{
|
||||
"name": "Suivi des tribeid",
|
||||
"actionclick": "pwa.tribeids.tribeidactivity()"
|
||||
},
|
||||
{
|
||||
"name": "Admin des tribeid",
|
||||
"actionclick": "pwa.tribeids.settings()"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"name": "Suivi technique",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.tribeids.suivi()"
|
||||
}]
|
||||
}
|
@@ -0,0 +1,145 @@
|
||||
// app management sidebar and navbar
|
||||
/*
|
||||
Load into pwa.state.data.tpl[name] templates content
|
||||
appsidebarmenu.mustache side menu sbgroupmenu:[list of submenu]
|
||||
apptopbarmenu.mustache top menu menuprofil:[ list of submenu]
|
||||
apptopbarnotification.mustache show a dropdown list if withnotification is true
|
||||
apptopbarmessage.mustache show a dropdown list if withmessage is true
|
||||
|
||||
Load list of public data into pwa.state.data.menu
|
||||
sidebar
|
||||
topbar
|
||||
Then add specific menu in based on login list into
|
||||
pwa.state.data.login.user.ACCESSRIGHTS.app[tribeid:website]
|
||||
each name starting by sidebar is added into sidebar.subgroupmenu
|
||||
each name starting by topbar is added into topbar.menuprofil
|
||||
|
||||
|
||||
*/
|
||||
var pwa = pwa || {};
|
||||
pwa.app = {};
|
||||
pwa.app.init = async () => {
|
||||
//Load template in pwa.state.data.tpl
|
||||
console.log( 'app.init()' );
|
||||
const tpllist = {};
|
||||
[ 'appsidebarmenu', 'apptopbarmenu', 'apptopbarnotification', 'apptopbarmessage' ].forEach( c => {
|
||||
tpllist[ c ] = `static/components/appmesa/${c}.mustache`
|
||||
} );
|
||||
// add other generic public template, carefull name have to be unique
|
||||
tpllist[ 'notiflist' ] = `static/components/notification/notiflist.mustache`;
|
||||
// tpllist[ 'msglist' ] = `static/components/messagerie/msglist.mustache`;
|
||||
|
||||
tpllist[ 'verticaltab' ] = `static/components/verticaltab/verticaltab.mustache`;
|
||||
|
||||
await pwa.state.loadfile( tpllist, "tpl" );
|
||||
await pwa.app.getcontent();
|
||||
//get menu depending of user profile: tribeid:app
|
||||
};
|
||||
pwa.app.getcontent = async () => {
|
||||
const menubase = {};
|
||||
let menu = [ 'sidebar', 'topbar' ];
|
||||
//check if authentify and add specific menu
|
||||
if( pwa.state.data.login && pwa.state.data.login.isAuthenticated ) {
|
||||
//Get personnal menu user.ACCESSRIGHTS={app:{ "tribeid:website":{sidebar,top}
|
||||
const appname = `${pwa.state.data.ctx.tribeid}:${pwa.state.data.ctx.website}`
|
||||
//console.log( 'with ', appname )
|
||||
menu = menu.concat( pwa.state.data.login.user.ACCESSRIGHTS.app[ appname ] )
|
||||
}
|
||||
//console.log( 'update pwa.state.data.menu with ', menu )
|
||||
menu.forEach( c => { menubase[ c ] = `static/data/${c}_${pwa.state.data.ctx.lang}.json` } );
|
||||
await pwa.state.loadfile( menubase, 'menu' );
|
||||
pwa.app.loadsidebarmenu( menu.filter( m => m.includes( 'sidebar' ) ) )
|
||||
pwa.app.loadtopmenu( menu.filter( m => m.includes( 'topbar' ) ) );
|
||||
//active les icones svg de feather
|
||||
feather.replace();
|
||||
//active scroll presentation + sidebar animation
|
||||
pwa.app.simplebar();
|
||||
pwa.app.clickactive();
|
||||
}
|
||||
pwa.app.loadsidebarmenu = ( list ) => {
|
||||
//console.log( 'list de menu sidebar', list )
|
||||
const data = pwa.state.data.menu.sidebar
|
||||
for( let m of list ) {
|
||||
if( m != 'sidebar' ) {
|
||||
console.log( m )
|
||||
data.sbgroupmenu = data.sbgroupmenu.concat( pwa.state.data.menu[ m ] )
|
||||
}
|
||||
}
|
||||
//console.log( data )
|
||||
document.querySelector( "#sidebar" )
|
||||
.innerHTML = Mustache.render( pwa.state.data.tpl.appsidebarmenu, data )
|
||||
}
|
||||
pwa.app.loadtopmenu = ( list ) => {
|
||||
const data = pwa.state.data.menu.topbar
|
||||
for( let m of list ) {
|
||||
if( m != 'topbar' ) {
|
||||
data.menuprofil = data.menuprofil.concat( pwa.state.data.menu[ m ] )
|
||||
}
|
||||
}
|
||||
//update date from login if authenticated
|
||||
if( pwa.state.data.login.isAuthenticated ) {
|
||||
//remove the login item from menuprofil
|
||||
data.menuprofil.shift();
|
||||
data.name = pwa.state.data.login.user.NAME;
|
||||
data.avatarimg = pwa.state.data.login.user.AVATARIMG;
|
||||
// get notification / message if exist
|
||||
//const notifsrc= `${pwa.urlbackauth}/Tribes/logs/`;
|
||||
if( pwa.state.data.menu.topbar.withnotification ) {
|
||||
pwa.notification.update();
|
||||
}
|
||||
if( pwa.state.data.menu.topbar.withmessage ) {
|
||||
//pwa.message.update( );
|
||||
}
|
||||
}
|
||||
//console.log( 'topbar data', data.menuprofil );
|
||||
document.querySelector( "#navbar" )
|
||||
.innerHTML = Mustache.render( pwa.state.data.tpl.apptopbarmenu, data )
|
||||
}
|
||||
pwa.app.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" ) );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
}
|
||||
pwa.app.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();
|
||||
}
|
||||
} )
|
||||
};
|
@@ -0,0 +1,5 @@
|
||||
<!-- div id="maincontent" class="container-fluid p-0" -->
|
||||
|
||||
<p>Content when js is desactivated</p>
|
||||
|
||||
<!--/div-->
|
@@ -0,0 +1,29 @@
|
||||
<!-- div class="wrapper" -->
|
||||
<nav id="sidebar" class="sidebar"></nav>
|
||||
<div class="main">
|
||||
<nav id ="navbar" class="navbar {{navbarclass}}"></nav>
|
||||
<main class="content">
|
||||
<importhtml></importhtml>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="container-fluid">
|
||||
<div class="row text-muted">
|
||||
<div class="col-6 text-start">
|
||||
<p class="mb-0">
|
||||
<a href="{{{urlapxtrib}}}" class="text-muted"><strong>{{claim}}</strong></a> ©
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<ul class="list-inline">
|
||||
{{#links}}
|
||||
<li class="list-inline-item">
|
||||
<a class="text-muted" href="{{{url}}}">{{{desc}}}</a>
|
||||
</li>
|
||||
{{/links}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<!-- /div -->
|
@@ -0,0 +1,33 @@
|
||||
<div class="sidebar-content js-simplebar">
|
||||
<a class="sidebar-brand" href="{{sbbrandlink}}">
|
||||
<span class="align-middle">{{{sbtitle}}}</span>
|
||||
</a>
|
||||
{{#sbgroupmenu}}
|
||||
<ul class="sidebar-nav">
|
||||
<li class="sidebar-header">
|
||||
{{{groupheader}}}
|
||||
</li>
|
||||
{{#sbssgroupmenu}}
|
||||
<li class="sidebar-item ">
|
||||
{{^iditemmenus}}
|
||||
<a class="sidebar-link" onclick="{{actionclick}}">
|
||||
<i class="align-middle" data-feather="{{icon}}"></i>
|
||||
<span class="align-middle">{{name}}</span>
|
||||
</a>
|
||||
{{/iditemmenus}}
|
||||
{{#iditemmenus}}
|
||||
<a data-bs-target="#{{iditemmenus}}" data-bs-toggle="collapse" class="sidebar-link collapsed">
|
||||
<i class="align-middle" data-feather="{{icon}}"></i>
|
||||
<span class="align-middle">{{name}}</span>
|
||||
</a>
|
||||
<ul id="{{iditemmenus}}" class="sidebar-dropdown list-unstyled collapse " data-bs-parent="#sidebar">
|
||||
{{#itemmenus}}
|
||||
<li class="sidebar-item"><a class="sidebar-link" onclick="{{actionclick}}">{{name}}</a></li>
|
||||
{{/itemmenus}}
|
||||
</ul>
|
||||
{{/iditemmenus}}
|
||||
</li>
|
||||
{{/sbssgroupmenu}}
|
||||
</ul>
|
||||
{{/sbgroupmenu}}
|
||||
</div>
|
@@ -0,0 +1,61 @@
|
||||
<a class="sidebar-toggle d-flex">
|
||||
<i class="hamburger align-self-center"></i>
|
||||
</a>
|
||||
{{#withsearch}}
|
||||
<form class="d-none d-sm-inline-block">
|
||||
<div class="input-group input-group-navbar">
|
||||
<input type="text" id="globalsearch" class="form-control" placeholder="{{{searchtxt}}}" aria-label="Search">
|
||||
<button class="btn" type="button" onclick="pwa.search.req('globalsearch');return false;" cancelhref="?action=search.req&idsearchtxt=globalsearch">
|
||||
<i class="align-middle" data-feather="search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{{/withsearch}}
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul id="topbarmenuright" class="navbar-nav navbar-align">
|
||||
{{#withnotif}}
|
||||
<li id="notiflist" class="nav-item dropdown">
|
||||
</li>
|
||||
{{/withnotif}}
|
||||
{{#withmessage}}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-icon dropdown-toggle" href="#" id="messagesDropdown" data-bs-toggle="dropdown">
|
||||
<div class="position-relative">
|
||||
<i class="align-middle" data-feather="message-square"></i>
|
||||
<span class="indicator">0</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-end py-0" aria-labelledby="messagesDropdown">
|
||||
<div class="dropdown-menu-header">
|
||||
<div class="position-relative">
|
||||
{{{messageheader}}}
|
||||
</div>
|
||||
</div>
|
||||
<div id="topmenumessages" class="list-group">
|
||||
</div>
|
||||
<div class="dropdown-menu-footer">
|
||||
<a href="#" class="text-muted">{{{messagefooter}}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{/withmessage}}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-icon dropdown-toggle d-inline-block d-sm-none" href="#" data-bs-toggle="dropdown">
|
||||
<i class="align-middle" data-feather="settings"></i>
|
||||
</a>
|
||||
<a class="nav-link dropdown-toggle d-none d-sm-inline-block" href="#" data-bs-toggle="dropdown">
|
||||
<img src="{{avatarimg}}" class="avatar img-fluid rounded me-1" alt="avatar" /> <span class="text-dark">{{name}}</span>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-end">
|
||||
{{#menuprofil}}
|
||||
<a class="dropdown-item" href="{{{href}}}">
|
||||
<i class="align-middle me-1" data-feather="{{{icon}}}"></i> {{{desc}}}
|
||||
</a>
|
||||
{{#menubreaker}}
|
||||
<div class="dropdown-divider"></div>
|
||||
{{/menubreaker}}
|
||||
{{/menuprofil}}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
@@ -0,0 +1,16 @@
|
||||
<div class="list-group">
|
||||
{{#messages}}
|
||||
<a href="#" class="list-group-item">
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-2">
|
||||
<img src="{{{imgsrc}}}" class="avatar img-fluid rounded-circle" alt="Vanessa Tucker">
|
||||
</div>
|
||||
<div class="col-10">
|
||||
<div class="text-dark">{{{name}}}</div>
|
||||
<div class="text-muted small mt-1">{{{subject}}}.</div>
|
||||
<div class="text-muted small mt-1">{{{elapse}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{{/messages}}
|
||||
</div>
|
@@ -0,0 +1,16 @@
|
||||
<div class="list-group">
|
||||
{{#notifications}}
|
||||
<a href="#" class="list-group-item">
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-2">
|
||||
<i class="{{{classicon}}}" data-feather="{{{icon}}}"></i>
|
||||
</div>
|
||||
<div class="col-10">
|
||||
<div class="text-dark">{{{titre}}}</div>
|
||||
<div class="text-muted small mt-1">{{{description}}}.</div>
|
||||
<div class="text-muted small mt-1">{{{elapse}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{{/notifications}}
|
||||
</div>
|
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"navbarclass": "navbar-expand navbar-light navbar-bg",
|
||||
"footer": {
|
||||
"urlapxtrib": "https://apxtrib.org",
|
||||
"claim": "apxtrib made with love for freedom",
|
||||
"links": [{
|
||||
"url": "#",
|
||||
"desc": "Support"
|
||||
}, {
|
||||
"url": "#",
|
||||
"desc": "Privacy"
|
||||
}]
|
||||
}
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"groupheader": "Mon espace client",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Espace web",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.spaceweb.init()",
|
||||
"iditemmenus": "clentidspace",
|
||||
"itemmenus": [{
|
||||
"name": "Mon espace web",
|
||||
"actionclick": "pwa.spaceweb.myfile()"
|
||||
},
|
||||
{
|
||||
"name": "Mes utilisateurs",
|
||||
"actionclick": "pwa.spaceweb.users()"
|
||||
},
|
||||
{
|
||||
"name": "Mes contenus",
|
||||
"actionclick": "pwa.spaceweb.content()"
|
||||
},
|
||||
{
|
||||
"name": "Mes plugins",
|
||||
"actionclick": "pwa.spaceweb.plugins()"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"name": "Referentiels",
|
||||
"icon": "sliders",
|
||||
"iditemmenus": "adminreferentiel",
|
||||
"itemmenus": [{
|
||||
"name": "Force update",
|
||||
"actionclick": "pwa.referential.forceupdate()"
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"actionclick": "pwa.referential.setting('data')"
|
||||
},
|
||||
{
|
||||
"name": "json",
|
||||
"actionclick": "pwa.referential.setting('json')"
|
||||
},
|
||||
{
|
||||
"name": "Objects",
|
||||
"actionclick": "pwa.referential.setting('object')"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"sbbrandlink": "app_index_fr.html",
|
||||
"sbtitle": "Need-Data",
|
||||
"sbgroupmenu": [{
|
||||
"groupheader": "apxtrib",
|
||||
"sbssgroupmenu": [{
|
||||
"name": "Les news",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.news.init()"
|
||||
},
|
||||
{
|
||||
"name": "Reporting",
|
||||
"icon": "sliders",
|
||||
"actionclick": "pwa.reporting.init()",
|
||||
"iditemmenus": "reportingapxtrib",
|
||||
"itemmenus": [{
|
||||
"name": "",
|
||||
"actionclick": "pwa.reporting.init()"
|
||||
}]
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"withsearch": true,
|
||||
"searchtxt": "Recherche...",
|
||||
"withnotification": true,
|
||||
"notificationheader": "Vos notifications",
|
||||
"notificationfooter": "Voir toutes les notifications",
|
||||
"href": "?action=notification.view",
|
||||
"withmessage": true,
|
||||
"messageheader": "Vos messages non lus",
|
||||
"messagefooter": "Voir tous les messages",
|
||||
"avatarimg": "static/img/avataranonymous.png",
|
||||
"name": "Login",
|
||||
"menuprofil": []
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
var pwa = pwa || {};
|
||||
/*
|
||||
Manage message
|
||||
|
||||
____________________
|
||||
|
||||
*/
|
||||
//--##
|
||||
pwa.message = {};
|
||||
|
||||
pwa.message.update = ( urlmsg ) => {
|
||||
console.log( 'get message update' );
|
||||
axios.get( urlmsg, { headers: pwa.state.data.headers } )
|
||||
.then( rep => {
|
||||
const tpl = document.getElementById( "app_menutopmessage" );
|
||||
document.getElementById( "topmenumessages" )
|
||||
.innerHTML = Mustache.render( tpl.innerHTML, { messagess: rep.data } );
|
||||
} )
|
||||
.catch( err => {
|
||||
console.log( `Err pwa.notification.update data from ${urlmsg}`, err );
|
||||
} );
|
||||
|
||||
};
|
||||
/*pwa
|
||||
.state
|
||||
.ready( pwa.notification.update( 'static/data/staticContentwebsite/notification.json' ) );
|
||||
*/
|
@@ -0,0 +1,271 @@
|
||||
"use strict";
|
||||
var pwa = pwa || {};
|
||||
/*
|
||||
Manage referentials for a tribeid
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
//--##
|
||||
pwa.referential = {};
|
||||
pwa.referential.content = `
|
||||
<div class="row gap-20 masonry pos-r">
|
||||
<div class="blocA masonry-item col-md-6">
|
||||
<div class="bgc-white p-20 bd">
|
||||
<h6 class="c-grey-900">Affiche json</h6>
|
||||
<div id="jsoneditor" class="jsoneditor">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="blocB masonry-item col-md-6">
|
||||
<div class="bgc-white p-20 bd">
|
||||
<h6 class="c-grey-900">Changer son mot de passe</h6>
|
||||
<div class="formdata">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
pwa.referential.set = async ( sourceref ) => {
|
||||
/*
|
||||
@sourceref app (recupere le referentiel de l'application)
|
||||
workon (recupere le referentiel du client id sur lequel on travail state.data.headers[X-workOn])
|
||||
On alimente le referentiel ds localStorage
|
||||
state.app.referentials = {menu:}
|
||||
*/
|
||||
console.groupCollapsed( 'Load pwa.referential.set with ', sourceref )
|
||||
//let reftoload;
|
||||
let savexworkon;
|
||||
if( sourceref == "app" ) {
|
||||
//reftoload = pwa.state.data.app.referentials
|
||||
// affecte le menu en fonction du profil
|
||||
console.assert( pwa.state.data.app.profil && pwa.state.data.app.profil[ pwa.state.data.userlogin.ACCESSRIGHTS.app[ `${pwa.tribeid}:${pwa.PROJET}` ] ], `profil de l app ${pwa.tribeid}:${pwa.PROJET} n'existe pas pour le user dans userlogin.ACCESSRIGHTS.app , verifier qu'on a bien pour cette app un menu correspondant` );
|
||||
const menuapp = pwa.state.data.app.profil[ pwa.state.data.userlogin.ACCESSRIGHTS.app[ `${pwa.tribeid}:${pwa.PROJET}` ] ].menu;
|
||||
if( !pwa.state.data.app.referentials.json[ menuapp ] ) {
|
||||
//on ajoute ce menu avec une version à O pour forcer sa mise à jour
|
||||
pwa.state.data.app.referentials.json[ menuapp ] = { version: 0 }
|
||||
}
|
||||
//set xworkon on tribeid where app is stored
|
||||
savexworkon = pwa.state.data.headers[ 'X-WorkOn' ];
|
||||
pwa.state.data.headers[ 'X-WorkOn' ] = pwa.tribeid
|
||||
}
|
||||
/* else if(sourceref == "xworkon") {
|
||||
// on recupere le referentiel utile pour clientcon.json du xworkon pour le projet
|
||||
reftoload = pwa.state.data.xworkon.referentials
|
||||
}*/
|
||||
// recupere les versions du clientconf.json
|
||||
const clientconfref = await axios.get( `${pwa.urlbackauth}/referentials/clientconf/referentials`, { headers: pwa.state.data.headers } );
|
||||
console.debug( 'clientconfref', clientconfref );
|
||||
for( const o of [ 'object', 'json', 'data' ] ) {
|
||||
console.debug( o )
|
||||
//update by adding or upgraded version if in dev or in prod and pwa.state.data[sourceref].referentials[type=object|json|data][nomref].version is upper than the local one
|
||||
// Take care app is load first with previous referential then need to refresh app to use the new version.
|
||||
if( !clientconfref.data.referentials[ o ] ) {
|
||||
clientconfref.data.referentials[ o ] = {};
|
||||
}
|
||||
//Warning do not use foreach in async cause foreach is not sync
|
||||
for( const r of Object.keys( clientconfref.data.referentials[ o ] ) ) {
|
||||
console.debug( r )
|
||||
if( !pwa.state.data.app.referentials[ o ][ r ] ) {
|
||||
// New referential added need to reload app to refresh app
|
||||
pwa.state.data.app.referentials[ o ][ r ] = { version: -1 };
|
||||
}
|
||||
if( pwa.MODE_ENV == "dev" || !( pwa.state.data.app.referentials[ o ][ r ].version == clientconfref[ o ][ r ].version ) ) {
|
||||
// alors nouvelle version à mettre à jour en dev on le fait systematiquement
|
||||
console.log( `${pwa.urlbackauth}/referentials/content/${o}/${r}`, pwa.state.data.headers );
|
||||
const dataref = await axios.get( `${pwa.urlbackauth}/referentials/content/${o}/${r}`, { headers: pwa.state.data.headers } )
|
||||
if( dataref.status == 200 ) {
|
||||
console.log( `${o} - ${r}`, dataref.data )
|
||||
pwa.state.data[ sourceref ].referentials[ o ][ r ] = dataref.data;
|
||||
pwa.state.save()
|
||||
} else {
|
||||
console.log( `ERREUR de recuperation de referentiel ${o} ${r}` )
|
||||
}
|
||||
}
|
||||
}
|
||||
// we remove from local if nomref disapear of app clientconfref.data.referential
|
||||
Object.keys( pwa.state.data[ sourceref ].referentials[ o ] )
|
||||
.forEach( r => {
|
||||
if( !clientconfref.data.referentials[ o ] ) {
|
||||
delete pwa.state.data[ sourceref ].referentials[ o ];
|
||||
pwa.state.save();
|
||||
}
|
||||
} )
|
||||
};
|
||||
if( sourceref == "app" ) {
|
||||
// on remet le xworkon en cours
|
||||
pwa.state.data.headers[ 'X-WorkOn' ] = savexworkon;
|
||||
}
|
||||
console.groupEnd();
|
||||
};
|
||||
pwa.referential.forceupdate = () => {
|
||||
axios.get( `${pwa.urlbackauth}/referentials/updatefull`, {
|
||||
headers: pwa.state.data.headers
|
||||
} )
|
||||
.then( data => {
|
||||
alert( data.status )
|
||||
} )
|
||||
}
|
||||
// GUI to manage referential
|
||||
pwa.referential.setting = async ( objecttype ) => {
|
||||
// Convert location.search to get objecttype
|
||||
const urlpar = new URLSearchParams( objecttype );
|
||||
objecttype = ( urlpar.get( 'objecttype' ) ) ? urlpar.get( 'objecttype' ) : objecttype;
|
||||
|
||||
const tpleditor = `
|
||||
<div class="input-group mb-3" data-idref="{{id}}">
|
||||
<button class="btn btn-outline-primary actionobject save" >
|
||||
{{{btnsave}}}
|
||||
</button>
|
||||
<button class="btn btn-outline-primary actionobject delete" >
|
||||
{{{btndelete}}}
|
||||
</button>
|
||||
<button class=" btn btn-outline-primary actionobject copy" >
|
||||
{{{btncopy}}}
|
||||
</button>
|
||||
<input type="text" class="form-control nameas" placeholder="{{{copyplaceholder}}}" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="jsoneditor mb-3"></div>
|
||||
`;
|
||||
|
||||
console.groupCollapsed( `load referentials setting for ${objecttype}` );
|
||||
//reinit submenuitems
|
||||
pwa.state.data.app.referentials.json.referentialsetting.submenuitems = [];
|
||||
//Requested directly the back warranty to get always the last updated referential
|
||||
const data = await axios.get( `${pwa.urlbackauth}/referentials/contentlist/${objecttype}`, {
|
||||
headers: pwa.state.data.headers
|
||||
} );
|
||||
console.log( "Liste des referentiels ", data.data )
|
||||
let reqref = []
|
||||
let ref = []
|
||||
//init a temporary (opposite od state that is save) data to work on referential (each time referentials/object is load this variable is refresh)
|
||||
pwa.tmp = {};
|
||||
data.data.forEach( o => {
|
||||
reqref.push( axios.get( `${pwa.urlbackauth}/referentials/contentfull/${objecttype}/${o}`, {
|
||||
headers: pwa.state.data.headers
|
||||
} ) )
|
||||
ref.push( o );
|
||||
} );
|
||||
axios.all( reqref )
|
||||
.then( axios.spread( ( ...rep ) => {
|
||||
console.log( rep )
|
||||
rep.forEach( ( d, i ) => {
|
||||
pwa.tmp[ ref[ i ] ] = d.data
|
||||
const submenuit = {
|
||||
active: "",
|
||||
groupinfo: ref[ i ],
|
||||
id: `referential${ref[i]}`,
|
||||
optionjsoneditor: {},
|
||||
onclick: `pwa.referential.save(event,'referential${ref[i]}')`,
|
||||
btnsave: pwa.state.data.app.referentials.json.referentialsetting.btnsave,
|
||||
btndelete: pwa.state.data.app.referentials.json.referentialsetting.btndelete,
|
||||
btncopy: pwa.state.data.app.referentials.json.referentialsetting.btncopy,
|
||||
copyplaceholder: pwa.state.data.app.referentials.json.referentialsetting.copyplaceholder,
|
||||
objecttype: objecttype
|
||||
};
|
||||
pwa.state.data.app.referentials.json.referentialsetting.submenuitems.push( submenuit )
|
||||
} );
|
||||
document.getElementById( 'maincontent' )
|
||||
.innerHTML = Mustache.render( document.getElementById( 'referential' )
|
||||
.innerHTML, pwa.state.data.app.referentials.json.referentialsetting );
|
||||
|
||||
pwa.state.data.app.referentials.json.referentialsetting.submenuitems.forEach( tab => {
|
||||
document.getElementById( tab.id )
|
||||
.innerHTML = Mustache.render( tpleditor, tab );
|
||||
//console.log( tab.id, tab )
|
||||
// Convert each div with formfieldtype to a form field set with value if exist and listen button to run callback
|
||||
pwa.referential.init( tab );
|
||||
} );
|
||||
} ) )
|
||||
.catch( err => {
|
||||
console.log( "eeeee", err );
|
||||
const submenuit = {
|
||||
active: "",
|
||||
groupinfo: objecttype,
|
||||
id: `referential${objecttype}`,
|
||||
optionjsoneditor: {},
|
||||
onclick: `pwa.referential.save(event,'referential${objecttype}')`,
|
||||
data: { erreur: err }
|
||||
};
|
||||
pwa.state.data.app.referentials.json.referentialsetting.submenuitems.push( submenuit )
|
||||
} );
|
||||
console.groupEnd();
|
||||
}
|
||||
|
||||
pwa.referential.init = ( tab ) => {
|
||||
const doctab = document.querySelector( `#${tab.id}` );
|
||||
const editor = new JSONEditor( doctab.querySelector( `.jsoneditor` ), tab.optionjsoneditor );
|
||||
console.table( tab )
|
||||
console.log( tab.objecttype, tab.groupinfo )
|
||||
editor.set( pwa.tmp[ tab.groupinfo ] );
|
||||
editor.expandAll();
|
||||
// ajoute un listener sur btn pour faire axios post with editor.get()
|
||||
Array.from( doctab.querySelectorAll( '.save, .delete, .copy' ) )
|
||||
.forEach( act => {
|
||||
act.addEventListener( 'click', e => {
|
||||
e.preventDefault();
|
||||
console.log( 'cliiiiiiiiiiiiiiiiiiiick', tab.id )
|
||||
if( e.target.classList.contains( 'save' ) ) {
|
||||
/*
|
||||
axios.put( `${pwa.urlbackauth}/referentials/content/${tab.objecttype}/${tab.groupinfo}`, editor.get(), {
|
||||
headers: pwa.state.data.headers
|
||||
} )
|
||||
.then( data => {
|
||||
console.log( "affiche message done" );
|
||||
} )
|
||||
.catch( err => {
|
||||
console.log( "affiche message err ", err )
|
||||
} );
|
||||
*/
|
||||
console.log( 'editor', editor.get() );
|
||||
}
|
||||
if( e.target.classList.contains( 'delete' ) ) {
|
||||
//axios.get( @tTODO la mise à jour du nouveau referentiel avec la version)
|
||||
}
|
||||
if( e.target.classList.contains( 'copy' ) ) {
|
||||
//@TODO create a new referential file localy from an existing one
|
||||
}
|
||||
/*console.log( e.target.closest( '[data-idref]' )
|
||||
.getAttribute( 'data-idref' ) )
|
||||
console.log( editor.get() );
|
||||
envoyer à axios et modifier pwa.state. en cours
|
||||
*/
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
pwa.referential.initold = async ( object ) => {
|
||||
$( '#mainContent' )
|
||||
.html( pwa.referential.content );
|
||||
// charge ul#menuleft
|
||||
// create the editor
|
||||
const container = document.getElementById( "jsoneditor" )
|
||||
const options = {}
|
||||
const editor = new JSONEditor( container, options )
|
||||
axios.get( `${pwa.urlbackauth}/referentials/content/object/${object}`, {
|
||||
headers: pwa.state.data.headers
|
||||
} )
|
||||
.then(
|
||||
( ref ) => { editor.set( ref.data ) },
|
||||
( error ) => {
|
||||
window.location.pathname == "/"
|
||||
} )
|
||||
// set json
|
||||
/*const initialJson = {
|
||||
"Array": [1, 2, 3],
|
||||
"Boolean": true,
|
||||
"Null": null,
|
||||
"Number": 123,
|
||||
"Object": { "a": "b", "c": "d" },
|
||||
"String": "Hello World"
|
||||
}
|
||||
editor.set(initialJson)
|
||||
*/
|
||||
// get json
|
||||
const updatedJson = editor.get()
|
||||
console.log( 'updatedJson', updatedJson )
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
<h1 class="h3 mb-3">{{titre}}</h1>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class='card'>
|
||||
<div class='card-body'>
|
||||
<p>La gestion d'un referentiel est multilangue, la sauvegarde remplace l'ancien et génére chaque referentiel par langue.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class='col-sm-12 col-xl-4'>
|
||||
<div class='card h-100'>
|
||||
<div class='card-body'>{{{datadef}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-sm-12 col-xl-4'>
|
||||
<div class='card h-100'>
|
||||
<div class='card-body'>{{{jsondef}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-sm-12 col-xl-4'>
|
||||
<div class='card h-100'>
|
||||
<div class='card-body'>{{{objectdef}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-xl-2">
|
||||
<div class="card">
|
||||
<div class="card-header bg-grey">
|
||||
<h5 class="card-title mb-0">{{{submenutitre}}}</h5>
|
||||
</div>
|
||||
<div class="list-group list-group-flush" role="tablist">
|
||||
{{#submenuitems}}
|
||||
<a class="list-group-item list-group-item-action {{active}}" data-bs-toggle="list" href="#{{id}}" role="tab">{{{groupinfo}}}
|
||||
</a>
|
||||
{{/submenuitems}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-9 col-xl-10">
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane fade show active" role="tabpanel">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
var pwa = pwa || {};
|
||||
/*
|
||||
Reporting js managing sceen
|
||||
|
||||
|
||||
*/
|
||||
//--##
|
||||
pwa.reporting = pwa.reporting || {};
|
||||
pwa.reporting.init = () => {
|
||||
console.log('charge reporting');
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
// app management for search request
|
||||
/*
|
||||
@todo create a search/index content for an apxtrib instance
|
||||
//store request to analyse kind of looking for
|
||||
|
||||
*/
|
||||
var pwa = pwa || {};
|
||||
pwa.search = {};
|
||||
pwa.search.tpl = `
|
||||
<div class="container-fluid p-0">
|
||||
<h1 class="h3 mb-3">Recherche pour: {{searchtxt}}</h1>
|
||||
<div class="row">
|
||||
{{#results}}
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<p><a href="{{url}}" target="_blank">{{url}}</a> - {{format}}</p>
|
||||
<h5 class="card-title mb-0">{{{title}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{{desc}}}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
{{#relatedtag}}
|
||||
<button type="button" class="btn btn-dark" >{{.}}</button>
|
||||
{{/relatedtag}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/results}}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
pwa.search.dataexample = {
|
||||
searchtxt: "search string to looking for",
|
||||
results: [ {
|
||||
url: "https://apxtrib.org",
|
||||
format: "pdf",
|
||||
title: "Search finding title of the page",
|
||||
desc: "sentence contexte of the searchtxt",
|
||||
relatedtag: [ "keyword1", "keyword2" ]
|
||||
} ]
|
||||
}
|
||||
|
||||
pwa.search.req = ( info ) => {
|
||||
if( info[ 1 ] == "?" ) {
|
||||
const urlparse = new URLSearchParams( info );
|
||||
//Then set param with urlpar.get('variable name')
|
||||
info = {
|
||||
idsearch: urlparse.get( 'idsearchtxt' )
|
||||
}
|
||||
}
|
||||
const searchtxt = document.getElementById( info )
|
||||
.value;
|
||||
console.log( info, searchtxt );
|
||||
|
||||
const req = { searchtxt };
|
||||
req.results = [ {
|
||||
url: "",
|
||||
format: "",
|
||||
title: "Nous n'avons rien à vous proposer sur ce sujet",
|
||||
desc: `<p>To find more click on <a href='https://google.com/search?q=${searchtxt.replace(/ /g,'+')}' target="_blanck"> google search </a></p> `,
|
||||
relatedtag: [ 'tag1', "tag2", "tag3" ]
|
||||
} ];
|
||||
|
||||
document.getElementsByTagName( 'main' )[ 0 ]
|
||||
.innerHTML = Mustache.render( pwa.search.tpl, req );
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
"use strict";
|
||||
|
||||
var pwa = pwa || {};
|
||||
// Affiche pour tous les tuso et manage des tutos en fonction des droits
|
||||
// ces tuto sont stocké dans items avec les tag TUTO MAILDIGIT
|
||||
// Un searchindex/TUTOMAILDIGIT.json list les id
|
||||
|
||||
|
||||
//--##
|
||||
pwa.tuto = {};
|
||||
$(document)
|
||||
.ready(function() {
|
||||
//simule un ensemble de click pour faciliter le dev sans avoir à recliquer
|
||||
// à commenter avant de passer en production
|
||||
//pwa.tuto.init();
|
||||
})
|
||||
|
||||
pwa.tuto.masonryview = () => {
|
||||
const blocmasonry = {
|
||||
classnamebloc: "searchtuto",
|
||||
classmasonryitem: "col-md-12",
|
||||
titlemasonry: "Liste des tutos",
|
||||
masonrycontent: "",
|
||||
actionmasonry: [{
|
||||
classbtn: "btn-primary",
|
||||
actionclick: "pwa.tuto.createTuto();",
|
||||
title: "Ajouter un tuto",
|
||||
icone: "fas fa-plus"
|
||||
}]
|
||||
}
|
||||
//on recupere la data
|
||||
const data = {}
|
||||
// recupere liste des tag et comptage pour afficher les tag présent
|
||||
//
|
||||
// axios.get( items/tuto, company, card (objet)/tuto retourne un json avec liste de cards )
|
||||
//
|
||||
/*blocmasonry.masonrycontent = Mustache.render($('#sectionFilterlist')
|
||||
.html(), data)*/
|
||||
return blocmasonry
|
||||
}
|
||||
pwa.tuto.gestion = () => {
|
||||
alert('gere')
|
||||
}
|
||||
pwa.tuto.menutop = () => {
|
||||
//liste des options possibles pour le contexte
|
||||
$('#tplmenutop > .nav-left li')
|
||||
.removeClass('d-none')
|
||||
.addClass('d-none');
|
||||
const listmenutop = ['burger']; //['burger', 'filemanager', 'statistique', 'manageobjet'];
|
||||
listmenutop.forEach(m => {
|
||||
$('#tplmenutop > .nav-left li.' + m)
|
||||
.removeClass('d-none');
|
||||
});
|
||||
//Ajout eventuel d'icone d'action on enleve celels d'avant
|
||||
$('li.objectspecifique')
|
||||
.remove();
|
||||
const addmenutop = {
|
||||
listmenu: [{
|
||||
"liclass": "manageobjet",
|
||||
"title": "Gestion des objets",
|
||||
"actionclick": "pwa.tuto.gestion();",
|
||||
"icone": "fas fa-cubes"
|
||||
}]
|
||||
}
|
||||
const tplmenutop = `
|
||||
{{#listmenu}}
|
||||
<li class="{{liclass}} objectspecifique">
|
||||
<a class='menutop' title="{{title}}" onclick="{{actionclick}}">
|
||||
<i class="{{icone}}"></i>
|
||||
</a>
|
||||
</li>
|
||||
{{/listmenu}}`;
|
||||
$('#tplmenutop ul.nav-left')
|
||||
.append(Mustache.render(tplmenutop, addmenutop))
|
||||
}
|
||||
|
||||
|
||||
pwa.tuto.init = async (object) => {
|
||||
console.log('Lance tuto')
|
||||
pwa.tuto.menutop();
|
||||
|
||||
// Reinit et ajoute des bloc
|
||||
$('#mainContent > .row')
|
||||
.html('<div class="masonry-sizer col-md-12"></div>');
|
||||
$('#mainContent > .row')
|
||||
.append(Mustache.render($('#app_masonryitemaction')
|
||||
.html(), pwa.tuto.masonryview()));
|
||||
new Masonry(".masonry", {
|
||||
itemSelector: ".masonry-item",
|
||||
columnWidth: ".masonry-sizer",
|
||||
percentPosition: true
|
||||
});
|
||||
|
||||
};
|
@@ -0,0 +1,74 @@
|
||||
"use strict";
|
||||
|
||||
var pwa = pwa || {};
|
||||
//--##
|
||||
pwa.userManager = pwa.userManager || {};
|
||||
|
||||
pwa.userManager.init = function() {
|
||||
$("#espaceMasonry")
|
||||
.html("");
|
||||
pwa.userProfile.ficheUser("0", "ADMIN");
|
||||
};
|
||||
pwa.userManager.userList = async function() {
|
||||
//check ADMIN
|
||||
if(pwa.MODE_ENV) {
|
||||
return [
|
||||
{ uuid: "pcolzy", desc: "pcolzy" },
|
||||
{ uuid: "user2", desc: "User2" }
|
||||
];
|
||||
} else {
|
||||
const datauser = await axios.get(pwa.urlbackauth + "/login", {
|
||||
headers: pwa.state.data.headers
|
||||
});
|
||||
const lst = datauser.data.items.map(u => {
|
||||
return { uuid: u.uuid, desc: u.name };
|
||||
});
|
||||
return lst;
|
||||
}
|
||||
};
|
||||
|
||||
pwa.userManager.ficheUser = function(iduser) {
|
||||
// Génere un form de user pre-rempli avec iduser
|
||||
let userForm = {
|
||||
includein: "#espaceMasonry",
|
||||
template: "#mainContentMasonry",
|
||||
idmasonry: "UserForm",
|
||||
destinationclass: "formUser",
|
||||
header: "Information du compte",
|
||||
formclass: "formUserProfil",
|
||||
nombreColonne: 6,
|
||||
commentaire: "",
|
||||
footer: ""
|
||||
};
|
||||
let datauser = pwa.state.data.user;
|
||||
if(iduser) {
|
||||
//On recupere les informations iduser
|
||||
// faire un get (iduser) datauser =
|
||||
userForm.button = [{
|
||||
action: "update",
|
||||
label: "Sauvegarder",
|
||||
msgok: "Votre sauvegarde a bien été effectuée en local",
|
||||
msgko: "Votre sauvegarde n'a pas pu être réalisée ",
|
||||
actionclick: "pwa.userManager.update()",
|
||||
idObject: pwa.state.data.user.uuid,
|
||||
objectSelected: "user"
|
||||
}];
|
||||
} else {
|
||||
userForm.button = [{
|
||||
action: "create",
|
||||
label: "Créer",
|
||||
msgok: "Utilisateur créer en local",
|
||||
msgko: "La création d'un utilisateur n'est pas possible ",
|
||||
actionclick: "pwa.userManager.create()",
|
||||
idObject: "0",
|
||||
objectSelected: "user"
|
||||
}];
|
||||
}
|
||||
userForm.main = pwa.forms.genereForm(pwa.state.app.ref.users, datauser);
|
||||
console.log("button envoye", userForm.button);
|
||||
userForm.buttonup = Mustache.render($("#actionButton")
|
||||
.html(), {
|
||||
button: userForm.button
|
||||
});
|
||||
pwa.masonry.append(userForm, pwa.forms.actionForm);
|
||||
};
|
@@ -0,0 +1,88 @@
|
||||
|
||||
<h1 class="h3 mb-3">Chart.js</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card flex-fill w-100">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Line Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">A line chart is a way of plotting data points on a line.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-line"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Bar Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">A bar chart provides a way of showing data values represented as vertical bars.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-bar"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Doughnut Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">Doughnut charts are excellent at showing the relational proportions between data.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart chart-sm">
|
||||
<canvas id="chartjs-doughnut"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Pie Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">Pie charts are excellent at showing the relational proportions between data.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart chart-sm">
|
||||
<canvas id="chartjs-pie"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Radar Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">A radar chart is a way of showing multiple data points and the variation between them.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-radar"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Polar Area Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">Polar area charts are similar to pie charts, but each segment has the same angle.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-polar-area"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,170 @@
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0">{{{publicinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userpublicinfo" somethingchange="false">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="mb-3" {{{meta.users.PSEUDO.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.PSEUDO.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.BIOGRAPHY.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.BIOGRAPHY.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.PUBLICKEY.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.PUBLICKEY.html}}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="text-center" {{{meta.users.IMGAVATAR.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.IMGAVATAR.html}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickpub}}}">
|
||||
{{{btnsavepub}}}
|
||||
</button>
|
||||
<div class="msgsubmit"></div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
||||
<h5 class="card-title mb-0">{{{privateinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userprivateinfo" somethingchange="false" >
|
||||
<div class="row">
|
||||
{{{infoprivate}}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" {{{meta.users.NICKNAME.tag}}}>
|
||||
{{{meta.users.NICKNAME.html}}}
|
||||
</div>
|
||||
<div class="mb-3 col-md-6" {{{meta.users.NAME.tag}}}>
|
||||
{{{meta.users.NAME.html}}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.EMAIL.tag}}}>
|
||||
{{{meta.users.EMAIL.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.ADDRESS1.tag}}}>
|
||||
{{{meta.users.ADDRESS1.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.ADDRESS2.tag}}}>
|
||||
{{{meta.users.ADDRESS2.html}}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" {{{meta.users.CITY.tag}}}>
|
||||
{{{meta.users.CITY.html}}}
|
||||
</div>
|
||||
<div class="mb-3 col-md-4" {{{meta.users.ZIP.tag}}}>
|
||||
{{{meta.users.ZIP.html}}}
|
||||
</div>
|
||||
<div class="mb-3 col-md-2" {{{meta.users.COUNTRY.tag}}}>
|
||||
{{{meta.users.COUNTRY.html}}}
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickprivate}}}">
|
||||
{{{btnsaveprivate}}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0">{{{publicinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userpublicinfo" somethingchange="false">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="mb-3" {{{meta.users.PSEUDO.tag}}} tpl="{{{users.PSEUDO.type}}}" object="users" fieldname="PSEUDO" placeholder="{{{users.PSEUDO.placeholder}}}" desc="{{{users.PSEUDO.desc}}}"
|
||||
Checkjson="{{{users.PSEUDO.check}}}"
|
||||
newvalue="">
|
||||
{{{meta.users.PSEUDO.html}}}
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{users.BIOGRAPHY.type}}" object="users" fieldname="BIOGRAPHY" placeholder="{{users.BIOGRAPHY.placeholder}}" rows="{{{users.BIOGRAPHY.rows}}}" desc="{{{users.BIOGRAPHY.desc}}}" Checkjson="{{{users.BIOGRAPHY.check}}}" info="{{{users.BIOGRAPHY.info}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{users.PUBLICKEY.type}}" object="users" fieldname="PUBLICKEY" placeholder="{{}}" rows="2" desc="{{{users.PUBLICKEY.desc}}}" info="{{{users.PUBLICKEY.info}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="text-center" formfieldtype="{{users.IMGAVATAR.type}}" object="users" fieldname="IMGAVATAR" altimg="{{users.PSEUDO.desc}}" classimg="rounded-circle img-responsive mt-2" width="{{users.IMGAVATAR.width}}" height="{{users.IMGAVATAR.height}}" classdivupload="mt-2" classbtn="btn btn-primary" desc="{{{users.IMGAVATAR.desc}}}"
|
||||
info="{{{users.IMGAVATAR.info}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickpub}}}">
|
||||
{{{btnsavepub}}}
|
||||
</button>
|
||||
<div class="msgsubmit"></div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
||||
<h5 class="card-title mb-0">{{{privateinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userprivateinfo" somethingchange="false" >
|
||||
<div class="row">
|
||||
{{{infoprivate}}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" formfieldtype="{{{users.NICKNAME.type}}}" object="users" fieldname="NICKNAME" placeholder="{{{users.NICKNAME.placeholder}}}" desc="{{{users.NICKNAME.desc}}}"
|
||||
Checkjson="{{{users.NICKNAME.check}}}"
|
||||
newvalue="">
|
||||
<div class="mb-3 col-md-6" formfieldtype="{{{users.NAME.type}}}" object="users" fieldname="NAME" placeholder="{{{users.NAME.placeholder}}}" desc="{{{users.NAME.desc}}}"
|
||||
Checkjson="{{{users.NAME.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{{users.EMAIL.type}}}" object="users" fieldname="EMAIL" placeholder="{{{users.EMAIL.placeholder}}}" desc="{{{users.EMAIL.desc}}}"
|
||||
Checkjson="{{{users.EMAIL.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{{users.ADDRESS1.type}}}" object="users" fieldname="ADDRESS1" placeholder="{{{users.ADDRESS1.placeholder}}}" desc="{{{users.ADDRESS1.desc}}}"
|
||||
Checkjson="{{{users.ADDRESS1.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{{users.ADDRESS2.type}}}" object="users" fieldname="ADDRESS2" placeholder="{{{users.ADDRESS2.placeholder}}}" desc="{{{users.ADDRESS2.desc}}}"
|
||||
Checkjson="{{{users.ADDRESS2.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" formfieldtype="{{{users.CITY.type}}}" object="users" fieldname="CITY" placeholder="{{{users.CITY.placeholder}}}" desc="{{{users.CITY.desc}}}"
|
||||
Checkjson="{{{users.CITY.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3 col-md-4" formfieldtype="{{{users.ZIP.type}}}" object="users" fieldname="ZIP" placeholder="{{{users.ZIP.placeholder}}}" desc="{{{users.ZIP.desc}}}"
|
||||
Checkjson="{{{users.ZIP.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3 col-md-2" formfieldtype="{{{users.COUNTRY.type}}}" object="users" fieldname="COUNTRY" placeholder="{{{users.COUNTRY.placeholder}}}" desc="{{{users.COUNTRY.desc}}}"
|
||||
Checkjson="{{{users.COUNTRY.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickprivate}}}">
|
||||
{{{btnsaveprivate}}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,23 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Password</h5>
|
||||
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="inputPasswordCurrent">Current password</label>
|
||||
<input type="password" class="form-control" id="inputPasswordCurrent">
|
||||
<small><a href="#">Forgot your password?</a></small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="inputPasswordNew">New password</label>
|
||||
<input type="password" class="form-control" id="inputPasswordNew">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="inputPasswordNew2">Verify password</label>
|
||||
<input type="password" class="form-control" id="inputPasswordNew2">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
BIN
asupsetup/data/domain/apixpress/www/app/webapp/static/components/flipbox.zip
Executable file
BIN
asupsetup/data/domain/apixpress/www/app/webapp/static/components/flipbox.zip
Executable file
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"title": "Profile",
|
||||
"desc": "<p>Vos informations</p>",
|
||||
"submenutitle": "Blabla",
|
||||
"submenuitems": [{
|
||||
"submenudesc": "group1",
|
||||
"active": "active",
|
||||
"id": "gr1",
|
||||
"content": "blabla group1"
|
||||
}, {
|
||||
"submenudesc": "group2",
|
||||
"id": "gr2",
|
||||
"content": "blabla group2"
|
||||
}, {
|
||||
"submenudesc": "group3",
|
||||
"id": "gr3",
|
||||
"content": "blabla group 3"
|
||||
}]
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
$( 'a.contenu' )
|
||||
.on( 'click', function () {
|
||||
// $( this )
|
||||
// .preventDefault();
|
||||
// hide all
|
||||
$( '.face.back >div' )
|
||||
.addClass( 'd-none' );
|
||||
const dest = $( this )
|
||||
.attr( 'data-dest' )
|
||||
$( '.face.back >.' + dest )
|
||||
.removeClass( 'd-none' );
|
||||
$( '.flip >.card' )
|
||||
.toggleClass( 'flipped' );
|
||||
} )
|
||||
|
||||
$( '.face.back >> a.retour' )
|
||||
.on( 'click', function () {
|
||||
$( '.flip >.card' )
|
||||
.toggleClass( 'flipped' );
|
||||
} )
|
@@ -0,0 +1,37 @@
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="flip">
|
||||
<div class="card">
|
||||
<div class="face front">
|
||||
<div class="inner">
|
||||
<h3>Blabla</h3>
|
||||
<p><a class="contenu" data-dest="contenuA">ContenuA</a></p>
|
||||
<p><a class="contenu" data-dest="contenuB">ContenuB</a></p>
|
||||
<p><a class="contenu" data-dest="contenuC">ContenuC</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="face back">
|
||||
<div class="inner text-center contenuA">
|
||||
<a class="retour"> back </a>
|
||||
<h3>A Improved efficiency through automation</h3>
|
||||
</div>
|
||||
<div class="inner text-center contenuB">
|
||||
<a class="retour"> back </a>
|
||||
<h3>B Improved efficiency through automation</h3>
|
||||
</div>
|
||||
<div class="inner text-center contenuC">
|
||||
<a class="retour"> back </a>
|
||||
<h3>C Improved efficiency through automation</h3>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-default">Know More</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,53 @@
|
||||
.flipbox {
|
||||
.flip {
|
||||
-webkit-perspective: 800;
|
||||
perspective: 800;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
.flip .card.flipped {
|
||||
-webkit-transform: rotatey(-180deg);
|
||||
transform: rotatey(-180deg);
|
||||
}
|
||||
.flip .card {
|
||||
width: 270px;
|
||||
height: 178px;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: 0.5s;
|
||||
transform-style: preserve-3d;
|
||||
transition: 0.5s;
|
||||
background-color: #fff;
|
||||
|
||||
}
|
||||
.flip .card .face {
|
||||
-webkit-backface-visibility: hidden ;
|
||||
backface-visibility: hidden ;
|
||||
z-index: 2;
|
||||
}
|
||||
.flip .card .front {
|
||||
position: absolute;
|
||||
width: 270px;
|
||||
z-index: 1;
|
||||
}
|
||||
.flip .card .front img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.flip .card .img {
|
||||
position: relaitve;
|
||||
width: 270px;
|
||||
height: 178px;
|
||||
z-index: 1;
|
||||
border: 2px solid #000;
|
||||
}
|
||||
.flip .card .back {
|
||||
padding-top: 10%;
|
||||
-webkit-transform: rotatey(-180deg);
|
||||
transform: rotatey(-180deg);
|
||||
position: absolute;
|
||||
}
|
||||
.inner{
|
||||
margin:0px !important;
|
||||
width: 270px;
|
||||
}
|
||||
}
|
@@ -0,0 +1,9 @@
|
||||
<!-- main class="d-flex w-100 h-100" -->
|
||||
<div class="container d-flex flex-column">
|
||||
<div class="row vh-100">
|
||||
<div class="col-sm-10 col-md-8 col-lg-6 mx-auto d-table h-100">
|
||||
<importhtml></importhtml>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /main -->
|
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"iconnotif": "bell",
|
||||
"number": 0,
|
||||
"notifheader": "Vos notifications",
|
||||
"notiffooter": "Voir toutes les notifications",
|
||||
"actionnotifmanager": "",
|
||||
"href": "?action=notification.view",
|
||||
"notifs": [{
|
||||
"urldetail": "#",
|
||||
"classicon": "text-danger",
|
||||
"icon": "alert",
|
||||
"title": "Intusion de 192.168.1.3",
|
||||
"desc": "Check your log",
|
||||
"elapse": "il y a 13mn"
|
||||
},
|
||||
{
|
||||
"urldetail": "#",
|
||||
"classicon": "text-success",
|
||||
"icon": "star",
|
||||
"title": "Successfull backup",
|
||||
"desc": "",
|
||||
"elapse": "il y a 2 jours"
|
||||
},
|
||||
{
|
||||
"urldetail": "#",
|
||||
"classicon": "text-warning",
|
||||
"icon": "bell",
|
||||
"title": "Commande en attente",
|
||||
"desc": "Vous avez des commandes en attente de traitement",
|
||||
"elapse": "il y a 6 heures"
|
||||
}
|
||||
]
|
||||
}
|
@@ -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 );
|
||||
} );
|
||||
};
|
@@ -0,0 +1,32 @@
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-icon dropdown-toggle" href="#" id="alertsDropdown" data-bs-toggle="dropdown">
|
||||
<div class="position-relative">
|
||||
<i class="align-middle" data-feather="{{iconnotif}}"></i>
|
||||
<span class="indicator">{{number}}</span>
|
||||
</div>
|
||||
</a>
|
||||
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-end py-0" aria-labelledby="alertsDropdown">
|
||||
<div class="dropdown-menu-header">
|
||||
{{{notificationheader}}}
|
||||
</div>
|
||||
<div class="list-group">
|
||||
{{#notifs}}
|
||||
<a href="{{urldetail}}" class="list-group-item">
|
||||
<div class="row g-0 align-items-center">
|
||||
<div class="col-2">
|
||||
<i class="{{{classicon}}}" data-feather="{{{icon}}}"></i>
|
||||
</div>
|
||||
<div class="col-10">
|
||||
<div class="text-dark">{{{title}}}</div>
|
||||
<div class="text-muted small mt-1">{{{desc}}}</div>
|
||||
<div class="text-muted small mt-1">{{{elapse}}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{{/notifs}}
|
||||
</div>
|
||||
<div class="dropdown-menu-footer">
|
||||
<a href="#" class="text-muted">{{{notificationfooter}}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"icon": "settings",
|
||||
"desc": "Log out",
|
||||
"href": "?action=auth.logout",
|
||||
"menubreaker": false
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"icon": "user",
|
||||
"desc": "Mes Activités",
|
||||
"href": "?action=userprofile.settings",
|
||||
"menubreaker": false
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"icon": "pie-chart",
|
||||
"desc": "Mon profile",
|
||||
"href": "?action=userprofile.settings",
|
||||
"menubreaker": false
|
||||
}
|
@@ -0,0 +1,88 @@
|
||||
|
||||
<h1 class="h3 mb-3">Chart.js</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card flex-fill w-100">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Line Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">A line chart is a way of plotting data points on a line.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-line"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Bar Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">A bar chart provides a way of showing data values represented as vertical bars.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-bar"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Doughnut Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">Doughnut charts are excellent at showing the relational proportions between data.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart chart-sm">
|
||||
<canvas id="chartjs-doughnut"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Pie Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">Pie charts are excellent at showing the relational proportions between data.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart chart-sm">
|
||||
<canvas id="chartjs-pie"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Radar Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">A radar chart is a way of showing multiple data points and the variation between them.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-radar"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title">Polar Area Chart</h5>
|
||||
<h6 class="card-subtitle text-muted">Polar area charts are similar to pie charts, but each segment has the same angle.</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart">
|
||||
<canvas id="chartjs-polar-area"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,66 @@
|
||||
var pwa = pwa || {};
|
||||
/*
|
||||
Manage user data for current login user
|
||||
|
||||
From user data = pwa.state.data.userlogin
|
||||
|
||||
*/
|
||||
//--##
|
||||
pwa.main = pwa.main || {};
|
||||
pwa.main.tpldata = pwa.main.tpldata || {};
|
||||
pwa.main.tpl = pwa.main.tpl || {};
|
||||
pwa.main.ref = pwa.main.ref || {};
|
||||
//Add template here to make it available after authentification
|
||||
// in pwa.state.data.tpl[name]
|
||||
// pwa.state.data.tpldata[name] in the user's language by adding at the end of value _{pwa.state.data.ctx.lang}.json
|
||||
pwa.main.tpl.usersettingaccount = `static/components/userprofile/usersettingaccount.mustache`;
|
||||
pwa.main.tpldata.topbaruserprofile = `static/components/userprofile/topbaruserprofile`;
|
||||
pwa.main.tpldata.topbaruseractivity = `static/components/userprofile/topbaruseractivity`;
|
||||
pwa.main.tpldata.topbaruserLogout = `static/components/userprofile/topbaruserLogout`;
|
||||
pwa.main.referential.users = 'url ... obeject/users.json';
|
||||
//header check if user is allow to get this
|
||||
|
||||
pwa.userprofile = pwa.userprofile || {};
|
||||
|
||||
pwa.userprofile.settings = ( e ) => {
|
||||
console.groupCollapsed( 'load user settings' );
|
||||
console.log( Object.keys( pwa ) )
|
||||
//data form init from pwa.state or axios.get( data from user )
|
||||
const data = pwa.state.data.userlogin;
|
||||
// add meta data object to create forms
|
||||
const meta = { "users": {} };
|
||||
pwa.state.data.app.referentials.object.users.forEach( f => {
|
||||
// genere tag
|
||||
const test = Object.keys( f )
|
||||
f.tag = " object='users' " + test.reduce( ( ac, k ) => {
|
||||
return ac + k + '="' + f[ k ] + '" ';
|
||||
} );
|
||||
// genere html field care do html after tag if not
|
||||
f.html = pwa.form.tpl[ f.tpl ].html( f )
|
||||
meta.users[ f.idfield ] = f
|
||||
//console.log( f.idfield )
|
||||
//console.log( f )
|
||||
} );
|
||||
pwa.state.data.app.referentials.json.usersetting.submenuitems[ 0 ].meta = meta;
|
||||
console.log( "meta", pwa.state.data.app.referentials.json.usersetting )
|
||||
// tpl in #usersetting data in referentials json usersetting
|
||||
document.getElementById( 'maincontent' )
|
||||
.innerHTML = Mustache.render( document.getElementById( 'setting' )
|
||||
.innerHTML, pwa.state.data.app.referentials.json.usersetting );
|
||||
// load each content of tab then init form with data merged with tab info
|
||||
pwa.state.data.app.referentials.json.usersetting.submenuitems.forEach( tab => {
|
||||
document.getElementById( tab.id )
|
||||
.innerHTML = Mustache.render( document.getElementById( `${tab.id}tpl` )
|
||||
.innerHTML, tab );
|
||||
console.log( tab.id, tab )
|
||||
// Convert each div with formfieldtype to a form field set with value if exist and listen button to run callback
|
||||
pwa.form.init( tab.id, { ...tab, ...data }, pwa.userprofile.save )
|
||||
} )
|
||||
console.groupEnd();
|
||||
}
|
||||
pwa.userprofile.save = ( data ) => {
|
||||
console.log( "data to save", data )
|
||||
}
|
||||
pwa.userprofile.activities = () => {
|
||||
console.group( 'load user activity' );
|
||||
}
|
@@ -0,0 +1,170 @@
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0">{{{publicinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userpublicinfo" somethingchange="false">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="mb-3" {{{meta.users.PSEUDO.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.PSEUDO.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.BIOGRAPHY.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.BIOGRAPHY.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.PUBLICKEY.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.PUBLICKEY.html}}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="text-center" {{{meta.users.IMGAVATAR.tag}}}
|
||||
newvalue="">
|
||||
{{{meta.users.IMGAVATAR.html}}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickpub}}}">
|
||||
{{{btnsavepub}}}
|
||||
</button>
|
||||
<div class="msgsubmit"></div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
||||
<h5 class="card-title mb-0">{{{privateinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userprivateinfo" somethingchange="false" >
|
||||
<div class="row">
|
||||
{{{infoprivate}}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" {{{meta.users.NICKNAME.tag}}}>
|
||||
{{{meta.users.NICKNAME.html}}}
|
||||
</div>
|
||||
<div class="mb-3 col-md-6" {{{meta.users.NAME.tag}}}>
|
||||
{{{meta.users.NAME.html}}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.EMAIL.tag}}}>
|
||||
{{{meta.users.EMAIL.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.ADDRESS1.tag}}}>
|
||||
{{{meta.users.ADDRESS1.html}}}
|
||||
</div>
|
||||
<div class="mb-3" {{{meta.users.ADDRESS2.tag}}}>
|
||||
{{{meta.users.ADDRESS2.html}}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" {{{meta.users.CITY.tag}}}>
|
||||
{{{meta.users.CITY.html}}}
|
||||
</div>
|
||||
<div class="mb-3 col-md-4" {{{meta.users.ZIP.tag}}}>
|
||||
{{{meta.users.ZIP.html}}}
|
||||
</div>
|
||||
<div class="mb-3 col-md-2" {{{meta.users.COUNTRY.tag}}}>
|
||||
{{{meta.users.COUNTRY.html}}}
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickprivate}}}">
|
||||
{{{btnsaveprivate}}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0">{{{publicinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userpublicinfo" somethingchange="false">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="mb-3" {{{meta.users.PSEUDO.tag}}} tpl="{{{users.PSEUDO.type}}}" object="users" fieldname="PSEUDO" placeholder="{{{users.PSEUDO.placeholder}}}" desc="{{{users.PSEUDO.desc}}}"
|
||||
Checkjson="{{{users.PSEUDO.check}}}"
|
||||
newvalue="">
|
||||
{{{meta.users.PSEUDO.html}}}
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{users.BIOGRAPHY.type}}" object="users" fieldname="BIOGRAPHY" placeholder="{{users.BIOGRAPHY.placeholder}}" rows="{{{users.BIOGRAPHY.rows}}}" desc="{{{users.BIOGRAPHY.desc}}}" Checkjson="{{{users.BIOGRAPHY.check}}}" info="{{{users.BIOGRAPHY.info}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{users.PUBLICKEY.type}}" object="users" fieldname="PUBLICKEY" placeholder="{{}}" rows="2" desc="{{{users.PUBLICKEY.desc}}}" info="{{{users.PUBLICKEY.info}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="text-center" formfieldtype="{{users.IMGAVATAR.type}}" object="users" fieldname="IMGAVATAR" altimg="{{users.PSEUDO.desc}}" classimg="rounded-circle img-responsive mt-2" width="{{users.IMGAVATAR.width}}" height="{{users.IMGAVATAR.height}}" classdivupload="mt-2" classbtn="btn btn-primary" desc="{{{users.IMGAVATAR.desc}}}"
|
||||
info="{{{users.IMGAVATAR.info}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickpub}}}">
|
||||
{{{btnsavepub}}}
|
||||
</button>
|
||||
<div class="msgsubmit"></div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
|
||||
<h5 class="card-title mb-0">{{{privateinfo}}}</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="userprivateinfo" somethingchange="false" >
|
||||
<div class="row">
|
||||
{{{infoprivate}}}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" formfieldtype="{{{users.NICKNAME.type}}}" object="users" fieldname="NICKNAME" placeholder="{{{users.NICKNAME.placeholder}}}" desc="{{{users.NICKNAME.desc}}}"
|
||||
Checkjson="{{{users.NICKNAME.check}}}"
|
||||
newvalue="">
|
||||
<div class="mb-3 col-md-6" formfieldtype="{{{users.NAME.type}}}" object="users" fieldname="NAME" placeholder="{{{users.NAME.placeholder}}}" desc="{{{users.NAME.desc}}}"
|
||||
Checkjson="{{{users.NAME.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{{users.EMAIL.type}}}" object="users" fieldname="EMAIL" placeholder="{{{users.EMAIL.placeholder}}}" desc="{{{users.EMAIL.desc}}}"
|
||||
Checkjson="{{{users.EMAIL.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{{users.ADDRESS1.type}}}" object="users" fieldname="ADDRESS1" placeholder="{{{users.ADDRESS1.placeholder}}}" desc="{{{users.ADDRESS1.desc}}}"
|
||||
Checkjson="{{{users.ADDRESS1.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3" formfieldtype="{{{users.ADDRESS2.type}}}" object="users" fieldname="ADDRESS2" placeholder="{{{users.ADDRESS2.placeholder}}}" desc="{{{users.ADDRESS2.desc}}}"
|
||||
Checkjson="{{{users.ADDRESS2.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mb-3 col-md-6" formfieldtype="{{{users.CITY.type}}}" object="users" fieldname="CITY" placeholder="{{{users.CITY.placeholder}}}" desc="{{{users.CITY.desc}}}"
|
||||
Checkjson="{{{users.CITY.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3 col-md-4" formfieldtype="{{{users.ZIP.type}}}" object="users" fieldname="ZIP" placeholder="{{{users.ZIP.placeholder}}}" desc="{{{users.ZIP.desc}}}"
|
||||
Checkjson="{{{users.ZIP.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
<div class="mb-3 col-md-2" formfieldtype="{{{users.COUNTRY.type}}}" object="users" fieldname="COUNTRY" placeholder="{{{users.COUNTRY.placeholder}}}" desc="{{{users.COUNTRY.desc}}}"
|
||||
Checkjson="{{{users.COUNTRY.check}}}"
|
||||
newvalue="">
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary" onclick="{{{onclickprivate}}}">
|
||||
{{{btnsaveprivate}}}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,22 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">Password</h5>
|
||||
<form>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="inputPasswordCurrent">Current password</label>
|
||||
<input type="password" class="form-control" id="inputPasswordCurrent">
|
||||
<small><a href="#">Forgot your password?</a></small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="inputPasswordNew">New password</label>
|
||||
<input type="password" class="form-control" id="inputPasswordNew">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="inputPasswordNew2">Verify password</label>
|
||||
<input type="password" class="form-control" id="inputPasswordNew2">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user