// Libra.config.init={initTab:["initNS", "initDom","initTemplate", "initClass", "initAlias", "initNw", "initDd","initOriginBoot", "initX", "initUser", "initHash"]}; Libra.config.path = { virtual: "https://www.libraonline.net/Libra/", virtualSite: "https://www.libraonline.net/", real: "/usr/share/nginx/html/", fw: "https://www.libraonline.net/fw/", proxy: "https://www.libraonline.net/Libra/lib/server/proxy.php", document: "/usr/share/nginx/html/data/documents/", auth:"https://www.libraonline.net/Libra/lib/server/" } // Libra.config.langs = ["it","en","ru","cz","ua","de"] Libra.config.langs = {'it':{code:"it",text:"italian",name:"italiano"},en:{code:"en",text:"english",name:"english"},ru:{code:"ru",text:"russian",name:"русский"},cz:{code:"cz",text:"czech",name:"čeština"}} Libra.config.regex = { fn: "function", functionRe: "/([^(]function\\s*\\(.*?\\)\\s*\\{((?:[^{}]+|\\{(?2)*\\})+)\\})/", functionEmptyRe:"/([^(]function\\s*\\(.*?\\)s*\\{\\})/", functionFineFrom:"}$","functionFineFromPhp":"/}$/", functionFineTo:";;;}", commaLastFrom:"/(,)\\s*}$/", backslash:"\\", realBackslash:"\\\\", delimiterCodeLangBegin:"<@@@", delimiterCodeLangEndRe:"\\@\\@\\@>", functionEnd:";;;}", functionEndRe:"\\;\\;\\;}", delimiterLibraAutoBegin:"/*libraAuto<@@@", delimiterLibraAutoBeginRe:"\\/\\*libraAuto\\<\\@\\@\\@", delimiterLibraAutoEndRe:"\\@\\@\\@\\>libraAuto\\*\\/", delimiterSourceLangPhpBegin:"", delimiterSourceLangPhpBeginRe:"^<\\?php", delimiterSourceLangPhpEndRe:"\\?>.*$", stripslashes:"\\\\(.?)", functionSource:"(function\\s*([A-z0-9]+)?\\s*\\(.[\\s\\S]*?\\;\\;\\;\\})", braceBegin:"{","braceEnd":"}", dash:"-","functionTagVar":"var _LibraTagFunction=([0-9]+);","cr":"\r","lf":"\n","crlf":"\r\n", LanguageChange1:"Libra.Language.change({language:'", LanguageChange2_1:",fn:fun", LanguageChange2_2:"ction(_return){", LanguageChange3:",scope:this});}", sourceLang:"<\\@\\@\\@(?:([^\\s]*)\\s ?(?:use\\s*\\((.*?)\\)|\\s*))()(.[\\s\\S]*?)\\@\\@\\@>", phpSourceLang:"/<@@@(?:([^\\s]*)\\s+?(?:use\\s*\\((.*)\\)|\\s*))(.*)@@@>/msU", delimiterCodeLangBeginRe:"<\\@\\@\\@", delimiterCodeLangEnd:"@@@>", delimiterLibraAutoEnd:"@@@>libraAuto*/" } /* Libra.config.db={ "tableBeforeColumn":false, "tableBeforeColumnDivisor":"_", "historyMod":"1", "deleteLogic":false, "systemColumnsDb":[], "hosts":{ "localhost":{ "databases":{ "userDb":{ "tables":{ "objectLock":{ "struct":{ "columns":{ "objectLockId":{ "struct":{"COLUMN_NAME":"objectLockId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"path":{"struct":{"COLUMN_NAME":"path","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userId":{"struct":{"COLUMN_NAME":"userId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"objectLockId"},"class":{"struct":{"columns":{"classId":{"struct":{"COLUMN_NAME":"classId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"className":{"struct":{"COLUMN_NAME":"className","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"classJson":{"struct":{"COLUMN_NAME":"classJson","DATA_TYPE":"json","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"classId"},"objectGroup":{"struct":{"columns":{"objectGroupId":{"struct":{"COLUMN_NAME":"objectGroupId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"groupCode":{"struct":{"COLUMN_NAME":"groupCode","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"UNI","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"objectGroupId"},"propertyGroup":{"struct":{"columns":{"propertyGroupId":{"struct":{"COLUMN_NAME":"propertyGroupId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"propertyId":{"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"groupCode":{"struct":{"COLUMN_NAME":"groupCode","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"UNI","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"propertyGroupId"},"group":{"struct":{"columns":{"groupId":{"struct":{"COLUMN_NAME":"groupId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"groupCode":{"struct":{"COLUMN_NAME":"groupCode","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"UNI","COLUMN_DEFAULT":null}},"groupName":{"struct":{"COLUMN_NAME":"groupName","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"UNI","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"groupId"},"groupClass":{"struct":{"columns":{"groupClassId":{"struct":{"COLUMN_NAME":"groupClassId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"classId":{"join":{"table":"class","joinColumn":"classId","displayField":"className"},"struct":{"COLUMN_NAME":"classId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"groupId":{"struct":{"COLUMN_NAME":"groupId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"groupClassId"},"groupObject":{"struct":{"columns":{"groupObjectId":{"struct":{"COLUMN_NAME":"groupObjectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"groupId":{"struct":{"COLUMN_NAME":"groupId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"groupObjectId"},"object":{"struct":{"columns":{"objectId":{"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"classId":{"join":{"table":"class","joinColumn":"classId","displayField":"className"},"struct":{"COLUMN_NAME":"classId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"objectName":{"struct":{"COLUMN_NAME":"objectName","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"UNI","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"objectId"},"objectSync":{"struct":{"columns":{"objectSyncId":{"struct":{"COLUMN_NAME":"objectSyncId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"siteId":{"struct":{"COLUMN_NAME":"siteId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"nwId":{"struct":{"COLUMN_NAME":"nwId","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"objectSyncId"},"property":{"struct":{"columns":{"propertyId":{"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"classId":{"join":{"table":"class","joinColumn":"classId","displayField":"className"},"struct":{"COLUMN_NAME":"classId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyName":{"struct":{"COLUMN_NAME":"propertyName","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":256,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"valueType":{"struct":{"COLUMN_NAME":"valueType","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":"13","COLUMN_KEY":"","COLUMN_DEFAULT":null}},"bindable":{"struct":{"COLUMN_NAME":"bindable","DATA_TYPE":"tinyint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":"0"}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"allowBlank":{"struct":{"COLUMN_NAME":"allowBlank","DATA_TYPE":"tinyint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":"1"}},"defaultValue":{"struct":{"COLUMN_NAME":"defaultValue","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"propertyId"},"valueBoolean":{"struct":{"columns":{"valueBooleanId":{"struct":{"COLUMN_NAME":"valueBooleanId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyId":{"join":{"table":"property","joinColumn":"propertyId","displayField":"propertyName"},"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"value":{"struct":{"COLUMN_NAME":"value","DATA_TYPE":"tinyint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"valueBooleanId"},"valueFunction":{"struct":{"columns":{"valueFunctionId":{"struct":{"COLUMN_NAME":"valueFunctionId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyId":{"join":{"table":"property","joinColumn":"propertyId","displayField":"propertyName"},"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"value":{"struct":{"COLUMN_NAME":"value","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"valueSource":{"struct":{"COLUMN_NAME":"valueSource","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"valueFunctionId"},"valueNumber":{"struct":{"columns":{"valueNumberId":{"struct":{"COLUMN_NAME":"valueNumberId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyId":{"join":{"table":"property","joinColumn":"propertyId","displayField":"propertyName"},"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"value":{"struct":{"COLUMN_NAME":"value","DATA_TYPE":"double","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"valueNumberId"},"valueObject":{"struct":{"columns":{"valueObjectId":{"struct":{"COLUMN_NAME":"valueObjectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyId":{"join":{"table":"property","joinColumn":"propertyId","displayField":"propertyName"},"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"value":{"join":{"alias":"aliasValueObject","table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"value","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"valueObjectId"},"valueString":{"struct":{"columns":{"valueStringId":{"struct":{"COLUMN_NAME":"valueStringId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyId":{"join":{"table":"property","joinColumn":"propertyId","displayField":"propertyName"},"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"value":{"struct":{"COLUMN_NAME":"value","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":255,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"translate":{"struct":{"COLUMN_NAME":"translate","DATA_TYPE":"tinyint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"en":{"struct":{"COLUMN_NAME":"en","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":255,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"it":{"struct":{"COLUMN_NAME":"it","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":255,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"ru":{"struct":{"COLUMN_NAME":"ru","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":255,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"ua":{"struct":{"COLUMN_NAME":"ua","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":255,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"cz":{"struct":{"COLUMN_NAME":"cz","DATA_TYPE":"varchar","CHARACTER_MAXIMUM_LENGTH":255,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"valueStringId"},"valueText":{"struct":{"columns":{"valueTextId":{"struct":{"COLUMN_NAME":"valueTextId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"PRI","COLUMN_DEFAULT":null}},"objectId":{"join":{"table":"object","joinColumn":"objectId","displayField":"objectName"},"struct":{"COLUMN_NAME":"objectId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"propertyId":{"join":{"table":"property","joinColumn":"propertyId","displayField":"propertyName"},"struct":{"COLUMN_NAME":"propertyId","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"value":{"struct":{"COLUMN_NAME":"value","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"translate":{"struct":{"COLUMN_NAME":"translate","DATA_TYPE":"tinyint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"userIdAdd":{"struct":{"COLUMN_NAME":"userIdAdd","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdMod":{"struct":{"COLUMN_NAME":"userIdMod","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"userIdDel":{"struct":{"COLUMN_NAME":"userIdDel","DATA_TYPE":"bigint","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateAdd":{"struct":{"COLUMN_NAME":"dateAdd","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateMod":{"struct":{"COLUMN_NAME":"dateMod","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateDel":{"struct":{"COLUMN_NAME":"dateDel","DATA_TYPE":"date","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeAdd":{"struct":{"COLUMN_NAME":"dateTimeAdd","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeMod":{"struct":{"COLUMN_NAME":"dateTimeMod","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"dateTimeDel":{"struct":{"COLUMN_NAME":"dateTimeDel","DATA_TYPE":"datetime","CHARACTER_MAXIMUM_LENGTH":null,"COLUMN_KEY":"","COLUMN_DEFAULT":null}},"en":{"struct":{"COLUMN_NAME":"en","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"it":{"struct":{"COLUMN_NAME":"it","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"ru":{"struct":{"COLUMN_NAME":"ru","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"ua":{"struct":{"COLUMN_NAME":"ua","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}},"cz":{"struct":{"COLUMN_NAME":"cz","DATA_TYPE":"longtext","CHARACTER_MAXIMUM_LENGTH":4294967295,"COLUMN_KEY":"MUL","COLUMN_DEFAULT":null}}}},"loaded":[],"tableId":"valueTextId"}}}}}},"systemColumns":{"del":"libraDel","session":"libraSession","userIdAdd":"userIdAdd","dateAdd":"dateAdd","datetimeAdd":"dateTimeAdd","userIdMod":"userIdMod","dateMod":"dateMod","datetimeMod":"dateTimeMod","userIdDel":"userIdDel","dateDel":"dateDel","datetimeDel":"dateTimeDel"}};*/ Libra.config.currency=[{"code":"EUR","name":"EURO","symbol":"\u20ac"},{"code":"USD","name":"DOLLARO","symbol":"$"},{"code":"UAH","name":"HRYVNIA","symbol":"\u20b4"},{"code":"CZK","name":"CORONA CECA","symbol":"K\u010d"}] Libra.ctlInstance=function( out, inp ) { if ( typeof out === 'undefined' ) out = inp instanceof Array ? [] : {}; return out } Libra.mergeConfig=function( out, inp,path = null ) { let setted=null, propSetted out = Libra.ctlInstance( out, inp ) for (let prop in inp ){ let val, propOrig, split, scope, fn, propFn, newPath=null if ( inp[ prop ] === null ) out[ prop ] = null else { split = prop.split(' ') if ( path && ( split.length > 1 || out instanceof Array ) ) newPath = path + '["' + prop + '"]' else newPath = (path ? path + '.' : '' ) + prop if( typeof inp[ prop ] === 'string' && ( ( /*inp[ prop ].match(/(?=.*^function)(?=.*\()(?=.*\)).*$/m)*/inp[ prop ].substring( 0, 8 ) === 'function' && inp[ prop ].includes('(')&& inp[ prop ].includes(')')&& inp[ prop ].includes('{')&& inp[ prop ].includes('}') ) || split.length > 1 ) ){ try { val = new Function( 'return ' + inp[ prop ] )() }catch(e){ console.log('error mergeConfig: ',split,path,prop, e )} if( typeof val === 'function' ) inp[ prop ] = val } if( typeof inp[ prop ] === 'function' ) Object.defineProperty( inp[ prop ], "name", { value: path ? newPath : prop } ) if( split.length === 1 ) { if ( typeof inp[ prop ] === 'object' ) out[ prop ] = Libra.mergeConfig( out[ prop ], inp[ prop ], newPath ) else out[ prop ] = inp[ prop ] } else { propOrig = prop prop = split[ 1 ] propFn = split[ 0 ] switch( propFn ) { default: out[ propOrig ] = inp[ propOrig ]; break case 'add': out[prop].add(inp[ propOrig ]); break case 'eval': inp[ propOrig ].call( out, prop ); break case 'setted': setted = inp[ propOrig ]; propSetted = prop; break case 'push': case 'unshift': out[ prop ] = out[ prop ] || []; out[ prop ][ propFn ]( ...inp[ propOrig ] ); break case 'proxy': inp[ propOrig ] = Libra.mergeConfig( inp[ propOrig ], inp[ propOrig ], newPath+'.'+propOrig ) if ( inp[ propOrig ].deleteProperty ) inp[ propOrig ].deleteProperty = function( target, prop ){ if ( prop in target ) { this.fn(target,prop); return delete target[ prop ] } }.bind( { fn: inp[ propOrig ].deleteProperty } ) if ( inp[ propOrig ].set ) inp[ propOrig ].set = function( target, prop, val, receiver ){ val = this.fn(target, prop, val, receiver) return target[prop] = val }.bind( { fn: inp[ propOrig ].set } ) out[ prop ] = new Proxy( out[ prop ], inp[ propOrig ] ) break case 'filter': let keys = Object.keys(out[ prop ]) if( keys.length ){ fn = inp[ propOrig ].bind( out[ prop ] ) if( out[ prop ].filter ) out[ prop ] = out[ prop ].filter( fn ) else keys.filter( function( key ){ let res = this.fn( this.scope[ key ] ); if( !res ) delete this.scope[ key ] }.bind( { scope: out[ prop ],fn: fn } ) ) } break case 'get': case 'set': out[ propOrig ] = inp[ propOrig ] out[ '__define' + propFn[ 0 ].toUpperCase() + 'etter__']( prop, inp[ propOrig ] ) // TODO vedere bene. lo lascio ora per addMethod di class /*case 'get': case 'set': if( !out.hasOwnProperty( '_' + prop ) ) { out[ '_' + prop ] = out[ prop ] delete( out[ prop ] ) } scope = { scope: out, property: '_' + prop, type: propFn } out[ '_' + propFn + prop ] = inp[ propOrig ].bind( scope ) out[ '__define' + propFn[ 0 ].toUpperCase() + 'etter__']( prop, function( val ){ this.scope[ '_' + this.type + prop ]( val ); if( !val ) return this.scope[ this.property ]; return this.scope[ this.property ] = val }.bind( scope ) ) break*/ } } } } if( setted ) setted.call( out, propSetted ) return out } /* function(out,inp){if(!out)return inp; for (let prop in inp){ let split = prop.split(' ') if(split.length>1){ out.__defineGetter__(split[1], inp.__lookupGetter__(split[1])) out.__defineSetter__(split[1], inp.__lookupSetter__(split[1]))} if ( typeof inp[ prop ] === 'object' ) out[ prop ] = Libra.merge( out[ prop ], inp[ prop ] ); else out[ prop ] = inp[ prop ]; } return out} */ Libra.merge = function(obj1,obj2){ if(!Object.keys(obj1).length)return obj2||{} for( var p in obj2 ){ let s = p.split( ' ' ) if( s.length > 1 ){ obj1.__defineGetter__( s[ 1 ], obj2.__lookupGetter__( s[ 1 ])) obj1.__defineSetter__( s[ 1 ], obj2.__lookupSetter__( s[ 1 ])) } try { if ( obj2[ p ].constructor == Object ) { if( typeof obj1[ p ] === 'undefined' ) obj1[ p ] = {} obj1[ p ] = Libra.merge( obj1[ p ], obj2[ p ]) } else obj1[ p ] = obj2[ p ] } catch( e ) { obj1[ p ] = obj2[ p ] } } return obj1 } Libra.mergeConfig(window,{ lang:function(tag){ if( !tag ) return '' let res = Libra.data.lang[ tag ] if( !res){ debug( 'lang: insert ' + tag ) res = '[' + tag + ']' }return res }, "setted js":function(arg){Libra.Init.continue()/*;window.debug=()=>{}*/}, error:function( arg, opt = null ){Libra.Notify.add( 'error', arg, opt )}, debug:function(){console.log.apply( this, arguments )}, onhashchange:function(e){if( Libra.data.silentHash ) Libra.data.silentHash = false; else X.setViewByHash(e.newURL.split( '#' )[ 1 ])}, Libra:{ changeLang:function(l){ Libra.Cookie.set('lang',l) window.location.reload() //TODO to server for user }, isHTML : RegExp.prototype.test.bind(/(<([^>]+)>)/i), Utils:{ analizeNode:function( arg ){ let complete = 0 if( arg.window && arg.window[ 0 ] ){arg.window.focus(); return arg.window } if( arg.href ){if( Libra.onbeforeunload ) arg = Libra.onbeforeunload( arg ); arg.window = window.open( arg.href, arg.target || '_blank' ); arg.window.focus(); return arg.window } } }, Init:{ initLang:function(){ for(let i in Libra.data.langs) data.store.storeLangs.data.push({handler:function(){Libra.changeLang(this.dataset.lang)},attr:{'data-lang':Libra.data.langs[i].code},xtype:'button',html:'  '+Libra.data.langs[i].name}) }, initCookieNotice:function(){ Libra.Json.dom({ parentNode: document.body,tag:'div',id:'divCookieNotice',css:' position: absolute;top: 72px;right: 8px;width: 400px;z-index: 65000!important;background-color: #32404e;color: #adb3b8;box-shadow: 2rem 2rem 2rem 2rem rgba(0,0,0,.575)!important;',cls:'p-4 rounded',items:[{ tag:'p',lang:'cookieNoticeTitle' },{ tag:'p',cls:'text-justify', css:'font-size:12px;html-align: justify !important;text-justify: inter-word;', lang:'cookieNoticeContent' },{css:' position: absolute;bottom: 12px;right: 12px;',xtype: 'button',ui:'primary',lang:'accept',handler:function(){debug(get('divCookieNotice'));document.body.removeChild(get('divCookieNotice'))}}]})}, initUser:function(){ //TODO wait(), poi caricare tutto da server }, initHash:function(){ /*TODO if( window.location.hash.split( '#' )[ 1 ] === 'safeMode' ) Libra.data.safeMode = true *let hash = window.location.hash.substr( 1 ) if( Libra.data.safeMode && Libra.data.reference.homeLink ) Libra.data.reference.homeLink.href = '#safeMode' else{ hash = hash || 'home' }*/ //if( Libra.data.reference.wm && hash ) X.setView( hash ) }, initDone:() => Libra.bootDone(), initX:() => { let _ref = Libra.data.reference Libra.data.x.wm = 'default'+(Libra.data.isMobile?'Mobile':'') _ref.wm = get('_libraWm') _ref.nav = _ref.wmMenuNavigation.parentNode _ref.navUp = _ref.wm.childNodes[0].childNodes[0].childNodes[0] }, wait: ( wait = null ) => Libra.data.init.wait= wait !== null ? wait :1, initOriginBoot:function(){this.wait(); Libra.load({ target:'origin', path:'boot.js.php' },{ fn: () => Libra.Init.continue( 1 )})}, continue:function( wait = null ){ this.initNS() if( wait !== null ) this.wait( !wait ) do{ if( Libra.data.init.wait ) break let currentScript = Libra.data.init.initTabLeft[ 0 ] //TODO if hash===scriptname Libra.data.init.initTabLeft.shift() if( currentScript && Libra.Init[ currentScript ]) Libra.Init[ currentScript ](); else error('init script ubsent:'+ currentScript ) }while( Libra.data.init.initTabLeft.length > 0 ) }, initNS:function(){ if( Libra.data && Libra.data.initNS ) return //TODO dove metterlo isAria = true Libra.config.init.initTabLeft = Libra.config.init.initTab Libra.data = Libra.merge( Libra.clone( Libra.config ), Libra.data ) Libra.data = Libra.merge( Libra.data, { initNS: true, images:{ noImage: Libra.data.path.virtualSite + 'resources/images/no-image.png' }}) //TODO Libra.data.init.initTabLeft.shift() //TODO togliere quando si fa app per developer //window.debug=Libra.data.user.group.s_5?console.log:()=>{} //TODO sistemare }, initDom:function(){ Libra.data.body = document.body HTMLElement.prototype.select = function( arg ){debug('js.Libra.Init.initDom.select',this,arg)} HTMLElement.prototype.destroy=function(arg){ let prnt = this.parentNode //delete all event listeners, bindings prnt.removeChild(this) if(prnt.vmd){ //el = this.vmd.body.removeChild( item ) //el = null //delete items[ i ] //delete item //delete el //this.vmd.items = this.vmd.items.filter( Boolean ) let index = prnt.vmd.items.indexOf(this); if(index !== -1) prnt.vmd.items.splice(index, 1) if(prnt.vmd.lastAddedItem===this)prnt.vmd.lastAddedItem=null prnt.fireEvent({ name:'delete',detail:{item:this}, bubles:false }) } if(this.vmd){ if( this.vmd.store && this.vmd.storeRegister ) this.vmd.store.unRegister( this ) if( this.vmd.menuNode){ this.vmd.menuNode.vmd.view=null delete( this.vmd.menuNode.vmd.view ) } this.vmd=null delete(this.vmd) if(this.viewModel){ this.viewModel.data=null delete(this.viewModel.data) this.viewModel=null delete(this.viewModel) } } return true } HTMLElement.prototype.next=function(arg){ let target switch( this.tagName ){ case 'LIBRA-TAB': let items = this.vmd.items if( items.length > 1 ){ /*let currentIndex = items.indexOf(this.itemSelected) let nextIndex = (currentIndex + 1) % items.length this.selectItem(items[nextIndex])*/ //items[nextIndex]; target = this.vmd.itemSelected[ arg ? 'previousElementSibling' :'nextElementSibling' ] while(target&&items.indexOf(target)<0){ target = target[ arg ? 'previousElementSibling' :'nextElementSibling' ] } debug('next target:',target) if(!target)target=this.vmd.itemSelected[ !arg ? 'previousElementSibling' :'nextElementSibling' ] this.selectItem(target) /*target = this.vmd.itemSelected[ arg ? 'previousElementSibling' :'nextElementSibling' ] if(!target)target = this.vmd.itemSelected[ !arg ? 'previousElementSibling' :'nextElementSibling' ] this.selectItem(target)*/ } break default: error('complete initDom:next for:',this) } } HTMLElement.prototype.prev=function(){return this.next(true)} HTMLElement.prototype.$=function(arg){return this.querySelector( arg )} HTMLElement.prototype.$$=function(arg){return this.querySelectorAll( arg )} HTMLElement.prototype.add = function( arg ){if(arg instanceof HTMLElement) return this.appendChild(arg);return Libra.Json.dom( arg, { parentNode: this })} HTMLElement.prototype.on = function( arg ){ let name=this.localName+'.on('+ arguments[0]+')' Object.defineProperty( arguments[1], "name", { value: name }) return HTMLElement.prototype.addEventListener.call( this, ...arguments ) } HTMLElement.prototype.up = function( arg ){arg = arg.toUpperCase(), pn = this.parentNode || this.libraParent; return pn && pn.tagName ? ( pn.tagName.match( new RegExp( arg )) ? pn : ( pn.up ? pn.up( arg ) : false )) : false } HTMLElement.prototype.upXtype = function( arg ){return this.up( Libra.data.dom.tagHaveViewModel.join( '|' )) || Libra } HTMLElement.prototype.downXtype = function( arg ){return this.$( Libra.data.dom.tagHaveViewModel.join( ',' ))} HTMLElement.prototype.querySelectorUp = function( arg ){ if( this.parentNode && this.parentNode.parentNode && this.parentNode.parentNode.up ){ let i, els = this.parentNode.parentNode.$$( arg ) for( i=0; i < els.length; i++ ) if(els[i]===this.parentNode) return this.parentNode return this.parentNode.up( arg ) } return false } HTMLElement.prototype.getViewController = function( arg = {}){ if( this.viewController )return this.viewController let pr = this.upXtype() //TODO implementare controller parent da saltare direttamente nodi while ( pr && !pr.viewController ) pr = pr.upXtype() if( pr.viewController && arg.property && !pr.viewController[ arg.property ]) return pr.getViewController( arg ) return pr.viewController || Libra.mainController } HTMLElement.prototype.getViewModel = function( arg = {}){ if( this.viewModel ) return this.viewModel let pr = this.upXtype() //TODO implementare controller parent da saltare direttamente nodi while( pr && pr !== Libra && !pr.viewModel ) pr = pr.upXtype() if( pr.viewModel && arg.property && typeof Libra.String.mapToObject( arg.property, pr.viewModel.data ) === 'undefined'/*!Libra.eval(arg.property,pr.viewModel.data)*//*pr.viewModel[arg.property]*/ ) return pr.getViewModel( arg ) return pr.viewModel || Libra } },"initClass":function(){ Event.prototype.getRow = function( arg ){ let i, node, e = this if( e.path ){for( i = 0; i < e.path.length; i++ ) if( e.path[ i ].tagName && e.path[ i ].tagName === 'TR' ){node = e.path[ i ]; break}} else if( e.originalTarget ){if( e.originalTarget.tagName === 'TD' ) node = e.originalTarget.parentNode; else if( e.originalTarget === 'TR' ) node = e.originalTarget } return node } String.prototype.eval = function( str, arg ){if( !arg ){arg = str; str = this } if( !arg ) arg = window; try { return ( new Function( 'return ' + str ).bind( arg )())} catch ( e ){return null }} String.prototype.evalObjectPath = function( str, arg ){if( !arg ){arg = str; str = this } str = str.replace( new RegExp( '.[0-9]+.|.[0-9]+|[0-9]+.', 'g' ), function( arg ){let e = arg[ arg.length-1 ] === '.'; return '[' + arg.replace( /[.]/g , '' ) + ( e ? '].' :']' )}) try{ return ( new Function( 'return ( this' + ( str[ 0 ] !== '[' ? '.' :'' ) + str + ')' ).bind( arg )())} catch ( e ){return null }} String.prototype.evalBind = function(sourceString,arg){ if( !arg ){ arg = sourceString; sourceString = this } arg.argBind = arg.argBind || {} arg.argBind.inverse = false arg.viewModel = Libra.getViewModel( arg.node ) // inverse begin sourceString = sourceString.match( /^{(.*)}$/ )[ 1 ] arg.argBind.inverse = sourceString.split( /^!/ ) if( arg.argBind.inverse.length === 2 ){ sourceString = arg.argBind.inverse[ 1 ]; arg.argBind.inverse = true } else arg.argBind.inverse = false // inverse end arg.argBind.sourceArray = sourceString.split( '.' ) switch( arg.argBind.sourceArray.length ){ case 1: arg.argBind.sourceProperty = arg.argBind.sourceArray[ 0 ] arg.argBind.source = arg.viewModel.getObject( arg.argBind/*{property:argBind.sourceProperty}*/) //TODO ricerca data dove c'e' property break default: arg.argBind.sourceProperty = arg.argBind.sourceArray[ arg.argBind.sourceArray.length - 1 ] if(arg.argBind.sourceProperty === 'text') arg.argBind.sourceProperty = 'textContent' arg.argBind.sourceArray.pop() arg.argBind.sourceString = arg.argBind.sourceArray.join( '.' ) arg.argBind.source = arg.viewModel ? arg.viewModel.getObject( arg.argBind ) : null break } return arg.argBind } String.prototype.firstToUpperCase = function( arg ){if( !arg ) arg = this; return arg[ 0 ].toUpperCase() + arg.slice( 1 )} String.prototype.bool = function( arg ){if( !arg ) arg = this; return /^\\s*(true|1|on)\\s*$/i.test( arg )} String.prototype.rtrim = function( str, arg ){if( !arg ){arg = str; str = this }; return str.substring( 0, ( str.length - arg ))} String.prototype.part = function( str, arg ){if( !arg ){arg = str; str = this } arg = Libra.merge({ delimiter:'.', what:'last' }, arg ) let strSplit = str.split( arg.delimiter ) switch( arg.what ){ case 'first': return strSplit.shift() case 'last': return strSplit.pop() case 'pop': strSplit.pop(); return strSplit.join(arg.delimiter) case 'objectProperty': //TODO ?? return { property: strSplit.pop(), object: strSplit.join( arg.delimiter )} }} /*let cn, is, cfg, data, cfgs = window.class, datas = Libra.data.class, parent = Object for( cn in cfgs ) if(!datas[cn]){let cne, parent cfg = cfgs[ cn ], ced = cfg.customElementsDefine, is = Libra.data.class.tagsIs.includes( ced ) cfgs[ cn ].classObjects=Libra.clone(Libra.data.class.classObjectsParentExclude) if( cfg.extends ){ cne = cfg.extends parent = datas[ cne ] || window[ cne ]} if( is ) cfg = Libra.Class.is( cfg ) data = datas[ cn ] = Libra.Class.getConstructor( cn, cne ) Object.defineProperty( data, "name", { value: cn }) Libra.Class.extend( data, cfg, parent ) cfg._libraClassName = cn cfg._libraBufferFn = {} cfg._libraConfigExtends = cne if( ced ) customElements.define( ced, data, is ? { extends: ced.replace( /^libra-/ , '' )} : null )}*/ let cfgs = window.class for( cn in cfgs ) cfgs[ cn ] = Libra.Class.init({ name: cn, cfg: cfgs[ cn ] }) Libra.data.class.binder.timeout = 0 Libra.mergeConfig(window,{"proxy class":{ //TODO deleteProperty set:function(target, name, val, receiver){return Libra.Class.init({ name: name, cfg: val })} }}) },"initAlias":function(){ Libra.modprobe = Libra.Modules.modprobe Libra.lsmod = Libra.Modules.lsmod Libra.rmmod = Libra.Modules.rmmod Libra.load = Libra.Network.load add = Libra.Json.dom get = id => document.getElementById( id ) },"initNw":function(){//TODO abilitare /* Libra.Modules.modprobe('network').then({fn:()=>{ Libra.Network.io=io(Libra.data.path.virtualSite.replace(/\\/$/,'')+':'+Libra.data.site.portWs) for(var _i in Libra.Bus.list) Libra.Network.io.on(Libra.Bus.list[_i], Libra.Bus[Libra.Bus.list[_i]])}})*/ },"initTemplate":function(){ let _tid=``, _s3=`${_s1}`, style = `` let template = ` ${_tid}container'>${_s1} ${_tid}pocket'>${_s1} ${_tid}carousel' >${_s1} ${_tid}menu' >${style}${_s1} ` Libra.Json.dom({ parentNode: document.body, tag:'div', html:template }) },"initDd":function(){ Libra.data.dd={} let body = document.body, dd = Libra.data.dd Libra.Dd={ "previewfile":function(file){ let dd=Libra.data.dd if( dd.tests.filereader === true && dd.acceptedTypes[ file.type ] === true){ var reader = new FileReader() reader.onload = function (event){ /* var image = new Image(); image.src = event.target.result; image.width = 48; //a fake resize holder.appendChild(image);*/ //TODO: complettare /*var gridEditor=_this.getGrid(); var _row=gridEditor.getStore().add(new Ext.data.Record({ date:'', ext:'jpg', icon:'OS\\/SHARE\\/images\\/icons\\/jpg-48.png', modified:'', path:'upload..', name:'upload..', size:'0', type:'file jpg'})); gridEditor.suspendEvents(); gridEditor.creatingNewDir = true; gridEditor.getView().refresh();*/ } reader.readAsDataURL(file) }else{ //holder.innerHTML += '

Uploaded ' + file.name + ' ' + (file.size ? (file.size/1024|0) + 'K' :''); } },"readfiles":function(arg/*,_this*/){ if( arg.files.length > 0 ){ let i, send={},dd=Libra.data.dd, formData = dd.tests.formdata ? new FormData() : null //Libra.data.upload = Libra.data.upload||Libra.Eav.getObject({info:true,objectName:'data.store.storeDocument.data'}); //arg.send.storeClassDataId=Libra.data.upload.objectModel.classId arg.send.path='server://Document/upload' arg.send.class='Document' arg.send.fn='upload' arg.send._bus='msg' arg.send.busData='server' arg.send.busDb='data' for( i = 0; i < arg.files.length; i++){ if(dd.tests.formdata) formData.append( 'file' , arg.files[ i ]) this.previewfile( arg.files[ i ]) var xhr = new XMLHttpRequest() xhr.onreadystatechange = function (rsc){ let res = rsc.target if( res.readyState == 4 && res.status == 200 ) Libra.Network.requestComplete(rsc,this) } xhr.open( 'POST', Libra.data.path.proxy + '?_libra=' + JSON.stringify( arg.send ) + '&' + encodeURIComponent( Libra.Network.getExtraParams())) xhr.send(formData) }}},"start":function(arg){ arg.send = arg.send || {} if(arg.record){ arg.send.targetBusDb=/*arg.obj._libra.busDb*/'data'//TODO arg.send._libraDocumentId = arg.record[ Libra.data.eav.id ] } arg.files = arg.event.dataTransfer.files this.readfiles( arg ) }} dd.fileupload = add({ parent: body, tag:'p', hidden:true, //stile:'display: none !important;', id:'_libraUpload', html:'' }) dd.filereader = add({ parent: body, tag:'p', hidden:true, //id:'_libraFilereader' }) dd.formdata = add({ parent: body, tag:'p', hidden:true, //id:'_libraFormdata' }) dd.tests = { filereader: typeof FileReader != 'undefined', dnd:'draggable' in document.createElement('span'), formdata: !!window.FormData, progress: "upload" in new XMLHttpRequest } dd.support = { filereader: dd.filereader /*document.getElementById('filereader')*/, formdata: dd.formdata/*document.getElementById('formdata')*/ } dd.acceptedTypes = { 'image/png': true, 'image/jpeg': true, 'image/gif': true } //fileupload = js.Libra.Dd.obj/*document.getElementById('upload')*/ "filereader formdata".split(' ').forEach(function (api){ let dd = Libra.data.dd if(dd.tests[api] === false) dd.support[api].className = 'fail'; else dd.support[ api ].className = 'hidden' }) body.on( 'dragover', /*Libra.debounce( */e => { let node e.preventDefault() if( e.target.tagName === 'LIBRA-TABLE' && e.target.dataset.editing === '1' ){ node = e.getRow() if( node ) e.target.selectItem( node ) } }/*, 100)*/) body.on('drop',function(e){ let arg={event:e} e.preventDefault() e.stopPropagation() /* let component=Libra.findComponentByElement(target), libraView=component.up('libraView'), libraViewArgXtype=libraView._libra.xtype, arg={event:event}*/ //if(libraViewArgXtype) //{ //let targetView=libraView.down(libraViewArgXtype) //arg.obj=targetView switch(e.target.tagName){ case 'LIBRA-TABLE': arg.row = e.getRow() debug(arg.row) arg.record = arg.row.record break case 'libraForm': debug('TODO DD FORM') arg.record=e.target.record break } //} Libra.Dd.start( arg ) return false },false) }}, clone:function(arg){ if( arg instanceof HTMLElement || typeof arg !== 'object' ) return arg let i, obj = arg instanceof Array ? [] : {} for( i in arg ){ if( arg && typeof arg[ i ] === 'object' && arg [ i ] instanceof Object ) obj[ i ] = Libra.clone( arg [ i ]) else obj[ i ] = arg [ i ] } return obj }, // merge:function(out,inp){ // if( !out ) return inp // for(let prop in inp ){ // let split = prop.split(' ') // if(split.length>1){ // out.__defineGetter__(split[1], inp.__lookupGetter__(split[1])) // out.__defineSetter__(split[1], inp.__lookupSetter__(split[1])) // } // if( typeof inp[ prop ] === 'object' ) out[ prop ] = Libra.merge( out[ prop ], inp[ prop ]); else out[ prop ] = inp[ prop ]; // } // return out // }, Notify:{"add":function(group,arg,args=null){ let i, cnt=Libra.data.notify.count debug('notify:',this,group,arg,args,this.btn) /*let store = Libra.data.store.storeMessage, msg //TODO abilitare if( !Array.isArray( arg )) arg = [ arg ] for( i in arg ){ msg = { text: group, _libraObject: arg[ i ], description: JSON.stringify( arg[ i ])} if( store.add ) store.add( msg ) else store.data.push( msg )} if( this.btn ){ this.btn.incBadgeText( cnt ) cnt = 0}else cnt++*/ }}, Class:{ classObjects:function(arg){ if( arg === this.constructor.name ){ let i, cfg = window.class[ arg ], data = cfg.classObjects for( i in data ) this[ data[ i ] ] = Libra.clone( window.class[ arg ][ data[ i ] ]) } return this }, addMethod:function(arg){ let cfg = arg.cfg , target = arg.target, method = arg.method if( !Libra.data.class.prototypeExclude.includes( method )){ if( cfg.static && cfg.static.includes( method )) targetForMethod = target; else targetForMethod = target.prototype if( method.trim().indexOf(' ') !== -1 ){ let gs = method.trim().split(' ') if( gs[ 0 ] === 'get' ) targetForMethod.__defineGetter__( gs[ 1 ], cfg[ method ]) else targetForMethod.__defineSetter__( gs[ 1 ], cfg[ method ]) }else switch (typeof cfg[ method ]){ case 'function': targetForMethod[ method ] = cfg[ method ]; Object.defineProperty( targetForMethod[ method ], "name", { value: method }); break case 'object': default:arg.cfg.classObjects.push( method ); break }} }, getConstructor:function(cfg,cn,cne=null){ if( cfg.hasOwnProperty( 'constructor' )) cfg._constructor = cfg.constructor delete( cfg.constructor ) let cc = ( cfg.hasOwnProperty( '_constructor' ) ? "window.class." + cn + "._constructor.call( that, arguments );" : "" ) if( cne ) return ( new Function( "let that = Reflect.construct( window." + cne + " || Libra.data.class." + cne + ", arguments, this.constructor ); that = Libra.Class.classObjects.call( that, '" + cn + "' );" + cc + "return that" )) return cfg._constructor }, extend:function( child, prototype, parent ){ if( !parent ) parent = Object let i, cfg = window.class[ parent.name ] child.prototype = Object.create( parent.prototype ) child.prototype.constructor = child if( cfg ) for( i in cfg.static ){ arg = { target: child, cfg:{ static: [] }, method: cfg.static[ i ] } arg.cfg.static.push( arg.method ) arg.cfg[arg.method] = cfg[ arg.method ] Libra.Class.addMethod( arg ) } for( i in prototype ) if( prototype.hasOwnProperty( i )) Libra.Class.addMethod({ target: child, cfg: prototype, method: i }) let cfgParent = cfg if( cfgParent ){ let name for( i in cfgParent.classObjects ){ name = cfgParent.classObjects[ i ] if( !Libra.data.class.classObjectsParentExclude.includes( name )){ if(!prototype[name]) prototype.classObjects.push( name ) prototype[ name ] = prototype[ name ] ? Libra.merge( Libra.clone( cfgParent[ name ]), prototype[ name ]) : Libra.clone( cfgParent[ name ])}}} Libra.Class.super( child, parent ) }, super:function(Child1,Parent1){ let proto1 if( Child1.prototype ) proto1 = Child1.prototype; else proto1 = Child1 proto1.super = function( fn ){ let parent, pt = this, cfg = window.class if( !fn ) fn = arguments.callee.caller.name if( !pt._libraBufferFn[ fn ]){ pt.extends = pt._libraConfigExtends while ( cfg[ pt.extends ] && !cfg[ pt.extends ].hasOwnProperty( fn )) pt.extends = cfg[ pt.extends ].extends if( !cfg[ pt._libraClassName ].hasOwnProperty( fn )){ pt.extends = cfg[ pt.extends ].extends while ( cfg[ pt.extends ] &&! cfg[ pt.extends ].hasOwnProperty( fn )) pt.extends = cfg[ pt.extends ].extends } }else while ( cfg[ pt.extends ] && !cfg[ pt.extends ].hasOwnProperty( fn )) pt.extends=cfg[ pt.extends ].extends if( cfg[ pt.extends ]){ parent = cfg[ pt.extends ], ptPnt = parent let oldExtends = pt.extends pt.extends = ptPnt.extends if( !ptPnt.hasOwnProperty( fn )) error( 'prototype ' + oldExtends + ' has no function:' + fn ) pt._libraBufferFn[ fn ] = 1 ptPnt[ fn ].call( this, ...arguments.callee.caller.arguments ) pt.extends = oldExtends delete( pt._libraBufferFn[ fn ]) }else error( 'prototype ' + pt.extends + ' has no function:' + fn ) } }, is:function( arg ){ arg = Libra.merge( arg, { constructor:function(){this._doNotapplyBindOnCreateNode = 1 }, debug:Libra.data.class.libraContainer.prototype.debug, connectedCallback:function(){ //TODO provare spostare binding in dom let text, bind, ds = this.dataset this.id = this.id || Libra.getId() if(this.getAttribute( 'is' ) === 'libra-codearea' ){//TODO this.render=function(){ //this.classList.add('card-header') let cfg = { readOnly:false//!!me.readOnly,//'{readOnly}' ,lineWrapping: true, lineNumbers: true, tabSize: 4, indentUnit: 4 //, mode: "javascript" //,bind:{theme:'{libraCodeMirror.theme}'} ,mode: "application/x-httpd-php-open" ,gutters: ["CodeMirror-lint-markers"], lint: true ,styleActiveLine: true, matchBrackets: true } //TODO controllare if( Libra.data.user.libraEditorCode.theme ) cfg.theme = Libra.data.user.libraEditorCode.theme CodeMirror.modeURL = Libra.data.modules.codemirror.pathLib + 'mode/%N/%N.js' this.editor = CodeMirror.fromTextArea( this, cfg) if(this.className)this.editor.display.wrapper.className+=' '+this.className this.editor.display.wrapper.className+=' '+'border indent' //if(this.onInitEditor)this.onInitEditor(this.editor) //this.editor.setValue(this.record) //vmd.form.classList.add( 'h-100' ) //vmd.editor.display.wrapper.classList.add( 'h-100' ) }} if( this.requires && ( this.requires.mod.length || this.requires.class.length )){//TODO complettare this._wait = true for( i in this.requires.mod ) Libra.modprobe( this.requires.mod[ i ]).then({ fn: () => { this.render();if(this.onRender)this.onRender(this)}}) //return false } if( this.tagName === 'BUTTON' ){ this.classList.add( 'btn' ) if( this.href ) this.on( "click", e => Libra.Utils.analizeNode(this) ) if( ds.toggling ){ ds.pressed = ds.pressed || '0' this.value = ds.pressed.eval() this.on( "click", e => this.value = !this.value )}} if([ 'BUTTON','A'].includes( this.tagName )){ this.classList.add( 'cp' ) //if( ds.pressed ) this.classList.add( 'active' ) if( ds.ui ) this.classList.add( 'btn-' + ds.ui ) if( ds.iconCls ) this.classList.add( 'fa', ds.iconCls ) if( this.childNodes.length || this.innerHTML != '' || this.textContent != '' ) this.classList.add( 'famr' ) if( this.hasAttribute( 'hash' )) ds.hash = this.getAttribute( 'hash' ) if( ds.hash ){this.on( "click", e => location.hash = ds.hash )}} if( ds.reference ) this.getViewModel().setReference( ds.reference, this ) if( ds.bind ) bind = ds.bind if( this.bind ) bind = this.bind if( bind ) Libra.Dom.bind({node: this, bind: bind }) }}) //TODO spostare nella class if(arg.extends==='HTMLButtonElement'){ /*arg = Libra.merge( arg, { getValue:function(){return this.dataset.pressed.eval()}, "get value":function(arg){debug('qui',arg,this);return this.dataset.pressed.eval()}, "set value":function(a){this.dataset.pressed=a;this.classList[a?'add':'remove']( 'active' )}})*/ arg.getValue=function(){return this.dataset.pressed.eval()} arg["get value"]=function(arg){/*debug('qui',arg,this);*/return this.dataset.pressed.eval()} arg["set value"]=function(a){this.dataset.pressed=a;this.classList[a?'add':'remove']( 'active' )} } return arg },"init":function(arg){ let cn=arg.name, is, cfg=arg.cfg, data, cfgs = window.class, datas = Libra.data.class, parent = Object if(!datas[cn]) { let cne, parent, //cfg = cfgs[ cn ], ced = cfg.customElementsDefine, is = ced?Libra.data.xtype[ced.replace(/^libra-/,'')].is:null cfg.classObjects = Libra.clone( Libra.data.class.classObjectsParentExclude ) if( cfg.extends ){ cne = cfg.extends parent = datas[ cne ] || window[ cne ] } if( is ) cfg = Libra.Class.is( cfg ) data = datas[ cn ] = Libra.Class.getConstructor( cfg, cn, cne ) Object.defineProperty( data, "name", { value: cn }) Libra.Class.extend( data, cfg, parent ) cfg._libraClassName = cn cfg._libraBufferFn = {} cfg._libraConfigExtends = cne //TODO sistemare if( ced ) customElements.define( ced, data, is ? { extends: ced==='libra-codearea'?'textarea':ced.replace( /^libra-/ , '' )} : null ) } return cfg }}, Modules:{ loaded:function( arg ){ Libra.Network.sessionCheck({ 'session': arg.session, pathLibra: arg.moduleName }, true ) Libra.data.modules.loaded[ arg.moduleName ] = true }, modprobe:function( arg ){ let session = 'module' + Libra.getSessionId() let ret = [] if( typeof arg === 'string' ) arg = [ arg ] Libra.data.network.session[ session ] = { path:{}, owner:'modprobe' } arg.forEach( function( item ){ if( Libra.data.modules.loaded[ item ] === true ) return false try { Libra.data.network.session[ session ].path[ item ] = item ret.push(Libra.Modules[ item ]( session )) } catch( err ){ error( 'module ' + item + ' is not loaded successfully' ) debug( err ) delete( Libra.data.network.session[ session ]) Libra.data.modules.loaded[ item ] = false } }) Libra.Network.sessionCheck({ 'session': session }, true ) return { then:function( arg ){ if( !arg.fn ) error( 'error: then must be {fn:..,scope:..}' ) if( Libra.data.network.session[ session ]) Libra.data.network.session[ session ].cb = arg else arg.fn.call( arg.scope, ret ) } } },"network":function( arg ){ Libra.Network.load({ cache: true, charset: "iso-8859-1", path: Libra.data.path.fw + "socket.io/socket.io.slim.bs.js" },{ fn: () => Libra.Modules.loaded({ session: arg, moduleName:'network'})}) }}, Network:{ load:function( arg, args = { session: null, fn: null, scope: null }){ let i, j, ext, path, script, prior, session if( typeof args !== 'object' ) error( 'Loader.load: args is incorrect' ) if( typeof arg.path === 'undefined' ){error( 'load:arg.path is needed' ); return false } if( !Array.isArray( arg.path )) arg.path = [ arg.path ] if( args.fn || args.session ){ session = args.session || Libra.getSessionId() Libra.data.network.session[ session ] = { cb:args, path:{}} } for( i in arg.path ){ path = ( arg.pathPrefix ? arg.pathPrefix :'' ) + arg.path[ i ] if( session ) Libra.data.network.session[ session ].path[ path ] = false if( arg.cache && Libra.Network.isLoaded( path )){ if( session ) delete( Libra.data.network.session[ session ].path[ path ]) continue } ext = path.split( '.' ) ext = ext[ ext.length-1 ].toLowerCase() switch ( ext ){ case 'css': script = document.createElement( 'link' ); prior = document.getElementsByTagName( 'head' )[ 0 ]; script.rel = 'stylesheet';/* script.media = 'screen' */ break case 'js': case 'php': default: script = document.createElement('script'); prior = document.getElementsByTagName('script')[ 0 ]; break } script.async = Libra.data.network.asyncMode script.pathLibra = path if( session ) script.session = session prior.parentNode.insertBefore( script, prior ) script.onerror = function(){Libra.Network.sessionCheck( this, false ); delete( Libra.data.network.session[ this.session ])}//TODO error script.onload = script.onreadystatechange = function( _, isAbort ){ if( isAbort || !/*script*/this.readyState || /loaded|complete/.test( script.readyState )){ this.onload = this.onreadystatechange = null if( !isAbort ){Libra.data.network.loaded[ this.pathLibra ] = 1; if( this.session ) Libra.Network.sessionCheck( this, true )} else{ Libra.data.network.loaded[this.pathLibra]=0; if( this.session ) delete( Libra.data.network.session[ this.session ])} } } let extraParams = Libra.Network.getExtraParams() if( session ) extraParams._libraCbSession = session let strArr=[] for( j in extraParams ) strArr.push( j + '=' + extraParams[ j ]) path += ( path.includes( '?' ) ? '&' :'?' ) + strArr.join( '&' ) switch( ext ){ case 'css': script.href = path; break case 'js': case 'php': default: if( arg.charset ) script.charset = arg.charset script.src = path break } } return session }, sessionCheck:function( arg, load ){ let i = Libra.data.network.session, j = arg.session if( i[ j ]){ delete( i[ j ].path[ arg.pathLibra ]) if( Object.keys( i[ j ].path ).length === 0 ){ if( i[ j ].cb ) i[ j ].cb.fn.call( i[ j ].cb.scope, i[ j ].return, load ) delete( i[ j ]) } } },"send":function(_bus,_data=null,args={url:null,fn:null,scope:null}){ let msg = { _bus: _bus, _userId: Libra.data.user.id, _siteId: Libra.data.site.id, CID: Libra.Cookie.get( 'CID' ) }, _cb = args.fn, _scope = args.scope if( _data ) msg._libra = _data //TODO rifare bene if( args.params ) msg = Libra.merge( msg, args.params ) if( args.extraParams ) msg = Libra.merge( msg, args.extraParams ) msg = Libra.merge(msg, this.getExtraParams()) if( msg._libra && typeof msg._libra === 'string' ) msg._libra = JSON.parse( msg._libra ) if( _cb ){ msg._cbId = 'cb' + Libra.getSessionId() //TODO unire con delle sessioni esistenti Libra.data.requestCb[ msg._cbId ] = { fn: _cb, scope: _scope } } if( Libra.data.network.sync ){ msg._bus = _bus debug( 'emit', _bus, msg ) return this.io.emit( _bus, msg ) } else{ //delete(msg._bus); msg._nwVector = 'http' msg._libra = JSON.stringify( msg._libra ) let _request = { url: args.url || Libra.data.path.proxy, method:'POST',//'POST','GET' //jsonData:msg params: msg/*Ext.util.JSON.encode(msg)*/ ,success: this.requestSuccess ,failure: this.requestFailure //,headers:{ //'Content-Type':'application/json' //} ,useDefaultXhrHeader: false ,cors: true //,withCredentials: false //,crossDomain: true //,callback:Client.Network.requestFailure (options,success,response) //,callback:_cb //,scope:_scope } debug( 'send', _bus, msg ) msg._libra = encodeURIComponent( msg._libra ) let _fetch = fetch( args.url || Libra.data.path.proxy , { method:'POST', body: JSON.stringify( msg ) }).then( response => { //TODO elaborare status _fetch.responseClone = response.clone() return response.json() }).then( responseJson => { //TODO elaborare status return Libra.Network.requestComplete( _fetch.responseClone ,responseJson ) }).catch( debug )/*.catch(function(response){ Libra.Network.requestFailure(response)})*/ return _fetch } }, getExtraParams:function(){ /*TODO group developer */ let _return = { _siteId: Libra.data.site.id, _lang: Libra.data.user.lang, _userId: Libra.data.user.id, CID: Libra.Cookie.get( 'CID' ), LibraNamespace: Libra.data.site.LibraNamespace, _nwVector: Libra.data.network.sync ? 'ws' : 'http' } //TODO if(Libra.data.network.sync) _return._nwId=Libra.data.network.id if( Libra.data.debug._libraDebug ) Libra.merge( _return, Libra.data.debug ) return _return },"requestComplete":function ( conn, response, opt, eOpts ){ let responseJson={} if( response.responseJson ) responseJson = response.responseJson else if( response.responseText ){ if( response.responseText.charAt( 0 ) === '<' ) return Libra.Bus.debug( response.responseText,{ conn: conn, response: response, opt: opt, eOpts: eOpts }) //TODO send to error non debug if( response.responseText.charAt( 0 ) === Libra.data.regex.braceBegin ) responseJson = JSON.parse( response.responseText ) } else responseJson = response Libra.Bus.msg( responseJson, {conn: conn, response: response,opt: opt,eOpts: eOpts }) },"handlerCb":function(resp){ if(Libra.data.requestCb[resp._cbId]){ //TODO analizzare response callback var cb=Libra.data.requestCb[resp._cbId] //with(Libra.data.requestCb[resp._cbId]){ if(cb.scope) cb.fn.call(cb.scope,resp) else cb.fn(resp) //} //var _resCb=Libra.data.requestCb[resp._cbId].fn.apply(Libra.data.requestCb[resp._cbId].scope,resp); delete(Libra.data.requestCb[resp._cbId]) } },"isLoaded":function( arg ){ if( Libra.data.network.loaded[ arg ] && Libra.data.network.loaded[ arg ] === 1 ) return true return false }}, Json:{ encode:function( obj, _a = function( key, val ){ let regex = Libra.data.regex if( typeof val === 'function' ){ val =val + '' if( val.slice( -4 ) === regex.functionFineTo ) val=val.rtrim( 4 ) + regex.braceEnd val = val.rtrim( 1 ) + regex.functionFineTo } return val },_b=null){ return JSON.stringify(obj,_a,_b) }, decode:function( str, _a = function( key, val ){ if( typeof val === 'string' && val.substring( 0, 9 ) === 'function(' ){ val = val.rtrim( 4 ) + Libra.data.regex.braceEnd val = eval( "fn=" + val ) } return val }){ return JSON.parse(str,_a) }, transformLang:function( obj, prop, val ){ let res = lang( val ) if( res ) obj[ prop === 'lang' ? ( Libra.isHTML( res ) ? 'html' : 'text' ) : prop ] = res return obj }, transform:function(arg){ if( arg.viewName ) if( data.view[ arg.viewName ]){let _vn = arg.viewName; delete( arg.viewName ); arg = Libra.merge( arg, data.view[ _vn ] )} else error('configure: view: ', arg.viewName) let i, arr if( arg.lang ){ if(typeof arg.lang === 'object') for( let i in arg.lang ) arg = this.transformLang( arg, i, arg.lang[ i ] ) else arg = this.transformLang( arg, 'lang', arg.lang ) } if( arg.text ){ if( !arg.nodeType && !arg.tag && !arg.xtype ){arg.nodeType = 3; arg.nodeValue = arg.text } else arg.textContent = arg.text } arg.nodeType = arg.nodeType || 1 arg.attributes = arg.attr || {} if( arg.xtype ){ let xtype = Libra.data.xtype[ arg.xtype ] if( xtype.is ){ //TODO sistemare arg.tagName = xtype.transform || arg.xtype arg.is = 'libra-' + arg.xtype arg.attributes.is = arg.is }else arg.tagName = 'libra-' + arg.xtype } //if(arg.bind&&typeof arg.bind!=='string') arg.bind=JSON.stringify(arg.bind) arr = { items:'childNodes', tag:'tagName', parent:'parentNode' } for( i in arr ) if( arg.hasOwnProperty( i )) arg[ arr[ i ] ] = arg[ i ] arr = { disabled:1, form:1, scope:1, slot:1, hidden:1, title:1, name:1, type:1, cls:'class', css:'style' } for( i in arr ) if( arg.hasOwnProperty( i )) arg.attributes[ ( arr[ i ] === 1 ? i : arr[ i ])] = arg[ i ] arr = { tabbed:1,hash:1,toggling:1,pressed:1,propertyValue:'property-value',statusing:1,hideTrigger:1,view:1, closing:1, tabTitle:'tab-title',viewTitle:'view-title', tpl:'template',tplName:'template-name', layout:1,/*bind:1,*/ cmd:1, ref:'reference', ui:1, select:1, editing:1, checking:1, filtering:1, storeName:'store-name', modelName:'model-name', iconCls:'icon-cls', recordId:'record-id' } arr[ Libra.data.eav.id ] = Libra.data.eav.idAttr arr[ Libra.data.eav.key ] = Libra.data.eav.keyAttr for( i in arr ) if( arg.hasOwnProperty( i )) arg.attributes[ 'data-' + ( arr[ i ] === 1 ? i : arr[ i ])] = arg[ i ] if( !arg.tagName ) arg.tagName = 'div' return arg }, dom:function( objs, arg = { parentNode:null, appendChild:true, scope:null }){ let parentNode, objsKey, obj, node, nodeType, i, j, len, viewController, isArray = false, ret = [], arr = { bind:1,watch:1,/*modelName:1,*/autocomplite:1,checked:1,href:1,unselectable:1,onselectstart:1,onmousedown:1,placeholder:1,action:1,for:1,src:1,eventDetail:1,vmd:1,itemName:1,target:1,arguments:1,adding:1,/*_linkedNode:1,_linkedView:1,_linkedViewTarget:1,*/_isTabbed:1,width:1,value:1,treeParent:1,name:1, libraEventTarget:1, oldClass:1, id:1, is:1, record:1, renderBodyItemDone:1, columnKey:1, tabBody:1, /*rendered:1,*/ tbar:1, _libra:1, store:1, /*propertyValue:1,*/ html:'innerHTML', textContent:1, viewModel:1, renderChange:1,viewController:1,_itemKey:1,wmMenuViewSilent:1,defaults:1,requires:1, type:1 } //TODO forse aggiungere tutti? array di variabili che vengono passate direttamente in dom if( typeof objs === 'string' ) try{ objs = JSON.parse( objs )} catch ( e ){ if(Libra.isHTML(objs)) objs = {html:objs};else objs = {text:objs} } isArray = Array.isArray( objs ) if( !isArray ) objs = [ objs ] for( objsKey in objs ){ obj = objs[ objsKey ] if( arg.defaults ) obj = Libra.merge( Libra.clone( arg.defaults ), obj ) // obj.tag=obj.tag||'div' if( !obj.nodeType ) obj = Libra.Json.transform( obj ) nodeType = obj.nodeType parentNode = obj.parentNode || arg.parentNode //TODO per errore; togliere in futuro if(parentNode&& !(parentNode instanceof HTMLElement||parentNode instanceof ShadowRoot)){error('parentNode is not HTMLElement: obj:',objs, 'arg:',arg,'node:',node,'parentNode:',parentNode); delete(parentNode);parentNode=null} switch ( nodeType ){ case 1: /* ELEMENT_NODE */ node = document.createElement( obj.tagName, obj.is && Libra.data.xtype[ obj.is.replace( /^libra-/, '' ) ].is ? { is:obj.is } : null ) if( parentNode ) Object.defineProperty( node, 'parentNode', { value: parentNode }) for( i in obj.attributes ) if( !( !isAria && i.match( /^aria-/ ))) node.setAttribute( i, obj.attributes[ i ]) break //TODO togliere tpl case 3: /* TEXT_NODE */ if( obj.nodeValue ) node = document.createTextNode( obj.nodeValue )/*; else if( obj.libraTpl ) node = document.createTextNode( Libra.fillTemplate( obj.libraTpl ,arg.scope )); */;break case 8: /* COMMENT_NODE */ node = document.createComment( obj.nodeValue ); break case 9: /* DOCUMENT_NODE */ node = document.implementation.createDocument(); break case 10: /*DOCUMENT_TYPE_NODE */ node = document.implementation.createDocumentType( obj.nodeName ); break case 11: /* DOCUMENT_FRAGMENT_NODE */ node = document.createDocumentFragment(); break default: return node } if( !parentNode && !arg.before && !arg.after ) error( 'warning: parentNode is ubsent:', obj, node ) for( i in arr ) if( obj.hasOwnProperty( i )){ j = ( arr[ i ] === 1 ? i : arr[ i ]) node[ j ] = node.hasOwnProperty( j )? Libra.merge( node[ j ], obj[ i ]) : obj[ i ] } ret.push( node ) if( obj.events ){ for( let eventName in obj.events ){ switch( eventName ){ case 'render': setTimeout( function(){this.fn.call( this.node )}.bind({ fn: obj.events[ eventName ],node: node }), 0 ) break default: let fn = obj.events[ eventName ] if( typeof fn=== 'string' ){ viewController = node.getViewController({ property: fn }) if( viewController )node.on( eventName, viewController[ fn ]); else error( 'function ' + fn + ' is not declared for node ' + node ) } else node.on( eventName, fn ) break }}} if( arg.appendChild !== false ){ if( parentNode ){parentNode.appendChild( node ); if( parentNode.viewModel ) parentNode.viewModel.data.lastAddedItem = node } else if( arg.before ) arg.before.before( node ) else if( arg.after ) arg.after.after( node ) } if( obj.handler ){ if( typeof obj.handler === 'function' ) node.on( 'click', obj.handler ) else{ viewController = node.getViewController({ property: obj.handler }) if( viewController[ obj.handler ]) node.on( 'click', viewController[ obj.handler ]) else error('dom: handler:' + obj.handler + ' is not defined in viewController') }} if( obj.bind && !node._doNotapplyBindOnCreateNode ) Libra.Dom.bind({ node: node, bind: obj.bind }) if( nodeType === 1 || nodeType === 11 ){ let childNodes = obj.childNodes || [], defaults = obj.defaults || {} for( i = 0, len = childNodes.length; i < len; i++ ){ let childNode = childNodes[ i ], addedNode, argChild if( childNode.localName ) addedNode = node.appendChild( childNode ) //TODO applicare forse renderItem??? else{ childNode = Libra.merge( Libra.clone( defaults ), childNode ) if( childNode.bind ) childNode.bind = childNodes[ i ].bind delete( arg.parentNode ) argChild = Libra.clone( arg ) delete( argChild.defaults ) argChild.parentNode = node argChild.appendChild = true if( node.template ){ childNode = node.template.use({ self: node, scope: childNode }) argChild.parentNode = node.viewModel.data.body } addedNode = Libra.Json.dom( childNode, argChild ) }}} } return isArray ? ret : ret[ 0 ] }}, getViewModel:function(node){ return node.viewModel ? node.viewModel : ( node.getViewModel ? node.getViewModel() : null )}, Dom:{ bind:function(arg){ let t = { text:'textContent', html:'innerHTML' } for( let i in t ) if( arg.bind[ i ] ){ arg.bind[ t[ i ]] = arg.bind[ i ] delete arg.bind[ i ] } if( !arg.node.id ) arg.node.id = Libra.getId() let bindKey, bindJson = null, argBindAll = {} if( typeof arg.bind === 'string' ){ try{ bindJson = JSON.parse( arg.bind )} catch ( e ){ bindJson = arg.bind } if( typeof bindJson === 'string' ){ //shema semplificata di configurazione senza indicare proprietà su cosa viene bindato; portarlo alla configurazione necessaria arg.bind = {} switch( arg.node.tagName ){ case 'LIBRA-FORM': targetProperty = 'record'; break case 'INPUT': targetProperty = 'value'; break default: targetProperty = 'textContent'; break } arg.bind[ targetProperty ] = bindJson }else arg.bind = bindJson } for( bindKey in arg.bind ){ let sourceString = arg.bind[ bindKey ], createTextNode = false, argBind = {} if( typeof sourceString === 'string' ) argBind = sourceString.evalBind({ node: arg.node }) //TODO COMPLETTARE get source where get value /*if(source.split(/^this./)[1]){ //binding per this. riferito al oggetto stesso - al node target=arg.node source=source.split(/^this./)[1] }else if(source.split(/^reference.|data./)[1]){ //binding riferito al Libra target=Libra.data} else{ let viewModel=arg.node.getViewModel({property:source}) target=viewModel.data}*/ else{ argBind = Libra.merge( argBind, sourceString ) if( sourceString.source ) argBind.source = sourceString.source } argBind.value = argBind.source[ argBind.sourceProperty ] argBind.target = arg.node switch ( arg.node.tagName ){ case 'BUTTON': case 'LIBRA-A': case 'LIBRA-MENU': case 'LABEL': if( bindKey === 'textContent' ) createTextNode = true argBind.targetProperty = 'textContent' break default: argBind.targetProperty = bindKey break } //if(arg.node.nodeType===3)argBind.targetProperty='nodeValue' let fn = function( arg ){this.node[ this.property ] = this.inverse ? !arg : arg }.bind({ inverse: argBind.inverse, property: argBind.targetProperty, node: argBind.target }) if(arg.node.nodeType===3)argBind.fn = fn if( createTextNode && !arg.node.childNodes.length ){ argBind.target = arg.node.appendChild( arg.node.tagName==='LIBRA-MENU'?document.createElement('a'):document.createTextNode( arg.value )) argBind.target.id = arg.node.id + '-text' //TODO sistemare fn argBind.fn = fn } switch ( bindKey ){ //case 'eventEmitter': //case 'eventListener': /*case 'bindEvent': argBind.value.vmd.bindEvent = arg.node break*/ case 'class': case 'cls': //if(!argBind.target.id)argBind.target.id=Libra.getId() argBind.targetProperty = bindKey argBind.fn = function( arg ){ let _set = ' ' + arg this.node.bindedClass =this.node.bindedClass || '' if( arg ) this.node.className = this.node.className.replace( this.node.bindedClass,'' ) + _set else this.node.className = this.node.className.replace( this.node.bindedClass, '' ) this.node.bindedClass = _set }.bind({ inverse: argBind.inverse, property: argBind.targetProperty, node: argBind.target }) break; case 'hidden': case 'disabled': //TODO sistemare fn //if(!argBind.target.id)argBind.target.id=Libra.getId() argBind.targetProperty = bindKey argBind.fn = function( arg ){ this.node[ this.property ] = this.inverse ?!arg : arg }.bind({ inverse: argBind.inverse, property: argBind.targetProperty, node: argBind.target }) break } if( !( argBind.sourceProperty in argBind.source ) && argBind.source.viewModel ){argBind.sourceObject = argBind.source; argBind.source = argBind.source.viewModel.data } if( !( argBind.targetProperty in argBind.target ) && argBind.target.viewModel ){argBind.targetObject = argBind.target; argBind.target = argBind.target.viewModel.data } switch ( bindKey ){ case 'store': arg.node.viewModel.data.getStore = function(arg){ if( !arg.value.register ) arg.value = Libra.getStore( arg.value ) return arg.value }.bind( arg.node ) arg.node.viewModel.data.setStore = function(arg){ arg.valueOld.unRegister( this ) //TODO unregister setTimeout(() => this.reload(), 0) }.bind( arg.node ) break } Libra.bind( argBind ) argBindAll[ bindKey ] = argBind } return argBindAll }, json:function(node){ node = node || this let i, obj = { nodeType: node.nodeType } if( node.tagName ) obj.tagName = node.tagName.toLowerCase() else if( node.nodeName ) obj.nodeName = node.nodeName if( node.nodeValue ) obj.nodeValue = node.nodeValue let attrs = node.attributes if( attrs ){ let arr = obj.attributes = {}, length = attrs.length for( i = 0; i < length; i++ ) arr[ attrs[ i ].nodeName.toString() ] = attrs[ i ].nodeValue } let childNodes = node.childNodes if( childNodes ){ length = childNodes.length arr = obj.childNodes = new Array( length ) for( i = 0; i < length; i++ ) arr[ i ] = Libra.Dom.json( childNodes[ i ]) } return obj } }, getId:function(that){ Libra.data.idCounter++; return 'libra-' + Libra.data.idCounter.toString() }, getObject:function(arg){ if( !arg.sourceString && !arg.sourceProperty ) error( 'libraViewModel:getObject' ) if( arg.sourceString ) arg.source = ( 'this.' + arg.sourceString ).eval( Libra.data ) else arg.source = this.data if( arg.source ){ arg.value = arg.source[ arg.sourceProperty ] return arg.source } return null }, bind:function(arg){ arg.sourceProperty = arg.sourceProperty || arg.property arg.targetProperty = arg.targetProperty || arg.sourceProperty let value = arg.target.nodeType === 3 ? arg.target.nodeValue : arg.target.text if( !( arg.sourceProperty in arg.source )) arg.source[ arg.sourceProperty ] = arg.value if( !arg.source._binder ) arg.source = new Libra.data.class.binder( arg.source ) if(arg.fn) arg.source._watch( arg.sourceProperty, arg.fn , 0, arg.target) else{ if( !arg.target._binder ) arg.target = new Libra.data.class.binder( arg.target ) arg.source._bind( arg.sourceProperty, arg.target, arg.targetProperty ) } if( arg.hasOwnProperty( 'value' )){ let value = ( typeof arg.value === 'function' ? arg.value.call(arg.source) : arg.value ) arg.target[ arg.targetProperty ] = arg.inverse ? !value : value } if( arg.sourceString && arg.sourceString.match( /^user./ )){ arg.source._libraObjectName = arg.sourceString + '.' + arg.sourceProperty arg.source._libraSync = 1 } if( arg.target.watch ){ let argWatch = arg.target.watch.evalBind({node:arg.target}) debug('_watch',arg.sourceProperty, argWatch.value) arg.source._watch( arg.sourceProperty, argWatch.value/*,0,arg.target*/) } return arg }, Layout:{ row:function(that){that.classList.add( 'd-flex', 'flex-row' )}, column:function(that){that.classList.add( 'd-flex', 'flex-column' )}, fit:function(that){that.classList.add( 'w-100', 'h-100' )}, view:function(that){that.classList.add( 'w-100', 'h-100' )}, buttongroup:function(that){that.setAttribute( 'role','group' ); that.classList.add( 'btn-group' ); if( that.dataset.ui ) that.classList.add( 'btn-' + that.dataset.ui )} }, Template:{ get:function( arg ){return Libra.data.template[ arg ] || new Libra.data.class.libraTemplate({ name: arg })}, use:function( arg ){return Libra.Template.get( arg.name ).use( arg )} }, getStore:function(cnf){if( typeof cnf === 'string' ) cnf = { name: cnf }; return Libra.data.store[ cnf.name ] || new Libra.data.class.libraStore( cnf )}, Eav:{ busDb:function( arg ){ if( typeof arg === 'object' ) arg = arg.targetName||arg.objectName || arg.storeObjectName if( arg ) switch( arg.part({ what:'first' })){ case 'lang': return 'lang' case 'php': return 'server' case 'user': return 'user' case 'data': return 'data' case 'app': return 'app' case 'js': case 'X': return 'client' default: return 'client' } else return 'data' },"depth":function(arg){ let i, depth, level = 1 for( i in arg ){ if( !arg.hasOwnProperty( i )) continue if( typeof arg[ i ] === 'object' ){ depth = Libra.Eav.depth( arg[ i ]) + 1 level = Math.max( depth, level )}} return level },"save":function(obj,args={fn:null,group:Libra.data.groupEveryone,scope:null}){ debug('eav:save',obj,args) if(typeof obj==='string'){ var _LibraTagFunction=[], _LibraTagFunctionSource=[], _LibraTagFunctionSourceLink=[], _LibraTagFunctionValueSource=[], _LibraTagFunctionName=[], _LibraTagFunctionLang=[], _LibraTagFunctionArgs=[], tag="var _LibraTagFunction=", js = false try{ obj=eval('object='+obj+';') js=true }catch(err){} if(js===false){ obj=obj.replace(new RegExp(Libra.data.regex.sourceLang,"g"),function(a,lang,args,e,code,g){ code=code.replace(new RegExp(Libra.data.regex.delimiterSourceLangPhpBeginRe,"gm"),'') code=code.replace(new RegExp(Libra.data.regex.delimiterSourceLangPhpEndRe,"gm"),'') _LibraTagFunction.push( code ) _LibraTagFunctionLang.push( lang ) _LibraTagFunctionArgs.push( args ) return tag + _LibraTagFunction.length + ';' }) try{ obj = eval( 'object=' + obj + ';' ) delete( window.object ) }catch( err ){debug('warning: non criticval error: eval:', err) }}} switch( typeof obj ){ case 'object': if( Libra.Eav.depth( obj ) > 100 ){ error('Error: Depth of object is over 100') return null } if( _LibraTagFunction && _LibraTagFunction.length > 0 ){ obj = Libra.Language.applyTagFunction( obj, { _LibraTagFunctionName:_LibraTagFunctionName, _LibraTagFunctionSource:_LibraTagFunctionSource, _LibraTagFunctionSourceLink:_LibraTagFunctionSourceLink, _LibraTagFunctionValueSource:_LibraTagFunctionValueSource, _LibraTagFunction:_LibraTagFunction, _LibraTagFunctionLang:_LibraTagFunctionLang, _LibraTagFunctionArgs:_LibraTagFunctionArgs }) } obj=Libra.Json.encode(obj) break; case 'string': debug('---------------------------------------save object as string -------------------------------------------'); break; } //obj=this.parseFunction(obj); var arg={path:"server://Eav/saveObject",group:args.group,object:obj}; if(args.apply) arg.apply=args.apply; if(_LibraTagFunction&&_LibraTagFunction.length>0){ arg._LibraTagFunction=_LibraTagFunction; arg._LibraTagFunctionLang=_LibraTagFunctionLang; arg._LibraTagFunctionSource=_LibraTagFunctionSource; arg._LibraTagFunctionSourceLink=_LibraTagFunctionSourceLink; arg._LibraTagFunctionValueSource=_LibraTagFunctionValueSource; arg._LibraTagFunctionArgs=_LibraTagFunctionArgs; arg._LibraTagFunctionName=_LibraTagFunctionName; } debug('send',arg,args); Libra.send(arg,args); },"_getObjectRemote":function( _libra, args = {}){ var argsRemote = {} if( args.fn ) argsRemote.fn = args.fn else argsRemote.fn = (res) => { debug( 'server: get object:', res )} if( args.scope ) argsRemote.scope = args.scope else argsRemote.scope = this _libra.path = "server://Eav/get" Libra.send( _libra, argsRemote ) },"getObject":function( _libra, args = {}){ _libra = Libra.merge({ getProperty: false, targetTypeEav:'object', from:'local', what:'js' }, _libra ) if( _libra.targetTypeEav === 'object' && _libra.targetName ) _libra.objectName = _libra.targetName if( !_libra.busDb && _libra.objectName ) _libra.busDb = Libra.Eav.busDb( _libra ) return this._getObjectRemote( _libra, args ) },"del":function(arg){ if(typeof arg==='string'){ arg={targetName:arg,targetTypeEav:'object'}; } arg.busDb=Libra.Eav.busDb(arg) arg.path="server://Eav/del"; Libra.send(arg); }},"getModel":function(cnf){if( typeof cnf === 'string' ) cnf = { name: cnf }; return Libra.data.model[ cnf.name ] || new Libra.data.class.libraModel( cnf )},"send":function(_data,args = { fn: null, scope: null }){return Libra.Network.send(( _data._bus ? _data._bus :'msg' ), _data,args )},"getSessionId":function(){return new Date().getTime()+Math.random().toString(36).substr(2,9)},"Bus":{"pingpong":function( arg , opt = null ){debug( 'pong',arg )},"connect":function( arg, opt = null ){ let data = Libra.data data.network.sync = true data.socketStatus = 'yellow' Libra.Network.send( 'init', { path: "server://Network/initSync", remoteIp: data.site.remoteIp, _nwVector:'ws' }) },"disconnect":function( arg, opt = null ){ let data = Libra.data data.socketStatus = 'red' data.network.sync = false Network.send( 'msg', { path: "server://Network/clearObjectSync", siteId: data.site.id, userId: data.user.id, _nwId: data.user.CID }) },"debug":function( arg, opt = null ){ let i, len, data = Libra.data Libra.Notify.add( 'debug', arg, opt ) switch (data.debug._libraDebugType){ case "array": debug( 'Server:', arg ); break default: for( i = 0; len = arg.length, i < len; i++ ){ let output = [] Object.keys( arg[ i ]).map(( key ) => { if(key !== 'data' ){ if( key === 'file' ){arg[ i ][ key ] = arg[ i ][ key ].replace( Libra.data.path.real, ' ')} output.push( key ) output.push( ':' ) output.push( arg[ i ][ key ]) }}) output.push( '->' ) Object.keys( arg[ i ].data ).map(( key ) => output.push( arg[ i ].data[ key ])) debug.apply(this,output) }} },"sync":function( arg, opt = null ){ /*TODO add sync for(var _i in arg){ var cmd=arg[_i], store = Libra.Extjs.Store.get(cmd.db+cmd.table) switch(cmd._cmd){ case 'addData': store.autoSync=false store.autoSyncSuspended=1 store.add(cmd.data) store.autoSyncSuspended=0 store.autoSync=true break; case 'modData':debug('js.Libra.Bus.sync da fare') break; default:debug('js.Libra.Bus.sync da fare') break;}}*/ },"msg":function( arg, opt = null ){ let i if( arg._bus && arg._bus !== 'msg' ) this[ arg._bus ]( arg, opt ) for( i in arg ) if( Libra.data.bus.list.includes( i )) Libra.Bus[ i ]( arg[ i ], opt ) if( arg._cbId ) Libra.Network.handlerCb( arg, opt ) },"warning":function( arg, opt = null ){alert('TODO channel warning')},"eval":function( arg, opt = null ){ let i for( i in arg ){ if( arg[ i ].charAt( 0 ) === '<' ) return Libra.Bus.error( arg[ i ], opt ) else try { eval( arg[ i ])} catch ( e ){ debug( e ) Libra.Notify.add( 'error', e ) }} },"chat":function( arg, opt = null ){alert('TODO channel chat')},"system":function( arg, opt = null ){alert('TODO channel system')},"list":["chat","connect","debug","disconnect","error","eval","extjs","msg","pingpong","sync","system","warning","init"],"init":function( arg, opt = null ){Libra.data.socketStatus='green' },"error":function( arg, opt = null ){Libra.Notify.add( 'error', arg, opt )}},"debounce":function(func, wait, immediate){ let timeout return function executedFunction(){ let context = this, args = arguments, later = function(){timeout = null; if( !immediate ) func.apply( context, args )}, callNow=immediate&&!timeout clearTimeout( timeout ) timeout = setTimeout( later, wait ) if( callNow ) func.apply( context, args ) } },"viewController":{"logout":function(){ Libra.send({ path: "server://User/logout" },{ url: Libra.data.path.virtual + 'lib/server/logout.php', fn: () => { //Libra.data.isLogged = false Libra.data.user.idOld = Libra.data.user.id Libra.data.user.id = 0 Libra.data.user.name = 'anonymous' Libra.Cookie.set( '_userId', 0, 4 ) Libra.mergeConfig( Libra.data,{ "filter group":function( item ){return !( item._libraGroup && item._libraGroup[ 'u_' + Libra.data.user.idOld ])}, hash:'login' }) Libra.mergeConfig(data.store.storeWmMenuNavigation,{"filter data":function( item ){return !( item._libraGroup && item._libraGroup[ 'u_' + Libra.data.user.idOld ])}}) if(Libra.Init.initUser)Libra.Init.initUser()//TODO }})},"logged":function(arg){ let i for( i in arg) Libra.data.user[ i ] = arg[ i ] //Libra.data.isLogged = true if( Libra.Init.initUser )Libra.Init.initUser() //TODO },"close":function( e ){ debug('Libra.close',this,e) let target if( e ){ if( e.target.parentNode.localName === 'libra-tab' ) return e.target.parentNode.viewController.close({ target: e.target }) if( e.target.tagName === 'BUTTON' ) target = e.target; else target = e.target.up( 'button' ) target = target.libraEventTarget || target }else target = this //TODO remove event listeners if( target.localName === 'libra-view' ){ if( target.libraWmMenuNavigationNode ) Libra.data.reference.wmMenuNavigation.viewModel.data.store.del( target.libraWmMenuNavigationNode.record ) target.parentNode.removeChild( target ) window.history.back() }else target.parentNode.removeChild( target ) },"pocket":function( e ){ debug('lpp',e) let btn = e.target, arg = btn.arguments, wmPocket = Libra.data.reference.wmPocket, tgt = arg.target //pocket.delAll() debug('pckt',tgt) if( btn.value ){ //TODO non distruggere pocket ma solo il tipo interno if(tgt.vmd.pocket)tgt.vmd.pocket.destroy() tgt.vmd.pocket = wmPocket.add({ id:'pocket-'+tgt.id,xtype:'pocket',select:1, type: arg.type, target: arg.target }) wmPocket.hidden=0 }else{ //TODO destroy pocket wmPocket.hidden=1 if(tgt.vmd.pocket)tgt.vmd.pocket.destroy()} //TODO rifare handler in modo tale da passare arguments di event di target come argumento, scope fade come .bind() per this }},"setReference":function( str, arg ){ Libra.data.reference[ str ] = arg }, Path:{ parse:function(_libra){ _libra.viewCfg = _libra.viewCfg || {} if( _libra.path ){ let arrBus = _libra.path.split( '://' ), arrPath switch( arrBus.length ){ case 1: _libra.viewName = arrBus[ 0 ] break default: arrPath = arrBus[ 1 ].split( '/' ) _libra._pathLength = arrPath.length _libra._bus = arrBus[ 0 ].split( ':' ) if(_libra._bus.length === 1 ) _libra._bus = _libra._bus[ 0 ] else{ _libra.tabbed = _libra._bus[ 0 ] _libra._bus = _libra._bus[ 1 ]} switch(_libra._bus){ case 'store': //_libra.viewCfg = _libra.viewCfg || {} _libra.viewCfg.path = _libra.path _libra.viewCfg.storeName = arrPath[ 0 ] _libra.viewCfg.tplName = arrPath[ 1 ] if( _libra._pathLength === 2 ) _libra.viewCfg.xtype = 'table' else{ _libra.viewCfg.xtype = 'form' if([ 'add', '+' ].includes( arrPath[ 2 ])) _libra._cmd = 'add' else{ _libra._cmd = 'mod' _libra.viewCfg.recordId = arrPath[ 2 ]}} break default: error( 'js.Libra.Path.parse: unknown bus' ) break} break}} //postParse if( _libra.viewName ){ _libra.view = Libra.data.view[ _libra.viewName ] _libra.viewCfg = data.view[ _libra.viewName ] || {} if(Libra.data.xtype[ _libra.viewName ]) _libra.viewCfg.xtype = _libra.viewName } if( _libra.viewCfg.xtype ) _libra.tabbed = Libra.data.xtype[ _libra.viewCfg.xtype ].tabbed if( _libra.viewCfg && _libra.viewCfg.xtype && !_libra.viewCfg.id ){ //condition for get id _libra.viewCfg.id = _libra.viewCfg.hash || _libra.path if( _libra.viewCfg.id ) _libra.viewCfg.id = _libra.viewCfg.id.replace( /\/|:\/\/|:/g, '-' ) else _libra.viewCfg.id = _libra.viewCfg.storeName + '-' + _libra.viewCfg.tplName + '-' + _libra.viewCfg._cmd } if( !Object.keys( _libra.viewCfg ).length )delete( _libra.viewCfg ) else _libra.viewCfg.hash = _libra.hash || (_libra.tabbed ? _libra.viewCfg.xtype + ':' + _libra.path.replace( new RegExp( '^' + _libra.viewCfg.xtype + ':' ), '' ) : null) _libra._pathParsed = 1 //debug('parse end:',_libra,'view:',_libra.view,_libra.viewCfg) return _libra },"stringify":function(_libra){ error( 'js.Libra.Path.stringify: complete' ) debug(_libra) return _libra }},"bootDone":function(){ if( window.location.hash.split( '#' )[ 1 ] === 'safeMode' ) Libra.data.safeMode = true let hash = window.location.hash.substr( 1 ) if( Libra.data.safeMode && Libra.data.reference.homeLink ) Libra.data.reference.homeLink.href = '#safeMode' else{ hash = hash || 'home' } if( /*Libra.data.reference.wm &&*/ hash ) X.setViewByHash( hash ) },"setHash":function( hash, silent = 0 ){ hash = "#" + hash.replace( /^#/, '' ) if(window.location.hash!==hash){ Libra.data.silentHash = silent window.location.hash = hash }}, data:{ notify:{"count":0}, class:{ prototypeExclude:["extends","static","classObjects","1static","constructor","customElementsDefine","_constructor","1_libraClassName","1_libraConfigExtends","1_libraBufferFn","super"], classObjectsParentExclude:["extends","_libraClassName","_libraBufferFn","_libraConfigExtends"] }, dom:{ tagHaveViewModel:["libra-filter","libra-form","libra-table","libra-tree","libra-nav","libra-ocpanel","libra-editorcode","libra-panel","libra-editorhtml","libra-tab","libra-container"], tagHaveViewController:["libra-form","libra-table","libra-tree","libra-nav","libra-ocpanel","libra-editorcode","libra-panel","libra-editorhtml","libra-container"] }, eav:{ key:"_libraKey", keyAttr:"lak", idAttr:"loid", id:"_", data:{"mode":"json"} }, idCounter:0, isError:false, debug:{_libraDebug:false,_libraDebugFn:null,_libraDebugFile:null}, network:{"id":"","status":null,"sync":false,"enable":true,"asyncMode":true,"loaded":[],"session":[]}, modules:{"loaded":[]}, requestAjax:[], requestCb:[], reference:[], bus:{list:["connect","disconnect","debug","sync","extjs","msg","error","warning","eval","chat","system","pingpong"]}, model:[], group:{"s_0":[]}, "proxy group":{ deleteProperty:function(target, name){for(let storeName in data.store) Libra.mergeConfig(data.store[storeName],{"filter data":function(item){return !(item._libraGroup&&item._libraGroup[name])}})}, set:function(target, name, val, receiver){/*if( !val.store ) val.store = [];*/ return val}}, "get hash":function(){return window.location.hash.split( '#' )[ 1 ] }, "set hash":function(hash){if( hash ) window.location.hash = '#' + hash }, x:{ "set wm":function(val){ let wmDiv = get( '_libraWm' ) if( wmDiv ) document.body.removeChild( wmDiv ) add( typeof val === 'string' ? data.view.wm[ val ] : val, { parentNode: document.body }) } }, lang:[], store:[], silentHash:0,template:[],xtype:{container:[],carousel:[],panel:[],form:{tabbed:{menu:{text:"forms"},config:{defaults:{editing:1,closing:1}}}},tab:[],table:{tabbed:{menu:{text:"tables"},config:{defaults:{editing:1,closing:1}}}},tree:[],nav:[],code:[],pocket:[],a:{is:1},button:{is:1},input:{is:1},codearea:{is:1,transform:"textarea"},menu:[],combobox:[],editorhtml:[]}, view:{ // home:{tag:'div',html:'portale in fase di costruzione'} }}}, class:{ libraContainer:{ extends:"HTMLElement", customElementsDefine:"libra-container", viewModel:{data:{renderDone:false,items:[],slot:[],body:null,storeRegister:1}}, getValue:function(){return this.value }, constructor:function(){ this._doNotapplyBindOnCreateNode = 1 this._cache = { events:{}} this.requires = this.requires || { mod: [], class: [] } this.continue = this.initAll this.makeShadowRoot() }, connectedCallback:function(a){ let i this.itemName = this.itemName || 'item' this.viewModel = this.viewModel || { data:{}} if( !this.viewModel.data.renderDone ){ this.viewModel.data.body = this.viewModel.data.body || this if( !this.viewModel || ( this.viewModel && !this.viewModel.onConnectedCallback )) this.viewModel = new Libra.data.class.libraViewModel( this ) this.vmd = this.viewModel.data if( this.viewModel ) this.viewModel.onConnectedCallback() if( !this.viewController || ( this.viewController && !this.viewController.onConnectedCallback )) this.viewController = new Libra.data.class.libraViewController( this ) this.shadowRoot.$$( 'slot' ).forEach( slot => { this.vmd.slot[ slot.name || 'body' ] = slot }) for( i in this.vmd.slot ) this.vmd.slot[ i ].on( 'slotchange', e => { e.stopPropagation(); this.onSlotChange( e )}) this.initConnect() this.initAttribute() if( this.dataset.requires ) this.requires = this.dataset.requires.split( ',' ) this.id = this.id || Libra.getId() if( this.dataset.reference ) this.viewModel.setReference( this.dataset.reference, this ) if( this.dataset.storeName ){ this.vmd.store = Libra.getStore( this.dataset.storeName ) this.vmd.model = this.vmd.store.model } if( this.store ){ this.vmd.store = Libra.getStore( this.store ) this.vmd.model = this.vmd.store.model } if( this.dataset.modelName ){ this.vmd.model = Libra.getModel({ name: this.dataset.modelName, node: this }) if( this.vmd.model.store ) this.vmd.store = this.vmd.model.store } if( this.vmd.store ){ //if( !vmd.store.register ) vmd.store = Libra.getStore( vmd.store ) if( this.vmd.storeRegister ) this.vmd.store.register( this ) this.dataset.templateName = this.dataset.templateName || 'default' } this.initRequire() if( this.requires.mod.length || this.requires.class.length ){//TODO complettare this._wait = true for( i in this.requires.mod ) Libra.modprobe( this.requires.mod[ i ]).then({ fn: () => { this.continue();if(this.onRender)this.onRender(this)}}) } if( !this._wait ) this.initAll() } }, init:function(){}, makeShadowRoot:function(options={}){ ( "ShadyCSS" in window ) ? ShadyCSS.styleElement( this ) : null this.attachShadow({ mode: "open" }) const templateId = options.templateId || this.is const templateClone = this.getTemplateCopy( templateId ) //this.shadowRoot.applyAuthorStyles=true //this.shadowRoot.resetStyleInheritance=false let shr = this.shadowRoot shr.libraParent = this shr.tagName = 'SHADOWROOT' //shr.up=HTMLElement.prototype.up shr.appendChild( templateClone ) shr.$ = selector => shr.querySelector( selector ) shr.$$ = selector => shr.querySelectorAll( selector ) }, getTemplateCopy:function(templateId=this.is){ const template = document.getElementById( templateId ) if( !template ) error( `Template ${templateId} is not found` ) return template.content.cloneNode( true ) }, "get is":function(){return this.localName }, debug:function(){return debug.apply( this, [ '%c ' + this.localName + ':' + this.id + ':' + arguments.callee.caller.name + ':', 'color:blue', ...arguments ])}, fireEvent:function(arg={bubbles:false},arg2){ //TODO togliere //if( typeof arg !== 'object' ){error( 'error define fireEvent ',{el:this,arg:arg,arg2:arg2}); return false} let bubbles = arg.bubbles, customEventInit = { bubbles }, e if( arg.detail instanceof Object ){ if( arg.detail.item && this.itemName !== 'item' ){ arg.detail[ this.itemName ] = arg.detail.item delete( arg.detail.item ) } customEventInit.detail = arg.detail } e = new CustomEvent( arg.name, customEventInit ) this.dispatchEvent( e ) /*TODO analizare motore bindEvent if(this.vmd.bindEvent&&!arg.detail.eventEmitter&&(!this.vmd.bindEventList||(this.vmd.bindEventList&&this.vmd.bindEventList.includes(arg.name)))){ arg.detail.eventEmitter = this this.debug('bindEvent:1:',arg) this.vmd.bindEvent.fireEvent( arg )}*/ }, "$":function(arg){return this.querySelector( arg )}, "$$":function(arg){return this.querySelectorAll( arg )}, render:function(){}, wait:function(){this._wait = true }, disconnectedCallback:function(){ //passato a .destroy() di initDom if( this.vmd.store && this.vmd.storeRegister ) this.vmd.store.unRegister( this ) }, onSlotChange:function(e){ if(!this.vmd) return false let i, path = e.path || (e.composedPath && e.composedPath()), name = path[ 0 ].name || 'body', items = path[ 0 ].assignedElements({}), renderName = 'render' + name.firstToUpperCase() if( this.vmd[ name ] && !this.vmd[ name ][ renderName + 'Done' ]){ this.vmd[ name ][ renderName + 'Done' ] = true this[ renderName ]( items )} for( i = 0; i < items.length; i++ ){ let item = items[ i ] if( !item[ renderName + 'ItemDone' ] && item.tagName !== 'SLOT' ){ item[ renderName + 'ItemDone' ] = true //item._itemKey=this.vmd.items.length //this[ renderName + 'Item' ]( item ) if( name === 'body' ){ let sel = this.vmd.pushItemQs if( sel ){ let push=0; [...item.parentNode.$$(sel)].find( node => { if( node === item ){push = 1; this.vmd.items.push( item )}}) if( !push ){ let node=item.$( sel );if(node) this.vmd.items.push(node )} }else this.vmd.items.push( item )} this[ renderName + 'Item' ]( item )}} if(this.renderChange)this.renderChange(e) }, add:function(item,arg){ if( item ){ if( this.defaults ) item = Libra.mergeConfig( item, this.defaults ) item.id = item.id || Libra.getId() item._itemKey = this.vmd.items.length if( !arg ) arg = {} if( !arg.parentNode && !arg.before && !arg.after ) arg.parentNode = this.vmd.body item.vmd=item.vmd||{} this.vmd.lastAddedItem = item instanceof HTMLElement ? this.appendChild(item):add( item, arg ) //this.vmd.lastAddedItem.record=item this.fireEvent({ name:'add', detail:{ item: this.vmd.lastAddedItem }, bubbles:false }) if( this.vmd.lastAddedItem.dataset.hasOwnProperty( 'select' )) this.selectItem( this.vmd.lastAddedItem ) }else this.vmd.lastAddedItem = null return this.vmd.lastAddedItem }, del:function(node){ return node.destroy() //let items = this.vmd.items, el, item //passato a initDom.destroy() //for( i in items ) if(node === items[ i ]){ //return items[ i ].destroy() /*item = items[ i ] if( item._linkedNode ){ //if(item._isTabbed) item._linkedNode._linkedView = null} el = this.vmd.body.removeChild( item ) el = null delete items[ i ] //delete item //delete el this.vmd.items = this.vmd.items.filter( Boolean ) this.fireEvent({ name:'delete',detail:{node:item}, bubles:false }) return true*///} //return false }, delAll:function(){while( this.vmd.body.firstChild ) this.vmd.body.removeChild( this.vmd.body.firstChild ); this.vmd.items=[]; return this }, addRecord:function(row,arg){ let tpl = this.template.use({ self: this, scope: row }) if( tpl ) return this.add( tpl, arg ) else this.vmd.lastAddedItem = null return this.vmd.lastAddedItem }, renderBody:function(items){}, renderBodyItem:function(item){}, initAll:function(){ if( this.dataset.templateName ) this.template = Libra.Template.get( this.dataset.templateName ) this.init() this.renderAll() },initRequire:function(){}, renderAll:function(){ if( this.dataset.hasOwnProperty( 'disabled' )) this.classList.add( 'disabled' ) //TODO non puoi cliccare if( this.dataset.hasOwnProperty( 'selected' )) this.classList.add( 'active' ) //TODO non puoi cliccare this.renderCss() this.renderLayout() if( !this.dataset.hasOwnProperty( 'notLoad' )) this.load() this.viewModel.data.renderDone = true this.render() if(this.keyMap){ this.setAttribute('tabindex',0) let i, j this.keyMapCode = {} for( i in this.keyMap ){ j = this.keyMap[ i ] this.keyMapCode[ j.code ] = { ctrl: !!j.ctrl, alt: !!j.alt, shift: !!j.shift, mac: !!j.mac, map: j } } this.vmd.body.on( 'keydown', ( e ) => { let map = this.keyMapCode[ e.keyCode ] if( map && map.ctrl === e.ctrlKey && map.alt === e.altKey && map.shift === e.shiftKey && map.mac === e.metaKey ){ map = map.map if( map.stop ) /*e.stopPropagation() */e.preventDefault() //TODO vedere focus this.viewController[ map.handler ].call( this, arguments )}} ,true )} this.renderEvent() }, initAttribute:function(){}, renderCss:function(){}, renderLayout:function(){if( this.dataset.layout ) if( Libra.Layout[ this.dataset.layout ]) Libra.Layout[ this.dataset.layout ]( this );else error( 'layout ' + this.dataset.layout + ' not defined' )}, renderEvent:function(){ //this.on('select',e=>this.select({ e: e })) }, reload:function( arg ){this.delAll(); return this.load( arg )}, load:function( arg ){ let i arg=Libra.merge( this.vmd.storeFilter || [], arg ) if( this.vmd.store ){ let data = this.viewModel.data.store.getData( arg ), len = Object.keys(data).length if( len ) for( i in data) this.addRecord( data[ i ])} return data }, initConnect:function(){}, delRecord:function(rec){ //this.debug(this,rec) //TODO analizzare se serve let vmd = this.viewModel.data vmd.body.removeChild( vmd.body.$( '[data-' + Libra.data.eav.idAttr + '="' + rec[Libra.data.eav.id] + '"]' )) } }, libraPanel:{ extends:"libraContainer", customElementsDefine:"libra-panel", init:function(){ if( this.dataset.hasOwnProperty( 'viewTitle' )){ this.vmd.title = add({ xtype:'container', layout:'row', items:[ this.vmd.slot.title ] },{ before: this.vmd.slot.tbar }) add({ parent: this, slot:'title', tag:'div', text: this.dataset.viewTitle /*cls:'text-white ' + ( this.dataset.iconCls ? 'fa ' + this.dataset.iconCls + ' famr' :'' ),*/}) } if(this.tbar) this.vmd.tbar = add({ xtype:'container', layout:'row', items: [ this.vmd.slot.tbar ] },{ after: this.vmd.title || this.vmd.slot.title }) }, renderTitle:function(items){ this.vmd.title.classList.add( 'card-header', 'bg-primary' ) if( this.dataset.hasOwnProperty( 'closing' )){ this.vmd.title.classList.add( 'alert-dismissible' ) add({ parentNode: this.viewModel.data.title, tag:'button',type:"button",libraEventTarget:this,handler:'close',cls:"close",attr:{'aria-label':"Close",'data-dismiss':"alert"},items:[{ tag:'span', attr:{'aria-hidden':true},html:'×' }]})} }, renderTitleItem:function( item ){}, renderTbar:function( items ){ //this.viewModel.data.tbar.classList.add( 'card-header' ) this.viewModel.data.tbar.style.padding = '.5rem' }, renderTbarItem:function(item){ let i, cls=['btn','btnBar', 'btn-outline-secondary'/*,'btn-sm'*/] //item.classList.add( 'mr-5' ) item.style[ 'margin-right' ] = '.5rem' //item.style['margin']='0 .5rem 0 0' if( item.nodeName === 'BUTTON' ) item.classList.add( ...cls ) if( item.children ) for( i in item.children ) if( item.children[ i ].nodeName === 'BUTTON' ) item.children[ i ].classList.add( ...cls ) }, render:function(){ this.super() if( this.tbar ) add( this.tbar, { defaults:{ parentNode: this, slot:'tbar'}}) }}, libraTable:{ extends:"libraPanel", customElementsDefine:"libra-table", viewModel:{"data":{"inserting":1,"selectedRecord":null}}, dblclick:function( tr, arg ){ //TODO sistemare magari spostando in libraocpanel if( this.viewModel.data.store instanceof Libra.data.class.libraStoreObject ){ if( !tr.record.leaf ) this.viewController.setPath( tr.record[ Libra.data.eav.id]); /*TODO oc */ else this.debug('complettare') }else this.viewController.mod( tr.record ) }, viewController:{ add:function(e){ let arg = null if( e instanceof Event ) arg = { e: e } X.setView({ xtype:'form', storeName:this.viewModel.data.store.config.name, editing:1 }, arg ) }, mod:function(e){ let rec = e, arg = null if( e instanceof Event ){ rec = this.viewModel.data.selectedRecord arg = { e: e }} X.setView({ xtype:'form', storeName: this.vmd.store.config.name, record:this.vmd.selectedRecord, editing:1 }, arg ) }, setPath:function(arg){ this.vmd.store.setPath( arg ) this.vmd.pathText.textContent = '/' + this.vmd.store.path //TODO binding?? tra path e store.path }, del:function(){ let i for( i in this.vmd.selections ) this.vmd.store.del( this.vmd.selections[ i ].record ) }, sort:function(n){ let table = this.vmd.table, switching = true, switchcount = 0, dir=/*dir||*/ "asc", rows, i, x, y, shouldSwitch while ( switching ){ switching = false rows = this.vmd.body.children for( i = 0; i < (rows.length - 1); i++ ){ shouldSwitch = false x = rows[ i ].$$( "TD" )[ n ] y = rows[ i + 1 ].$$( "TD" )[ n ] if( dir === "asc" ) { if( x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()){shouldSwitch = true; break }} else if( dir === "desc" ){if( x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()){shouldSwitch = true; break }}} if( shouldSwitch ){ rows[ i ].before( rows[ i + 1 ]) //TODO vedere la velocita tra before e insertBefore switching = true switchcount ++ }else{ if( switchcount === 0 && dir === "asc" ){dir = "desc"; switching = true}} }}}, onClick:function(node){}, deselectItem:function(node){ if(!node){ for( let i in this.vmd.selections ) this.deselectItem(this.vmd.selections[ i ]) return true } this.value = undefined this.vmd.selectedRecord = null if( this.localName === 'libra-table' && this.dataset.hasOwnProperty( 'checking' )) node.$( 'th input' ).checked = 0 node.removeAttribute( 'data-selected' ) if([ 'libra-table', 'libra-tree' ].includes( this.localName )) node.classList.remove( 'table-primary' ) //TODO ??? this.vmd.selections.pop( node ) }, selectFirstItem:function(){this.selectItem(this.vmd.items[0])}, selectItem:function(node,silent = false ){ if( node.dataset.hasOwnProperty( 'selected' )) return false this.vmd.selections.forEach( node => this.deselectItem( node )) this.vmd.selectedRecord = node.record this.value = node.dataset[ Libra.data.eav.idAttr ] * 1 this.vmd.selections.push( node ) if([ 'libra-table', 'libra-tree' ].includes( this.localName )) node.classList.add( 'table-primary' ) if( this.localName === 'libra-table' && this.dataset.hasOwnProperty( 'checking' )) node.$( 'th input' ).checked = 1 node.dataset.selected = 1 if( !silent ) this.fireEvent({ name:'selectItem', detail:{ item: node }, bubbles: false }) }, initAttribute:function(){ this.super() let ds = this.dataset ds.templateName = 'tableTr' if( ds.hasOwnProperty('editing')) ds.sorting = ds.selecting = ds.resizing = ds.checking = '' }, init:function(){ this.super() //let storeText = this.vmd.store.text this.vmd.table = this.shadowRoot.$( 'table' ) || add({ parent: this.shadowRoot, tag:'table', items:[{ tag:'thead', items:[{ tag:'tr' }] }, { tag:'tbody' }] }) this.vmd.body =this.shadowRoot.$( 'tbody' ) || this.vmd.table this.vmd.body.dataset.xtype=this.localName.replace('libra-','') if( this.dataset.hasOwnProperty( 'checking' )){ this._checked=this._checked||{} this.check=e =>{ if( e.path[ 0 ].checked ) this._checked[ e.path[ 2 ].record[ Libra.data.eav.id ] ] = 1;else delete(this._checked[ e.path[ 2 ].record[ Libra.data.eav.id ] ]);this.fireEvent({name:'check',detail:{ value: e.path[ 0 ].checked,e:e, item: e.path[ 2 ] },bubbles:false})} Object.defineProperty(this, "checked", { get: () => { return Object.keys(this._checked).join(',')}, set:function(value){ let values = value.split( ',' ), items = this.viewModel.data.items for( let i = 0; i < items.length; i++) if( values.includes( items[ i ].dataset[ Libra.data.eav.idAttr ])){ items[ i ].$( 'th input' ).checked = 1 this._checked[ items[ i ].dataset[ Libra.data.eav.idAttr ]] = 1 }else{ items[ i ].$('th input').checked = 0 delete( this._checked[ items[ i ].dataset[ Libra.data.eav.idAttr ]])}}})} if( !this.dataset.hasOwnProperty( 'excludeHeader' )){ let i, field, items = [], item this.vmd.header = this.shadowRoot.$( 'thead' ) this.vmd.theadTr = this.shadowRoot.$( 'thead>tr' ) this.renderHeader() //TODO controll it se fatta con html; /*attr:{'data-sorting-disable':1},*/ if( this.dataset.hasOwnProperty( 'checking' )) items.push({ cls:'w1', items: [ { tag:'input', type:'checkbox', events:{ input: ( e ) => { let i; this.selections=[]; for( i = 0; i < this.vmd.items.length; i++ ) this[ ( e.target.checked ? '' :'de' ) + 'selectItem' ]( this.vmd.items[ i ])}}}]}) for( i in this.vmd.model.fields ){ field = this.vmd.model.fields[ i ] items.push({ text: field.text, name: field.name, columnKey: i }) if( this.dataset.hasOwnProperty( 'sorting' )){ item = items[ items.length - 1 ] item.events = { click: e => { if( e.target.nodeName === 'TH') this.viewController.sort( e.target.columnKey )}} item.cls = 'cp' }} add( items, { defaults:{ parentNode: this.vmd.theadTr, tag:'th' }}) for( i=0; i < items.length; i++ ) this.renderHeaderItem( items[ i ]) } if(this.dataset.hasOwnProperty( 'selecting' )){ this.vmd.selections = [] //this.vmd.selected = null this.vmd.selectedRecord = null this.vmd.body.on( 'click', e => { let tr, is, tgt = e.target, path = e.path || (e.composedPath && e.composedPath()) if( path.includes( this.vmd.body )){ for( var i in path ) if( path[ i ].nodeName === 'TR' ){tr = path[ i ]; break } is = tr.dataset.hasOwnProperty( 'selected' ) if( !is ) this.selectItem( tr ) if( tgt.nodeName === 'TD' ) this.onClick( tr ) else{ if(this[tr.record.expanded?'collapse':'expand'])this[tr.record.expanded?'collapse':'expand']( tr )}}})} if( this.dataset.hasOwnProperty( 'editing' )) data.template.buttonEditing({ target: this }) if( this.dataset.hasOwnProperty( 'filtering' )){ this.tbar = this.tbar || [] this.tbar.push({ xtype: "input", cls:"cols-sm-1",/* offset-10*/ attr:{ placeholder: "insert firter", "aria-label": "Search" }, events:{ keyup: e => { let input = e.target, filter = input.value.toUpperCase(), tr = this.viewModel.data.items, td, tds, i, j, value for( i = 0; i < tr.length; i++ ){ tds = tr[i].getElementsByTagName( "td" ) for( j = 0; j < tds.length; j++ ){ td = tds[ j ] if( td ){ value = td.textContent || td.innerText || td.firstChild.shadowRoot.childNodes[ 1 ].textContent if( value.toUpperCase().indexOf( filter ) > -1){tr[ i ].style.display = ''; break}else tr[ i ].style.display = 'none' }}}}}})} },"renderHeaderItem":function( item ){},"renderHeader":function( item ){this.viewModel.data.header.classList.add( 'thead-light' )},"renderCss":function(){ this.super() this.viewModel.data.table.classList.add( 'table', 'table-bordered' ) this.viewModel.data.table.classList.add( 'table-striped' ) },"add":function( item ){ this.super() let last = this.vmd.lastAddedItem if( !last.renderBodyItemDone ){ last.renderBodyItemDone = true this.renderBodyItem( last ) this.vmd.items.push( last )}},"renderEvent":function(){ this.viewModel.data.body.on("dblclick", e => { //TODO ? let i, tr, isSelected, path = e.path || (e.composedPath && e.composedPath()) for( i in path ) if( path[ i ].nodeName === 'TR' ){ tr = path[ i ]; break} this./*viewController.*/dblclick( tr, { event: e }) })},"tableResizable":function(table){ let row = table.getElementsByTagName( 'tr' )[ 0 ], cols = row ? row.children : undefined if( !cols ) return table.style.overflow = 'hidden' let tableHeight = table.offsetHeight for(let i=0;i { curCol = e.target.parentElement nxtCol = curCol.nextElementSibling pageX = e.pageX let padding = this.tableResizablePaddingDiff(curCol) curColWidth = curCol.offsetWidth - padding if(nxtCol) nxtColWidth = nxtCol.offsetWidth - padding }) div.on( 'mouseover', e => { e.target.style.borderRight = '2px solid #c5c4c4' }) div.on( 'mouseout', e => { e.target.style.borderRight = '' }) document.on( 'mousemove', e => { if( curCol ){ let diffX = e.pageX - pageX if( nxtCol ) nxtCol.style.width = (nxtColWidth - (diffX))+'px' curCol.style.width = (curColWidth + diffX)+'px' } }) document.on('mouseup', e => curCol = nxtCol = pageX = nxtColWidth = curColWidth = undefined ) }}, libraTree:{ extends:"libraTable", customElementsDefine:"libra-tree", dblclick:function( tr, arg ){}, collapse:function(node){ node.classList.replace( 'treeExpanded', 'treeBusy' ) if( node.nextElementSibling ) while ( node.nextElementSibling.treeParent === node ) this.viewModel.data.body.removeChild( node.nextElementSibling ) delete ( node.record.expanded ) node.classList.replace( 'treeBusy', 'treeCollapsed' ) }, expand:function(node){ let i node.classList.replace( 'treeCollapsed', 'treeBusy' ) for( i in node.record.child ) this.addRecord( node.record.child[ i ], { defaults:{ treeParent: node }, after: node }) node.record.expanded = true node.classList.replace( 'treeBusy', 'treeExpanded' ) }, onClick:function(node){ //TODO vedere bene //this.fireEvent( 'input',{node:node}) //this.fireEvent( 'change',{node:node}) //TODO vedere if(node.record.hash) X.setHash(node.record.hash); //TODO vedere if(node.record.view) X.setView(node.record.view) }, renderCss:function(){this.viewModel.data.table.classList.add('table','table-borderless') }, initAttribute:function(){ this.dataset.templateName = 'treeTr' this.dataset.selecting='' this.dataset.excludeHeader='' this.dataset.modelName='tree' } }, libraNav:{ extends:"libraTree", customElementsDefine:"libra-nav", render:function( item ){ this.super() this.viewModel.data.body.style.color = '#adb3b8' //TODO spostare in renderEvent o metterlo configurabile /*this.on( 'add', function( e ){ debug('rr',e.detail) if(!e.detail.eventEmitter)return false this.debug(e) let det = e.detail, view = det.view item if(view){ item = view.viewModel.data.menuItem if( item &&!(item instanceof HTMLElement)){ item.select=1 this.addRecord(item) //TODO select per tree item = this.vmd.lastAddedItem item.viewModel=item.viewModel||{data:{}} item.viewModel.data.view=view view.viewModel.data.menuItem=item debug('-------------',view.dataset.tabbed,view.localName.replace(/^libra-/,'')) if(view.dataset.tabbed){ Libra.data.xtype[view.dataset.tabbed].tabbed.menuItem = item if(view.vmd.itemSelected)view.vmd.itemSelected.viewModel.data.menuItem=item} }else{ let ds = view.dataset if(ds&&ds.hash){ item = this.shadowRoot.$( "td[data-hash='" + ds.hash + "']" ) if( item ) item = item.parentNode}} if(item){this.selectItem(item,true)}}})*/ //item.style.fontSize='18px' }, renderBodyItem:function( item ){ this.super() item.style.fontSize = '18px' }, itemName:"menuItem", renderEvent:function(){ this.on('selectItem', e => X.setView( null, { e: e })) } },"libraCarousel":{"extends":"libraContainer","customElementsDefine":"libra-carousel","initAttribute":function(){ this.super(); this.setAttribute('role','listbox'); },"renderCss":function(){this.super(); this.classList.add('carousel-inner','fit')},"renderBodyItem":function(item){ this.super() item.classList.add( 'carousel-item' ) if( this.viewModel.data.items.length === 0) item.dataset.select = '' if( item.id === '' ) item.id = Libra.getId() item.classList.add( 'carousel-item','h100','overflow-auto' ) if( item.dataset.hasOwnProperty( 'select' )) this.selectItem(item,true) },"selectItem":function( node, silent = false ){ if( node ){ let ref = Libra.data.reference this.deselectItem( this.vmd.itemSelected ) node.classList.add( 'active' ) node.dataset.select = '' this.vmd.itemSelected = node /* if( this === ref.wmView || this.parentNode === ref.wmView ){ //if( !this.wmMenuViewSilent ) X.setMenuView( node ) X.changeView({view:node,target:this})}*/ //this.debug('js.class.libraCarousel.selectItem',node,silent) if( !silent ) this.fireEvent({ name:'selectItem', detail:{item:node}}) //TODO sistemarlo con onSelectItem forse? //if( this === ref.wmView || this.parentNode === ref.wmView ) X.changeView({view:node,target:this}) return node}},"deselectItem":function(node){ if(node){ delete node.dataset.select node.classList.remove( 'active' )} },"renderEvent":function(){ /* let ref = Libra.data.reference //TODO spostare in convig di wm if( this === ref.wmView || this.parentNode === ref.wmView ) this.on('selectItem',function(e){ //this.debug('js.class.libraCarousel:0',e) if(!e.detail.eventEmitter) return false let menuItem = e.detail.menuItem, view,hash //TODO vedere vene con la modifica a item if( e.detail.item ) return false if( menuItem && menuItem.viewModel ) view = menuItem.viewModel.data.view debug('js.class.libraCarousel.onSelectItem:',e,view,e.detail) if( menuItem && view ){ view.parentNode.selectItem( view, true ) //hash = view.getAttribute( 'hash' ) //if( hash ) Libra.setHash( hash, true )} else view=X.setView( menuItem&&menuItem.record.view?menuItem.record.view:null, { target: this, e: e }) //X.changeView({view:view,e:e,target:this})})*/ }},"libraTab":{"extends":"libraCarousel","customElementsDefine":"libra-tab","keyMap":{"new":{"code":65,"alt":1,"handler":"newTab","stop":1},"next":{"code":88,"alt":1,"handler":"nextTab","stop":1},"prev":{"code":90,"alt":1,"handler":"prevTab","stop":1}},"viewController":{"close":function( e ){ e.stopPropagation() let ref = Libra.data.reference, header = e.target.parentNode, tab = header.vmd.tabBody, sel = tab.dataset.hasOwnProperty('select'), menuNode = this.vmd.menuNode if( sel ) this.prev() this.vmd.header.del( header ) this.del( tab ) //this.debug('close',e,e.target,this,this._isTabbed,this.vmd.items.length) if( this._isTabbed && this.vmd.items.length === 0 ){ this.parentNode.del(this) Libra.data.xtype[this.dataset.tabbed].tabbed.view=null delete(Libra.data.xtype[this.dataset.tabbed].tabbed.view) ref.wmMenuNavigation.selectItem(menuNode.previousSibling) ref.wmMenuNavigation.del(menuNode) } /*let i, item, lastItem, next this.viewController.prevTab() for( i in this.vmd.items ){ item = this.vmd.items[ i ] if( item.id === e.target.id ){ //next=item.previousSibling||item.nextSibling delete this.vmd.items[ i ] this.vmd.items = this.vmd.items.filter( Boolean ) if( !this.vmd.items.length ){ this.itemSelectedKeySilent = 1 this.dataset.itemSelectedKey = ''} break} //lastItem = item} this.vmd.header.removeChild( e.target.viewModel.data.tabHeader ) this.vmd.body.removeChild( e.target ) this.debug(this) if(this.vmd.tabbed&&!this.vmd.items.length)this.parentNode.viewController.close()*/ }},"render":function(){ this.super() if( this.adding ) add({ parent: this.vmd.header, rendered:1, iconCls:'fa-plus', xtype:'button',ui:'', handler: (e)=> this.add({value:'',select:1})}) },"renderCss":function(){this.super()},"renderBodyItem":function( item ){ item.id = item.id || Libra.getId() //item.viewModel=Libra.merge(item.viewModel,{ data:{}}) item.vmd=item.vmd||{} item.vmd.tabHeader = add({ parent: this.vmd.header, vmd:{ tabBody: item }, rendered:1, //cls:'h-100', tag:'div' }) this.renderHeaderItem( item.vmd.tabHeader ) item.classList.remove( 'h100' ) item.classList.add( 'hViewTab' ) this.super() },"renderHeader":function(){ let header = this.vmd.header header.classList.add( 'nav', 'nav-tabs' ) header.on( "click", e => { e.stopPropagation() if( e.target.localName === 'div' && !e.target.id ) return let target = e.target.localName === 'div' ? e.target : e.target.parentNode this.selectItem( target.vmd.tabBody ) }) },"renderHeaderItem":function( item ){ item.id = item.vmd.tabBody.id + '-header' item.textNode = add({ parent: item, tag:'span', text: item.vmd.tabBody.dataset.tabTitle || item.text||item.id }) if( item.vmd.tabBody.dataset.hasOwnProperty( 'closing' )) add({ parentNode:item, xtype:'button',cls:'close', css:'padding:4px 0 0 8px', handler:'close', iconCls:'fa-times', //text:'asd', //handler:(e)=>{e.stopPropagation();let div=e.target.up('div').viewModel.data.tabBody;div.viewController.close({target:div})}, attr:{'aria-label':'Close'}/*, items:[{ tag:'span', attr:{'aria-hidden':true}, html:' ×'}]*/ }) if( item.vmd.tabBody.dataset.hasOwnProperty( 'select' )){item.classList.add( 'active' ); this.dataset.itemSelectedKey = item.vmd.tabBody.id } item.classList.add('nav-item','nav-link','cp') if( this.vmd.header.children.length === 1 ){item.classList.add( 'active' ); item.vmd.tabBody.classList.add( 'active' )} },"init":function(){ this.super() //this.viewModel.data.header = this.add({ tag:'div', renderBodyItemDone:1 }) this.vmd.header = add({ /*tag:'div'*/xtype:'container', renderBodyItemDone:1 },{parentNode:this}) this.renderHeader() },"initAttribute":function(){this.setAttribute( 'role', 'listbox' )},"selectItem":function(node){ if(node){ this.super() if(node.vmd.tabHeader)node.vmd.tabHeader.classList.add( 'active' ) return node }},"deselectItem":function(node){ if(node){this.super() node.vmd.tabHeader.classList.remove( 'active' )} },"add":function(item, arg){ this.super() return this.vmd.lastAddedItem },"itemName":"tab"},"libraForm":{"extends":"libraPanel","customElementsDefine":"libra-form","set value":function(value){this.record = value },"get value":function(){return this.getValue()},"viewModel":{"data":{"storeRegister":0,"pushItemQs":"[name]","record":null,"recordId":0,"oldValue":[],"locked":false,"changed":false,"writing":false,"busy":false,"status":"ready","cacheValue":[],"input":[]}},"keyMap":{"save":{"code":83,"ctrl":1,"handler":"save","stop":1}},"init":function(){ let i if( this.dataset.hasOwnProperty( 'editing' )){ this.vmd.relation = {} if( this.vmd.store ) this.vmd.relation = Libra.merge( this.vmd.relation, this.vmd.store.relation ) if( this.vmd.model ) this.vmd.relation = Libra.merge( this.vmd.relation, this.vmd.model.relation ) if( !Object.keys( this.vmd.relation ).length ) delete( this.vmd.relation ) } if( this.record ){this.vmd.record = this.record; this.dataset.recordId = this.record[ Libra.data.eav.id ] } this.vmd.recordId = this.dataset.recordId ? + this.dataset.recordId : 0 this.vmd.writing = !this.vmd.recordId this.vmd.form = this.add({ tag:'form',renderBodyItemDone:1, id: this.id + '-form', items: this.vmd.slot.body }) this.vmd.body = this.vmd.form if( this.vmd.recordId > 0 ){ this.vmd.record = this.vmd.store.getData({ property: Libra.data.eav.id, value: this.vmd.recordId }) if( this.vmd.record ) this.vmd.record = this.vmd.record[ 0 ] } if( this.dataset.hasOwnProperty( 'statusing' )){this.tbar = this.tbar || []; this.tbar.push({ xtype:'button', ref:'statusX', oldClass:'alert-dark', iconCls:'fa-check', ui:'outline-secondary', cls:'alert-dark', attr:{ role:'alert' }})} if( this.dataset.hasOwnProperty( 'editing' )) data.template.buttonEditing({ target: this }) this.super() if( this.bind && this.bind.modelName ) this.vmd.setModelName = arg => { let ds = this.dataset, modelName = arg.value ds.modelName = modelName this.template = Libra.Template.get( ds.templateName = 'form' ) this.vmd.model = Libra.getModel({ node:this, name: modelName }) this.reload() } },"renderCss":function(){ this.super() if( this.vmd.store ) this.vmd.form.classList.add( 'card-body' ) },"initAttribute":function(){ this.super() if( this.dataset.hasOwnProperty( 'editing' )) this.dataset.statusing = 1 if( this.dataset.hasOwnProperty( 'storeName' )|| this.dataset.hasOwnProperty( 'modelName' )) this.dataset.templateName = 'form' },"load":function(){ let i, item if( this.vmd.model ) for( i in this.vmd.model.fields ){ item = this.addRecord( this.vmd.model.fields[ i ]) if( item ){ item = item.$( '[name]'/*'input,textarea'*/ ) || this.vmd.lastAddedItem this.vmd.items.push( item ) this.vmd.input [ item.name ] = item this.renderBodyItem( item ) }}},"render":function(){ let item this.super() if(this.vmd.store){ item = this.add( this.template.use({ self: this, scope:{ text: Libra.data.eav.id, type:'number',name: Libra.data.eav.id }})) if( item ){ item = item.$( '[name]'/*'input,textarea'*/ ) || this.vmd.lastAddedItem this.vmd.items.push( item ) this.vmd.input [ item.name ] = item this.vmd.lastAddedItem.hidden=true this.renderBodyItem( item ) } if( this.vmd.record ) this.setValue(this.vmd.record) }},"getValue":function(arg={action:'add'}){ let i, item, rec = {}, vmd = this.viewModel.data, recOld = vmd.recordOld /* formData = new FormData( this.viewModel.data.form ) //TODO non riconosce il tipo number * formData.forEach( function( i, j ){rec[ j ] = i })*/ for(let i in vmd.items ){ item = vmd.items[ i ] if( !( item.name in rec )){ rec[ item.name ] = item.getValue ? item.getValue() : item.value if( item.type === 'number' ) rec[ item.name ] = +rec[ item.name ] if( arg.action === 'mod' && rec[ item.name ] === recOld[item.name]) delete( rec[ item.name ]) } } if( arg.action === 'mod' ){ rec[ Libra.data.eav.id ] = recOld[ Libra.data.eav.id ] rec[ Libra.data.eav.key ] = recOld[ Libra.data.eav.key ] } return rec },"setValue":function( arg ){ if( !arg ) arg = {} let i, input, reset = Object.keys( arg ).length === 0 if( reset ){this.vmd.recordId = null;this.vmd.recordKey = null} else{ this.vmd.recordId = arg[ Libra.data.eav.id ] this.vmd.recordKey = arg[ Libra.data.eav.key ] if( !arg._binder ) arg = new Libra.data.class.binder( arg ) } this.vmd.recordIdOld = this.vmd.recordId this.vmd.recordKeyOld = this.vmd.recordKey /*for( i = 0; i < this.vmd.items.length; i++ ){ let input = this.vmd.items[ i ] //if( this.vmd.recordOld && this.vmd.recordOld._binder && reset ) this.vmd.recordOld._binder.bindings[ input.name ].delete( input ) //if( input._binder && this.vmd.recordIdOld ) input._binder.bindings.value.clear() if( !reset ){ //if( !input._binder ) input = new Libra.data.class.binder( input ) input.value = typeof arg[ input.name ] === 'undefined' ? null : arg[ input.name ] //input._bind( 'value' , arg, input.name )}}*/ if( reset ) this.vmd.form.reset() else for( i = 0; i < this.vmd.items.length; i++ ){let input = this.vmd.items[ i ]; if(input.name in arg) input.value = typeof arg[ input.name ] === 'undefined' ? null : arg[ input.name ]} this.vmd.oldValue = this.getValue() this.vmd.recordOld = arg //this.renderValue=arg },"viewController":{"cancel":function(){this.reset()},"lock":function(){ //TODO this.viewModel.data.locked = 1 this.viewModel.data.writing = 1 },"unlock":function(){ //TODO this.viewModel.data.locked = 0 this.viewModel.data.writing = 0 },"del":function(){ let rec = this.getValue() let res = this.viewModel.data.store.del( rec ) if( res ){ this.viewModel.data.record = null this.viewModel.data.locked = 0 }else this.debug( 'TODO error delete' ) if( this.closeOnDelete ) this.close() //TODO if closable },"success":function( arg ){ if( arg ){ this.vmd.record = arg.data[0] this.vmd.writing = 1 this.vmd.locked = 1 } },"error":function(){this.debug('TODO'); this.viewModel.data.status = 'error' },"save":function(){ //TODO validate let session, action = this.vmd.recordId?'mod':'add' session = this.vmd.store[action]( this.getValue({action:action}), { node:this, event:'save' }) },"reset":function(){ this.setValue() //this.viewModel.data.form.reset() this.viewModel.data.form.dispatchEvent( new Event( 'input' )) }},"renderEvent":function(){ this.vmd._watch( 'busy', arg => { if( arg ){this.vmd.busyX = this.add({ tag:'div', cls:'w-100 h-100', css:'position:absolute;top:0;right:0;bottom:0;left:0;padding:0;background-color:rgba(0,0,0,0.2);justify-content:center;display:flex;align-items: center', items:[{cls:'loader',tag:'div'}]})} else this.vmd.body.removeChild( this.vmd.busyX ) }) this.vmd._watch('record', arg =>{ this.setValue( arg )}) if( this.dataset.hasOwnProperty( 'statusing' )) this.vmd._watch('status', arg => { this.vmd.statusX.classList.remove( 'alert-' + this.vmd.statusX.oldClass ) switch( arg ){ default: error('status ' + arg + ' not described'); break case 'idle': this.vmd.statusX.oldClass = 'dark'; break case 'changed': this.vmd.statusX.oldClass = 'info'; break case 'busy': this.vmd.statusX.oldClass = 'warning'; break case 'error': this.vmd.statusX.oldClass = 'danger'; break case 'success': this.vmd.statusX.oldClass = 'success'; break } this.vmd.statusX.classList.add( 'alert-' + this.vmd.statusX.oldClass ) }) //TODO controllare, escono stock di record {} //TODO destroy event this.vmd.form.on( 'submit', e => e.preventDefault()) this.on('change',function(){ let i, ftr = [], value = this.getValue() //this.debug(this,this.vmd,value) //TODO complettare for( i in value) ftr.push({property:i,value:value[i]}) //TODO operator if(this.vmd.eventListener){ this.vmd.eventListener.viewModel.data.storeFilter=ftr this.vmd.eventListener.reload() }}) //this.vmd.form.on( 'change', e => { console.log('change')}) //this.vmd.form.on( 'keydown', e => { console.log('keydown')}) this.vmd.form.on( 'keydown'/*input*/, Libra.debounce(( e ) => { let i, newValue = this.getValue(), input = e.target this.vmd.changed = 0 //this.debug('input',e,this,e.target.name,e.target.value) this.vmd.cacheValue [ input.name ] = input.value this.fireEvent({name:'change',detail:{value:newValue,valueOld:this.vmd.oldValue}}) this.vmd.status='idle' for( i in newValue ) if( newValue [ i ] !== this.vmd.oldValue[ i ]){ this.vmd.changed = 1 this.vmd.status='changed' break } //if( /*this.vmd.changed &&*/ this.vmd.preview && this.vmd.preview.value ) this.viewController.preview({target:this.vmd.preview}) }, 500 )) },"renderBodyItem":function( item ){ item.form=this.viewModel.data.form.id if( !this.viewModel.data.autofocusSetted ){ this.viewModel.data.autofocusSetted = 1 item.setAttribute( 'autofocus' , '' ) if( !("autofocus" in document.createElement( "input" ))) item.focus() }}}, libraMenu:{ extends:"libraContainer", customElementsDefine:"libra-menu", init:function(){ let a = this.childNodes[ 0 ], id = "ddn-" + this.id, rem = 0 if( a instanceof HTMLAnchorElement ){//bind lo ha creato a.classList.add( 'nav-link', 'dropdown-toggle' ) a.dataset.toggle = 'dropdown' a.setAttribute( 'aria-haspopup', true ) a.setAttribute( 'aria-expanded', false ) }else{ rem = 1 a = { tag:'a', cls:'nav-link dropdown-toggle', id: id + '-a', attr:{ "data-toggle": "dropdown", "aria-haspopup": true, "aria-expanded": false }, text: a.textContent } } this.viewModel.data.body = this this.add({ tag:'li', renderBodyItemDone:1, cls:'dropdown', css:'list-style-type:none', items:[ a, { tag:'ul', cls:'dropdown-menu dropdown-menu-right', css:'margin-top: 0', attr:{ "aria-labelledby": id + '-Link'}} ] }) this.viewModel.data.body = this.$$( 'ul' )[ 0 ] if( rem ) this.removeChild( this.childNodes[ 0 ]) this.super() },"renderCss":function(){this.super(); this.classList.add( 'menu' )},"initAttribute":function(){ this.super() this.dataset.templateName = 'menu' }},"libraCombobox":{"extends":"libraMenu","customElementsDefine":"libra-combobox","viewModel":{"data":{"selectedRecord":null,"value":null}},"set value":function(value){ if( value === null ) return value let i, sr, vmd=this.viewModel.data this.valueOld = this.valueInt this.valueInt = value if( !vmd.renderDone ) return false if( !this.isSetRecord ){ sr = vmd.store.filter ({ property: this.dataset.propertyValue, value: value })[ 0 ] vmd.selectedRecord={} for( i in sr ) vmd.selectedRecord[ i ] = sr[ i ] }else sr = vmd.selectedRecord if( vmd.input ) vmd.input.value = ( sr && this.dataset.propertyValueRaw in sr ) ? sr[ this.dataset.propertyValueRaw ]: value if( this.viewModel.data.expanded ) this.collapse() this.isSetRecord = 0 this.fireEvent({name:'input',detail:{ target:this }}) this.fireEvent({name:'change',detail:{ record: sr, item: this, value: value, valueOld: this.valueOld, target: vmd.input }}) return this.valueInt },"get value":function(){ return this.valueInt },"init":function(){ let ds = this.dataset this.viewModel.data.inputId = this.id this.id += '-combo' ds.propertyValueRaw = ds.propertyValueRaw || 'text' ds.propertyValue = ds.propertyValue || Libra.data.eav.id //this.super() this.viewModel.data.trigger = {} },"initAttribute":function(){ let ds = this.dataset ds.notLoad = 1 ds.char = ds.char || 2 ds.editing = ds.editing || 1 if( ds.editing === '0' || ds.editing === 'false' ) this.removeAttribute( 'data-editing' ) this.super() },"expand":function(){ this.vmd.expanded = true this.reload({ value: this.vmd.input.value }) this.vmd.body.style.display = 'block' },"reset":function(){ this.value = null this.vmd.input.value = null this.record = null this.vmd.trigger.clear.hidden = true },"collapse":function(){this.vmd.expanded = false; this.vmd.body.style.display = '' },"getValue":function(){return this.value },"setValue":function( arg ){ this.value = arg },"renderCss":function(){this.classList.add( 'dropdown' )},"render":function(){ let input={ tag:'div', cls:'input-group',//mb-2 mr-sm-2 css:'width:100%', items:[{ tag:'input', css:(this.width?'width:'+this.width-36+'px':''),id: this.vmd.inputId, attr:{ /*readonly:!!!this.dataset.editing,*/placeholder: this.getAttribute( 'placeholder' ) || "select.." }, cls:'dropdown-toggle'//form-control },{ tag:'ul', cls:'dropdown-menu', css:'margin-top: 0', attr:{ 'aria-labelledby': this.vmd.inputId + '-link' } },{ tag:'div', /*css:'width:20px',*/cls:'input-group-append cp', items:[{ tag:'div', cls:'input-group-text', hidden:true, html:'×' }]}]} if( this.width ) input.items[0].css = 'width:' + this.width + 'px' if(!this.dataset.hasOwnProperty('editing')) input.items[0].attr.readonly=1 if(!this.dataset.hasOwnProperty('hidetrigger')) input.items[2].items.push({ tag:'div', cls:'input-group-text dropdown-toggle'}) //this.super() this.vmd.input=this.add(input) this.vmd.body = this.vmd.input.children[ 1 ] this.vmd.trigger.clear = this.vmd.input.children[ 2 ].children[ 0 ] this.vmd.trigger.expand = !this.dataset.hasOwnProperty( 'hidetrigger' ) ? this.vmd.input.children[ 2 ].children[ 1 ] : this.vmd.input.children[ 0 ] this.vmd.input = this.vmd.input.children[ 0 ] this.vmd.input.on( 'change', e => e.stopPropagation()) this.vmd.trigger.expand.on( 'click', e => { if( this.vmd.expanded ) this.collapse(); else this.expand()}) this.vmd.trigger.clear.on( 'click', e => this.reset()) this.vmd.body.on( 'click', e => { let i, sr; this.isSetRecord = 1; sr = e.target.record; for( i in sr ) this.vmd.selectedRecord={};this.vmd.selectedRecord[i]=sr[ i ]; this.value = e.target.record[ this.dataset.propertyValue ]}) this.vmd.input.on( 'blur', Libra.debounce( e => this.viewModel.data.body.style.display = '', 300)) this.vmd.input.on( 'input', e => { this.vmd.trigger.clear.hidden = !this.vmd.input.value if( this.vmd.input.value.length >= this.dataset.char ) this.expand() else this.collapse() }) if( typeof this.valueInt !== 'undefined' ) this.value = this.valueInt }}, libraButton:{extends:"HTMLButtonElement",customElementsDefine:"libra-button"}, libraA:{extends:"HTMLAnchorElement",customElementsDefine:"libra-a"}, libraInput:{extends:"HTMLInputElement",customElementsDefine:"libra-input"}, libraPocket:{ extends:"libraContainer", customElementsDefine:"libra-pocket", initConnect:function(){ switch( this.type ){ case 'group': this.vmd.tree = this.add({ viewTitle: "authorizations", xtype: "tree", store:{ data: Libra.data.group }, checking:1, //checked:'s_0', events:{ check: e => this.target.dataset.group = e.target.checked } }) this.vmd.tree.checked = this.target.dataset.group this.target.vmd.pocket = this break case 'preview': let tgt = this.target || this.parentNode, editor tgt.vmd.pocket = this if( tgt.tagName==='LIBRA-CODE') editor = tgt.vmd.codearea.editor; else /*'LIBRA-EDITORCODE'*/ editor = tgt.vmd.editor editor.pocket = this this.vmd.preview = this.add( editor.getValue().eval()) editor.on( 'change', Libra.debounce( function(editor){editor.pocket.delAll().add( editor.getValue().eval())}, 500)) //this.vmd.preview = this.add( codearea.value.eval()) break } },"disconnectedCallback":function(){ let editor,tgt=this.target if( tgt.tagName==='LIBRA-CODE') editor = tgt.vmd.codearea.editor; else /*'LIBRA-EDITORCODE'*/ editor = tgt.vmd.editor tgt.vmd.pocket = editor.pocket = null delete( editor.pocket ) delete( tgt.vmd.pocket ) } }, libraEditorHtml:{ extends:"libraForm", customElementsDefine:"libra-editorhtml", initAttribute:function(){ this.super() this.dataset.editing = 1 }, init:function(){ this.super() let vmd = this.viewModel.data vmd.editor = add({ parent:vmd.body, tag:'div', html:'', attr:{ contenteditable:1 }}) vmd.items.push( vmd.editor ) //this.viewModel.data.editor.contenteditable=true this.viewModel.data.targetName = '' this.viewModel.data.targetType = 'object' this.tbar = this.tbar || [] this.tbar = this.tbar.concat([ { tag:'div', layout:'buttongroup', defaults:{ xtype:'button' }, items:[ {iconCls:'fa-file',title:'clear',handler:() => { let vmd = this.viewModel.data; if( !vmd.isCode && confirm( 'Sei sicuro?' )){vmd.editor.innerHTML = '' }}}, {iconCls:'fa-print',title:'print',handler:() => { if(!this.viewModel.data.isCode){return }; let w = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes");w.document.open(); w.document.write("Print<\/title><\/head><body onload=\"print();\">" + vmd.editor.innerHTML + "<\/body><\/html>");w.document.close()}}, {iconCls:'fa-undo',title:'undo',handler:'format',cmd:'undo'}, {iconCls:'fa-redo',title:'redo',handler:'format',cmd:'uredo'}] },{ tag:'div', layout:'buttongroup', defaults:{ handler:'format',xtype:'button' }, items:[{ iconCls:'fa-copy', title:'copy', cmd:'copy'}, { iconCls:'fa-cut', title:'cut', cmd:'cut' },{ iconCls:'fa-paste', title:'paste', cmd:'paste' }] },{ tag:'div', layout:'buttongroup', defaults:{ handler:'format',xtype:'button' }, items:[{iconCls:'fa-bold',title:'bold',cmd:'bold'},{iconCls:'fa-italic',title:'italic',cmd:'italic'},{iconCls:'fa-underline',title:'underline',cmd:'underline'},{iconCls:'fa-remove-format',title:'remove format',cmd:'removeFormat'}] },{ tag:'div', layout:'buttongroup', defaults:{ handler:'format',xtype:'button' }, items:[ {iconCls:'fa-align-left',title:'justifyleft',cmd:'justifyleft'}, {iconCls:'fa-align-center',title:'justifycenter',cmd:'justifycenter'}, {iconCls:'fa-align-right',title:'justifyright',cmd:'justifyright'}, {iconCls:'fa-list-ol',title:'insertorderedlist',cmd:'insertorderedlist'}, {iconCls:'fa-list-ul',title:'insertunorderedlist',cmd:'insertunorderedlist'}, {iconCls:'fa-quote-right',title:'italic',cmd:'formatblock,blockquote'}, {iconCls:'fa-outdent',title:'outdent',cmd:'outdent'}, {iconCls:'fa-indent',title:'indent',cmd:'indent'} ] }, { xtype:'button',iconCls:'fa-link',title:'link',handler:()=>{let sLnk=prompt('inserire URL','https:\\/\\/');if(sLnk&&sLnk!=''&&sLnk!='https://'){formatDoc('createlink',sLnk)}}}, { tag:'div', layout:'buttongroup', defaults:{ tag:'input',type:"color",cls:'btn cp btn-outline-secondary btnBar',css:'width: 31px;height: 31px;padding: 2px;' }, items:[{ title:'colore testo', value:"#ffffff",events:{onchange: e => {formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0}}}, { title:'colore sfondo', value:"#000000", events:{onchange: e => {formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0}}}] },{ xtype:'combobox', propertyValue:'text', width:100, events:{onchange: e => {formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;}}, attr:{ placeholder:'format' }, store:{ fields:['text','val'], data:[ {text:'Title 1',val:'h1'}, {text:'Title 2',val:'h2'}, {text:'Title 3',val:'h3'}, {text:'Title 4',val:'h4'}, {text:'Title 5',val:'h5'}, {text:'Sottotitolo',val:'h6'}, {text:'Paragrafo',val:'p'}, {text:'Preformattato',val:'pre'} ]} },{ xtype:'combobox',propertyValue:'text',width:100, events:{onchange: e => {formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0}}, attr:{ placeholder:'font' }, store:{ fields:['text'], data:[{text:'Arial'},{text:'Arial Black'},{text:'Courier New'},{text:'Times New Roman'}]} },{ xtype:'combobox',propertyValue:'text',width:100, events:{onchange: e => {formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0}}, attr:{ placeholder:'misura' }, store:{ fields:['text','val'], data:[{text:'piccolissimo',val:1},{text:'piccolo',val:2},{text:'normale',val:3},{text:'grande',val:4},{text:'grande2',val:5},{text:'grande3',val:6},{text:'grande4',val:7}]} } ]) //this.super() },"initConnect":function(){ //this.dataset.modelName='code' //this.dataset.storeName = 'storeCode' //this.viewModel.data.editor=this.add({tag:'div',text:'asd',contenteditable:true}) },"renderCss":function(){}, viewController:{ format:function(e){ let vmd = this.viewModel.data, cmd = e.target.dataset.cmd.split('.') if(!vmd.isCode){document.execCommand(cmd[0], false, cmd[1]); vmd.editor.focus()} }, get:function(){ let code = '', vmd = this.viewModel.data, argToSend = { what:'source', from:'remote', targetName:vmd.targetName, targetTypeEav:'object' //TODO combobox } vmd.valueSource = '' //if(viewModel.data.info.pressed) //TODO abilitare //argToSend.targetInfo=true; code = Libra.Eav.getObject( argToSend,{ scope:this, fn:function(res,args){ let viewModel = this.viewModel, code = res.data[ 0 ], targetTypeEav = 'object', path = vmd.targetName code = code.object //if(!viewModel.data.info.pressed){ TODO abilitare //code=code['object']; //targetTypeEav=res.data[0]['targetTypeEav'];} code = JSON.stringify( code ) switch( targetTypeEav ){ case "property": code = JSON.parse( code ) if( typeof code === 'string' ) code=code.replace(/\;\;\;}$/g,'}'); else code = code.toString() break case "object": code = code.replace( /(\"function\s*([A-z0-9]+)?\s*\(.[\s\S]*?\;\;\;\}\")/ig, function(a){ a=a.replace(/\/\*libraAuto\<\@\@\@/g,'<@@@').replace(/\@\@\@\>libraAuto\*\//g,'@@@>'); a=a.replace(/\;\;\;\}/g,'}'); a=JSON.parse(a); return a }) break default: //TODO gestire meglio code='' path='<b style="color:red !important">error</b>' break } //viewModel.set('valueSource',code); //TODO vmd.editor.setValue( code ) if( vmd.title ) vmd.title.textContent = path vmd.libraView.viewController.setViewTitle( path ) let lang = 'javascript' if( vmd.targetName.split( '.' )[ 0 ] === 'php' ) lang = 'php' vmd.comboboxMode.value = lang }})}, save:function(){ let code, vmd = this.viewModel.data, target = this.viewModel.data.editor.getValue().trim(), targetName = this.viewModel.data.targetName if( !targetName ) code = target else code = "{'" + targetName + "':" + target + "}" Libra.Eav.save( code, { apply:false /*TODO attivare viewModel.data.apply.pressed*/, scope:{ self: this, target: target, targetName: targetName },fn:function(res){ let vmd=this.self.viewModel.data if(res.status && vmd.title) vmd.libraView.viewController.setViewTitle(path)//this.self.viewModel.data.title.textContent=this.targetName //TODO //this.controller.view.libraView.setPath(this.targetName); /*if(this.controller.getViewModel().data.apply.pressed){ if(this.targetName){ var arrrTargetName=this.targetName.split('.'); switch(arrrTargetName[0]){ case 'js': //eseguire direttamente arrrTargetName[0]='window'; var propertyName=arrrTargetName[(arrrTargetName.length-1)]; arrrTargetName.pop(); var path=arrrTargetName.join('.'); (new Function('Libra.mergeFunction('+path+',{'+propertyName+':'+this.target+'})'))(); break;}}}*/ }}) },"preview":function(e){ let vmd = this.viewModel.data, btn = e.target, preview = Libra.data.reference.wmPreview preview.delAll() if( btn.getValue()){ //vmd.isPreview = 1 let obj=null, code = this.viewModel.data.editor.getValue().trim() obj = code.eval() this.debug('preview',obj) if( obj ) return preview.add( obj ) } //vmd.isPreview = 0 }},"render":function(){ this.super() let vmd = this.viewModel.data vmd.textarea = vmd.form.$( 'textarea' ) vmd.form.classList.add( 'h-100' ) vmd.editor.classList.add( 'h-100' ) }}, binder:{ static:["get timeout","set timeout","delay","get queue","createProto","hash","transform"], constructor:function(obj){ let instance if(obj) instance = Libra.data.class.binder.createProto(obj, this) else instance = this Object.defineProperty( instance, '_binder', { configurable: true, value:{}}) Object.defineProperties( instance._binder, { 'properties':{ configurable: true, value:{}}, 'bindings':{ configurable: true, value:{}}, 'watchers':{ configurable: true, value:{}}, 'emitter':{ configurable: true, writable: true, value:{}} }) if(instance.__proto__&&instance./*__proto__.*/extends&&instance.__proto__.super&&Libra.data.class[instance./*__proto__.*/extends]){ /*instance=*/Libra.Class.super(instance, Libra.data.class[instance./*__proto__.*/extends]||window[instance./*__proto__.*/extends]) } return instance }, "get timeout":function(){return Libra.data.class.binder._timeout||0}, "set timeout":function(ms){Object.defineProperty(this,'_timeout',{configurable:true,value:ms})}, delay:function(ms=Libra.data.class.binder.timeout){ return new Promise((res,rej) => { if( ms > 0 ) setTimeout( res, ms ); else res()})}, "get queue":function(){return Promise.resolve()}, createProto:function(obj,instance){ let className = obj.constructor.name if( !this.prototypes ){ Object.defineProperty( this, 'prototypes', { configurable: true, value: new Map()})} if( !this.prototypes.has( className )){ let descriptor = { 'constructor':{ configurable: true, value: obj.constructor }} Object.getOwnPropertyNames( instance.__proto__ ).forEach( ( prop ) => { if( prop !== 'constructor' ){ descriptor[ prop ] = { configurable: true, value: instance[ prop ]}}}) this.prototypes.set( className, Object.create( obj.__proto__, descriptor )) } obj.__proto__ = this.prototypes.get( className ) return obj }, hash:function(str){ let _hash = 0 if( str.length === 0 ) return _hash for( let s of str ){ _hash = ( _hash - ( _hash << 5 )) + s.charCodeAt() _hash |= 0 } return _hash }, transform:function(obj,prop){ let descriptor, nativeSet, newGet = /*typeof obj[ prop ]==='function'?obj[ prop ]:*/function(){return this._binder.properties[ prop ] } newSet = function( value ){ let queues = [ Libra.data.class.binder.queue, Libra.data.class.binder.queue ] if( this._binder.properties[ prop ] === value ) return let fn = prop.firstToUpperCase(), fnGet = 'get' + fn, fnSet = 'set' + fn if( this._libraSync ){ debug('-----------------------save:',this._libraObjectName,':',value) let objToSave = {} objToSave[ this._libraObjectName ] = value Libra.Eav.save( objToSave ) } // debug('ctrll1',fnGet,this,this.viewController) let _tgt = this.viewController || this if( _tgt.hasOwnProperty( fnGet )){value = _tgt[ fnGet ]({ property: prop, value: value, that: this })/*;this[prop]=value*/} Object.defineProperty( this._binder.properties, prop, { configurable: true, value: value }) if( this._binder.bindings[ prop ]){ this._binder.bindings[ prop ].forEach(([ prop, ms ], boundObj ) => { if( boundObj === this._binder.emitter ){ this._binder.emitter = null return } if( boundObj[ prop ] === value ) return queues[ 0 ] = queues[ 0 ] .then(() => Libra.data.class.binder.delay( ms )) .then(() => { requestAnimationFrame(() => { let valueOld = boundObj[prop], fn = 'set' + prop.firstToUpperCase() boundObj._binder.emitter = obj debug( 'ctrll2',value, fn, 'this:', this,'this:vc:', this.viewController, 'bound:',boundObj,'bound:vc:', boundObj.viewController ) let _tgt = boundObj.viewController || boundObj // if( _tgt.hasOwnProperty( fnGet )){value = _tgt[ fnGet ]({ property: prop, value: value, that: this })/*;this[prop]=value*/} if( /*boundObj*/_tgt.hasOwnProperty( fn )){value = _tgt[ fn ]({ property: prop,value: value,valueOld: valueOld })} boundObj[ prop ] = value })})}) queues[ 0 ] = queues[ 0 ].catch( err => error( err )) } if( this._binder.watchers[ prop ]){ this._binder.watchers[ prop ].forEach(([ cb, ms ]) => { queues[ 1 ] = queues[ 1 ] .then(() => Libra.data.class.binder.delay( ms )) .then(() => { cb.call( this,value/*, this*/ )}) })} if( this._binder.watchers[ '*' ]){ this._binder.watchers[ '*' ].forEach(([ cb, ms ]) => { queues[ 1 ] = queues[ 1 ] .then(() => Libra.data.class.binder.delay( ms )) .then(() => { cb( value, this )}) })} queues[ 1 ] = queues[ 1 ].catch( err => error( err )) } //if(obj.constructor.name.indexOf('HTML')===-1) //if(!obj.constructor.name.match(/HTML|libra/)) if( !obj.hasOwnProperty( 'parentNode' )) descriptor = { configurable: true, enumerable: true, get: newGet, set: newSet } else{ if( 'value' in obj ){ descriptor = Object.getOwnPropertyDescriptor( obj.constructor.prototype, 'value' ) || Object.getOwnPropertyDescriptor(( window[ obj./*__proto__.*/extends ] || Libra.data.class[ obj./*__proto__.*/extends ]).prototype, 'value' ) obj.on( 'input', function( evob ){ //keydown if(evob.key.length === 1){ //newSet.call(this, this.value + evob.key); //}else{ Libra.data.class.binder.queue.then(() => newSet.call( this, this.value )) //} }) }else descriptor = Object.getOwnPropertyDescriptor( Node.prototype, 'textContent' ) nativeSet = descriptor.set descriptor.set = function( value ){ nativeSet.call( this, value ) newSet.call( this, value ) }} Object.defineProperty( obj._binder.properties, prop, { configurable: true, value: obj[ prop ] }) Object.defineProperty( obj, prop, descriptor) // debug('trs',prop,/*obj,*/obj[ prop ]) return obj }, _bind:function(ownProp,obj,objProp,ms){ if( !this._binder.bindings[ ownProp ]){ this._binder.bindings[ ownProp ] = new Map() Libra.data.class.binder.transform( this, ownProp ) } if( this._binder.bindings[ ownProp ].has( obj )) return !!console.log( 'Binding for this object is already set', this, obj ) this._binder.bindings[ ownProp ].set( obj, [ objProp, ms ]) if( !obj._binder.bindings[ objProp ] || !obj._binder.bindings[ objProp ].has( this )) obj._bind( objProp, this, ownProp, ms ) return this }, _unbind:function(ownProp,obj,objProp){ debug('_unbind',ownProp,obj,objProp,this._binder.bindings,obj._binder.bindings) try{ this._binder.bindings[ ownProp ].delete( obj ) obj._binder.bindings[ objProp ].delete( this ) return this } catch ( e ){return !!console.log( e )} }, _watch:function(prop = '*', cb, ms=0,node){ if( node && !node.id ) error('_watch: id undefined',node.id,node,prop,cb) let cbHash = (node ? node.id :'') + prop + cb.toString() cbHash = Libra.data.class.binder.hash( cbHash.replace( /\\s/g, '' )) //debug('cbHash',cbHash,prop) if( !this._binder.watchers[ prop ]){ this._binder.watchers[ prop ] = new Map() if( prop === '*' ) Object.keys( this ).forEach( item => Libra.data.class.binder.transform( this, item )) else if(!this._binder)Libra.data.class.binder.transform( this, prop ) } if( this._binder.watchers[ prop ].has( cbHash )) return !!console.log( 'Watchers of property ' + prop + ' is already set' ) this._binder.watchers[ prop ].set( cbHash, [ cb, ms ]) return cbHash }, _unwatch:function(prop='*',cbHash=0){ try{ debug( '_unwatch:TODO rifare hash',prop,cbHash,this._binder.watchers[prop]) this._binder.watchers[ prop ].delete( cbHash ) return this } catch ( e ){return !!console.log( e )} }},"libraModel":{"constructor":function(config){ if( !config.name ) config.name = 'modelDefault' if(!data.model[ config.name ]) error('model ' + config.name + ' is not defined' ) let i, field, store = config.store || config.node.viewModel.data.store, configFields = data.model[ config.name ].fields if( !data.model[ config.name ].dinamic ) Libra.data.model[ config.name ] = this this.config = config this.fields = {} this.relation = {} for( i = 0; i < configFields.length; i++ ){ field = configFields[ i ] if( typeof field === 'string' ) this.fields[ field ] = { name: field, text: field } else{ if( !field.text ) field.text = field.name this.fields[ field.name ] = field if( field.relation ) this.relation[ field.name ] = field.relation } } if( !Object.keys(this.relation).length ) delete( this.relation ) if( store && store.relation ) for( i in store.relation ){ if( i !== store.propertyId ) this.fields[ i ].relation = store.relation[ i ] } if( data.model[ config.name ].storeClass ) this.store = new Libra.data.class[ data.model[ config.name ].storeClass ]() return this }}, libraStore:{ constructor:function(cfg={}){ this.isSync = cfg.hasOwnProperty('isSync')?cfg.isSync:0//TODO abilitare 1 this.targets = {} this._cache = { events:{}} this.events = {} if( cfg.name && !cfg.name.includes( '.' )) cfg.name = 'data.store.' + cfg.name this.config = cfg this.name = cfg.name this.nameData = this.name + '.data' this.busDb = cfg.busDb || Libra.Eav.busDb( this.name ) //this.bus=cfg.bus||'db' this.init() this.applyBinding() //TODO analize forse non serve o farl osul lato server? return this },"fireEvent":function( str, arg ){ for(let i in this.targets) this.targets[i].fireEvent({name:str, detail:arg,bubbles:false})}, init:function(){ let i, cfg = this.config if( cfg.data && !cfg.name ){ this.bindingStore = this this.data = cfg.data this.model = { fields: cfg.fields } }else{ Libra.data.store[ this.name ] = this this.bindingStore = /*name.includes( '.' ) ?*/ this.name.eval()/* : data.store[ name ]*/ if(!this.bindingStore) error('store ' + this.name + ' not defined',this) if(this.bindingStore.events) for( i in this.bindingStore.events ) this.events[ i ] = this.bindingStore.events[ i ].bind( this ) this.text=this.bindingStore.text this.propertyId=this.bindingStore.propertyId this.relation = this.bindingStore.relation this.modelName = this.bindingStore.modelName this.model = Libra.getModel({ name: this.modelName,store:this }) this.data = this.bindingStore.data } this.data=this.prepareData(this.data) this.binding = true }, prepareData:function(data){ let i, isArr = Array.isArray( data ) for( i in data ){ data[ i ][ Libra.data.eav.key ] = isArr ? + i : i if( !data[ i ][ Libra.data.eav.id ]) data[ i ][ Libra.data.eav.id ] = isArr ? + i + 1 : i/*Libra.getId()*/ if( data[ i ].child ){ data[ i ].isChild = true data[ i ].child = this.prepareData(data[ i ].child) //TODO gestire bene id sechild aggiungere parent, id crescente, etc }} return data }, getData:function(filter=[]){ let data if( filter.length ) data = this.filter( filter ); else data = this.data if( this.events.load ) data = this.events.load( data, { filter: filter }) || data data = this.prepareData( data ) //TODO forse meglio applicare i filtri come argumento return data//data.store[this.config.name].data }, filter:function( arg ){ switch( typeof arg ){case 'string': case 'number': arg = [ { property: Libra.data.eav.id, value: arg } ] } if( !Array.isArray( arg )) arg = [ arg ] //TODO filter per piu argumenti if( typeof arg === 'string' ) arg.value = arg if( Array.isArray( this.data )) return this.data.filter(( rec, key, data ) => { let i, ret = 1, ftr for( i in arg ){ ftr = arg[ i ] switch ( typeof rec[ ftr.property ]){ case 'string': ret = rec[ ftr.property ].toLowerCase().indexOf( ftr.value.toLowerCase()) > -1; break default: ret = rec[ftr.property] == ftr.value; break } if( !ret ) break } return ret }) else return this.data }, del:function(arg){ if( !arg.hasOwnProperty( Libra.data.eav.id )){debug( 'store: error:' + Libra.data.eav.id + ' is ubsent in record', arg ); return false }else{ if( Libra.data.eav.key in arg ) delete( this.bindingStore.data[ arg[ Libra.data.eav.key ]]) else{ debug( 'TODO complettare delete in store', arg ) let i for( i in this.bindingStore.data ) if( this.bindingStore.data[ i ][ Libra.data.eav.id ] === arg[ Libra.data.eav.id ]){delete( this.bindingStore.data[ i ]); break } } return true } }, add:function( rec, arg = {}){ this.nodeActive = arg.node this.busy( true ) this.bindingStore.data.push( rec ) //TODO forse bisogna mettere binding x salvare sul server??? //TODO error //if( arg.node ){this.vmd.busy = false; this.vmd.status = 'success'; arg.node.viewController.success( rec )/*TODO error*/} //TODO return session rec },"getRecordByKey":function( arg ){return this.bindingStore.data[ arg ] },"getRecordById":function( arg ){return data.store[ this.config.name ].data[ arg - 1 ] },"applyBinding":function(){ let config = this.config this.bindingStore.data = new Proxy( this.bindingStore.data, { set:(target,property,value,receiver) => { if( property === 'length' ) return Reflect.set( target, property, value, receiver ) let i, act = 'mod', prop = +property, rec = receiver[ prop ] if( rec ){ //TODO forse disable sync? for( i in value ) rec[ i ] = value [ i ] }else{ act = 'add' rec=value value[ Libra.data.eav.key ] = prop if( !value[ Libra.data.eav.id ]) value[ Libra.data.eav.id ] = Libra.getId() //prop + 1 } return this.sync({ target: target, property: prop, record: rec, receiver: receiver, action: act, eventName:'set', scope:this, fn:function( arg ){ let i if( Reflect.set( arg.target, arg.property, arg.record, arg.receiver )){ if( arg.action === 'add' ) for( i in this.targets ) this.targets[ i ].addRecord( arg.record, { key: arg.property }) this.fireEvent( 'datachange', arg,false ) return true } return false }})}, deleteProperty:( target, prop ) => { if( prop in target ) return this.sync({ target: target, property: prop, record:target[ prop ], action:'del', eventName:'deleteProperty', scope:this, fn:function( arg ){ let i, ret = Reflect.deleteProperty( arg.target, arg.property ) if( ret && +arg.property >= 0 ){ for( i in this.targets ) this.targets[ i ].delRecord( arg.record ) this.fireEvent( 'datachange', arg,false ) } return ret } }) }}) if( !this.bindingStore._binder ) this.bindingStore = new Libra.data.class.binder( this.bindingStore ) this.bindingStore._watch( 'data', ( arr, arg2 ) => { let i, j arr=this.prepareData(arr) let data = this.getData() let from = arr/*data*/ //TODO vedere bene quando serve getData: oc, e poi? for( i in this.targets ){ this.targets[ i ].delAll() for( j in from ){ let addArg = {} if( this.binding ) addArg[ Libra.data.eav.key ] = +j this.targets[ i ].addRecord( from[ j ], /*{ key: +j }*/addArg ) //TODO capire perche } } //arg2._unwatch('data','data') arg2._binder.watchers.data.clear() this.applyBinding() this.fireEvent( 'datachange',{ eventName:'replace', value: arr }) }) },"register":function( arg ){this.targets[ arg.id ] = arg },"unRegister":function( arg ){delete(this.targets[ arg.id ])},"load":function( arg = null ){ debug('store load TODO complettare',arg)//TODO completttare },"mod":function( rec, arg = {}){ this.nodeActive = arg.node this.busy( true ) this.bindingStore.data[ rec[ Libra.data.eav.key ] ] = rec },"sync":function(arg){ if( !this.isSync ){ if( arg.node ){this.vmd.busy = false; this.vmd.status = 'success'; arg.node.viewController.success( rec )/*TODO error*/}; return arg.fn.call(arg.scope,arg) } else{ let sync, id = arg.record[ Libra.data.eav.id ], send = { isStore:1, bus:'msg', class:'Eav', fn:arg.action, busData:'server', targetTypeEav:'object', storeObjectName: this.name, storeObjectDataName:this.nameData, busDb: this.busDb //storeObjectId:_libra.storeObjectId, //storeClassDataId:_libra.storeClassDataId, //storeObjectDataId:_libra.storeObjectDataId, } switch(arg.action){ case 'mod': send[Libra.data.eav.id]=arg.record[Libra.data.eav.id] case 'add': send.data = [ arg.record ] break case 'del': send[Libra.data.eav.id]=arg.record[Libra.data.eav.id] break } Libra.data.debug._libraDebug=true sync = Libra.send( send,{ fn:function(res){ let ret debug('--store:sync:ccbb',res,this) if(res.status){ if(res.data&&res.data[0])this.arg.record=res.data[0] ret = this.arg.fn.call(this.arg.scope,this.arg) } else debug('store:Sync:todo error',res) if(this.store.nodeActive) this.store.nodeActive.viewController[res.status?'success':'failure']( res ) this.store.busy(false) return ret||res.status },scope:{store:this,arg:arg} }) return sync } },"busy":function(arg){ if( !this.nodeActive ) return false let vmd = this.nodeActive.vmd if(arg){ vmd.busy = true vmd.status = 'busy' }else{ vmd.busy = false delete( this.nodeActive ) this.nodeActive = null } }},"libraStoreObject":{"extends":"libraStore","init":function(){ let config = this.config this.name=config.name this.bus=config.bus||'object' this.binding = false this.path = config.path || '' this.dataRoot = { Libra: window[ 'Libra' ], data: window[ 'data' ]/*, TODO complettare html: window[ 'html' ]*/ } if( this.path === '' ) this.data = this.dataRoot else error('TODO:libraStoreObject path') this.bindingStore = this //TODO ??? this.applyBinding(this) },"setPath":function(path){ if( path === '..' ){ //TODO string.pop? this.path = this.path.split( '.' ) this.path.pop() this.path = this.path.join( '.' ) if( this.path ) this.bindingStore.data = path.evalObjectPath() else{ this.path = ''; this.bindingStore.data = this.dataRoot } }else{ this.path += ( this.path !== '' ? '.' :'' ) + path this.bindingStore.data = this.bindingStore.data[ path ] } },"getData":function(){ //TODO forse meglio applicare i filtri come argumento let res = this.path === '' ? [] : [ { property:'..'/*, _libraKey:'..'*/ }], data = this.data, item if( res.length ) res[ 0 ][ Libra.data.eav.id ] = '..' for( let prop in data ){ item = Object.getOwnPropertyDescriptor( data, prop ) item.property = item[ Libra.data.eav.id ] = prop item.leaf = typeof item.value !== 'object' res.push( item ) } return res },"getRecordByKey":function( arg ){return arg }},"libraViewModel":{"setReference":function( str, arg ){ if( !(str in this.data )){ this.data[ str ] = arg this.parent.setReference( str, arg ) } },"constructor":function(that){ this.node = that this.data = that.viewModel ? that.viewModel.data :{} that.viewModel.data.node = that this.data = new Libra.data.class.binder( this.data ) let parent = that.parentNode.getViewModel?that.parentNode:that.parentNode.libraParent this.parent=/*(that.parentNode||that.parentNode.libraParent)*/parent.getViewModel() },"get":function( arg ){ if(typeof arg === 'string' ){ if( this.data[ arg ]) return this.data[ arg ]; else return this.parent.get( arg ) }else{ if( this.data[ arg.source ] && this.data[ arg.source ][ arg.property ]) return this.data[ arg.source ][ arg.property ]; else return this.parent.get( arg ) } },"set":function(prop,val){this.data[prop]=val},"onConnectedCallback":function(){ let node = this.node, vmd = node.viewModel.data , bovmd if( node.bind ){ let res = Libra.Dom.bind({ bind: node.bind, node: node }) //TODO vedere bene come fare xke possono esserci piu' di un bind //for(let resProp in res) //vmd.bindedObject = res.sourceObject || res.source //TODO serviva per prendere il nome dello store in demobind dalal tabella a form //bovmd = vmd.bindedObject.viewModel ? vmd.bindedObject.viewModel.data : null //if( bovmd && bovmd.store ) node.dataset.storeName = bovmd.store.config.name } },"getObject":function(arg){ //let source if(!arg.sourceString&&!arg.sourceProperty)error('libraViewModel:getObject') //TODO aggiungere se stringa ad es lang.title if(arg.sourceString) arg.source = ('this.'+arg.sourceString).eval(this.data) else arg.source = this.data if( arg.source && arg.sourceProperty in arg.source/*arg.source.hasOwnProperty(arg.sourceProperty)*/){arg.value=arg.source[arg.sourceProperty]; return arg.source } arg.source=null return this.parent.getObject(arg) }},"libraViewController":{"constructor":function(that){ let i, arrProto = [ ...Libra.data.class.prototypeExclude, 'node' ] this.node = that for( i in that.viewController ) this[ i ] = that.viewController[ i ].bind( that ) let parent = that.parentNode.getViewController?that.parentNode:that.parentNode.libraParent this.parent = parent.getViewController() //this.parent=that.getViewController() //TODO forse serve bind for( i in this.parent ) if( !arrProto.includes( i ) && !this[ i ]) this[ i ] = this.parent[ i ].bind( that ) },"onConnectedCallback":function(){}},"libraTemplate":{"constructor":function( arg ){ Libra.data.template[ arg.name ] = this if( !data.template[ arg.name ]){ error( 'template ' + arg.name + ' is ubsent' ) arg.name = 'default' } let tpl = data.template[ arg.name ] if( typeof tpl === 'string' ){ if(tpl.match(/^function/)) this.template = tpl.eval() else this.template = new Function( 'scope', 'return ' + tpl ) }else this.template = tpl if(typeof this.template==='function')Object.defineProperty( this.template, 'name', { value:'template_' + arg.name }) return this },"use":function( arg ){ return this.template.call( arg.self, arg.scope ) }}},"data":{"template":{"menu":function(scope){ /*let li=document.createElement('li') parent.appendChild(li) if(item.nodeType) li.appendChild(item) else{ if(!item.text) this.debug('error: TODO: quale campo devo inserire?',item) li.textContent=item.text li.record=item item=li} item.classList.add('dropdown-item') if(item.childElementCount!==0){ li.classList.add('dropdown-submenu') item.classList.add('dropdown-toggle') let ul=document.createElement('ul') ul.classList.add('dropdown-menu') li.appendChild(ul) for(let i=0;i< item.children.length;i++) this.insert(item.children[i],ul)}*/ let ret={ tag:'li', //text:scope.text, record:scope, cls:'dropdown-item' } if(scope.xtype||scope.tag||scope.tagName) ret.items=[scope] else ret.text=scope.text if(scope.items&&scope.items.length){ ret.cls+=' dropdown-submenu dropdown-toggle' ret.items=[{ tag:'ul', cls:'dropdown-menu', items:[] }] for(let i=0;i< scope.items.length;i++){ ret.items[0].items.push(this.template.use({ self: this, scope: scope.items[i]})) } } return ret },"default":"{\"tag\":\"div\",\"text\":scope.text}","tableTr":function(scope){ let i, td, rel, column , tds = [], tr = { tag:'tr',hash:scope.hash }, vmd = this.viewModel.data debug('asd') tr[ Libra.data.eav.id ] = scope[ Libra.data.eav.id ] tr[ Libra.data.eav.key ] = scope[ Libra.data.eav.key ] tr.record = scope if( this.dataset.hasOwnProperty( 'checking' )) tds.push({ tag:'th', scope:'row', items:[{ tag:'input', type:'checkbox', handler: this.check}]}) for( i in vmd.model.fields ){ column = vmd.model.fields[ i ] rel = column.relation td = { tag:'td' } if( rel ){ let store = Libra.getStore( rel.storeName[ 0 ]), //TODO ottimizzare, forse cache per relationStore:{_libraobjectId:value}} per non fare filter ogni volta source = store.filter( scope[ column.name ])[ 0 ] td.bind = { text:{ source: source, sourceProperty:'text'//TODO configurabile?? }} }else{ if( vmd.store.binding ) td.bind = { text:{ source: scope, sourceProperty: column.name }} else td.text = scope[ column.name ] } tds.push( td ) } tr.items = tds return tr }, treeTr:function(scope){ let i, td, column , tds = [], tr = { tag:'tr', css:'width:100%' }, checking = this.dataset.checking == 1 tr[ Libra.data.eav.id ] = scope[ Libra.data.eav.id ] tr.id = scope.id || Libra.getId() tr[ Libra.data.eav.key ] = scope[ Libra.data.eav.key ] tr.record = scope if( checking ) tds.push({ tag:'th', scope:'row', css:'text-align: right; padding: .35rem;padding-right: 0rem; width: .5rem', items:[{ tag:'input', type:'checkbox', handler: this.check }]}) for( i in this.viewModel.data.model.fields ){ column = this.viewModel.data.model.fields[ i ] td = { tag:'td', css:'padding: .35rem;' + ( !checking ? 'padding-left: 2.25rem' :'' ), cls:' cp treeTd ', text: scope[ column.name ] //TODO manca bind } if( scope.lang ) td.lang = scope.lang td.cls += ( this.localName !== 'libra-nav' ? ' faTree' : '' ) + ' fa famr ' + ( scope.iconCls || 'fa-circle fa-xs' ) if( scope.hash ) tr.hash = scope.hash td.record = scope if(scope.isChild)tr.cls='treeTr treeCollapsed fa '//treeExpanded treeBusy tds.push( td ) //if(this.viewModel.data.store.binding) //le.dataset.data='data.store.'+this.dataset.storeName+'.data['+arg.key+'].'+column //else //le.textContent=row[column] } tr.items = tds return tr }, viewNotFound:"{\"tag\":\"div\",\"html\":'<img style=\"max-width: 100%;display: block;margin-left: auto;margin-right: auto;\" src=\"'+Libra.data.path.fw+'Libra/img/wip3.jpg\"/>'}", form:function(scope){ let id = this.id + '-' + scope.text, input = data.template.formInput.call( this, scope ), label = { tag:'label', cls:'col-sm-2 col-form-label', text: scope.text, attr:{ for: id } }, ret = { tag:'div', cls:'form-group row', items: [ label, { tag:'div', cls:'col-sm-10', items: [ input ] }]} if( scope.hideLabel ) ret.items.shift() if( scope.layout && scope.layout === 'fit' ) ret = input if( input ) return ret return null },"formInput":function(scope){ let id = this.id + '-' + scope.text, ret, tag='input', isAdd = true, vmd = this.viewModel.data, rel = scope.relation//vmd.store && vmd.store.relation && vmd.store.relation[scope.name] ? vmd.store.relation[scope.name]:null /*,transformTag={ text:'textarea', code:'codearea', html:'htmlarea'}*/ //tag = transformTag[ scope.type ] || tag if( rel ){ if( !['onetomany','onetoone'].includes(rel.type)) ret = { xtype:'combobox', cls:'col-sm-10', name:scope.text, storeName:rel.storeName[0] //css:'padding:0 15px 0 15px', } isAdd = false } if( isAdd ) switch(scope.type){ case 'code': ret = { xtype:'codearea',form:vmd.form.id,css:'width:100%',cls:'form-control',attr:{type:scope.type,id:id,name:scope.text}} break case 'text': tag = 'textarea' default: ret = { form:vmd.form.id,tag:tag,css:'width:100%',cls:'form-control',attr:{type:scope.type||'text',id:id,name:scope.text,placeholder:'insert '+scope.text}} break } return ret },"buttonEditing":function(arg){ let i, items=[], tgt = arg.target, btn = { xtype: "container", /*css:'padding: 0.5rem;',*/ layout: "buttongroup", defaults:{ xtype: "button", ui:'outline-secondary' }}, storeText = tgt.vmd.store.text tgt.tbar = tgt.tbar || [] switch( tgt.tagName ){ case 'LIBRA-FORM': case 'LIBRA-EDITORCODE': btn.defaults.form = tgt.vmd.form.id //TODO add title to button items = [ { iconCls:'fa-pencil', text:'lock', handler:'lock', bind:{ hidden:'{writing}' }}, { iconCls:'fa-unlock', text:'unlock', handler:'unlock', bind:{ hidden:'{!locked}', disabled:'{busy}' }}, { iconCls:'fa-floppy-o', text:'save', handler:'save', bind:{ hidden:'{!changed}', disabled:'{busy}' }, attr:{ type:'submit'}}, { iconCls:'fa-trash', text:'delete', handler:'del', /*hidden: false,*/bind:{ /*hidden: false'{!locked}',*/ disabled:'{busy}' }},//TODO sistemare hidden dopo aver sistemato locking { iconCls:'fa-ban', text:'cancel', handler:'reset', bind:{ hidden:'{!changed}' }, attr:{ type:'reset'}} ] if( tgt.dataset.hasOwnProperty( 'closing' )){items.push({ iconCls:'fa-times', text:'close', handler:'close' })} break case 'LIBRA-TABLE': items = [ { iconCls:"fa-plus", title:lang('add')+' '+storeText, handler:'add'}, { iconCls:"fa-pencil", title:lang('mod')+' '+storeText,handler:'mod'}, { iconCls:"fa-trash", title:lang('del')+' '+storeText, handler:'del'} ] break } if( tgt.tagName === 'LIBRA-EDITORCODE' ) for( i in items ) delete(items[ i ].text) btn.items = items tgt.tbar.push( btn ) return btn }}, view:{ // home:{html:'<img style="display: block;margin-left: auto;margin-right: auto;" src="'+Libra.data.path.fw+'Libra/img/wip3.jpg"/>'}, wm:{ defaultMobile:{ tag:"div", cls:"fit", id:"_libraWm", ref:"wm", items:[{ xtype:"container", items:[{ items:[{ tag:'div', attr:{"data-collapsed":0}, cls:"fa famr sidebar-brand d-flex align-items-center justify-content-center", css:"font-weight: 900;width:100%;background-color:#35baf6;border-bottom:1px solid #32404e !important", items:[{ xtype:"a",attr:{"data-collapsed":0}, css:'color:#fff', href:"#home", ref:"homeLink", lang:'title' },{ xtype:'button', iconCls:'fa-bars', css:'color:#fff;right:10px;position:absolute', handler:function(){ let _ref = Libra.data.reference, nav = _ref.nav, navUp = _ref.navUp, homeLink = _ref.homeLink // for(let i in [nav,navUp]) // debug('thisb',nav,navUp,navUp.dataset) function clps(e,d=null,f=null){ let a,b,c if( e.dataset.collapsed === '0' ){ a = d===null?"50px":d b = '1' c=1 }else{ a = f===null?"250px":f b = '0' c=0 } e.style.width = a e.style.flex = "0 0 "+a e.dataset.collapsed = b Libra.data.navCollapsed=c } clps(nav) clps(navUp) clps(homeLink,"0","181px") } // cls:"navbar-toggler", // type:"button", // attr:{"data-toggle":"collapse","data-target":"#navbarToggleExternalContent","aria-controls":"navbarToggleExternalContent","aria-expanded":"false","aria-label":"Toggle navigation"}, // items:[{tag:'span',cls:"navbar-toggler-icon"}] }] }], tag:"header", cls:"d-flex flex-row bg-white topbar", css:"height:4rem" },{ items:[{ cls:"navbar-nav bg-gradient-primary sidebar sidebar-dark accordion", css:"flex: 0 0 0;background-color: #32404e;color: #adb3b8! important;width: 0px !important;height:100% !important;min-height: 100% !important", attr:{"data-collapsed":1}, items:[{ xtype:"nav", ref:"wmMenuNavigation", storeName:"storeWmMenuNavigation" }], tag:"nav" },{ xtype:"carousel", cls:"wmMenuView card hView", css:"flex: 0 0 250px;margin: 7px 0px 7px 7px;", ref:"wmMenuView", hidden:true, itemName:"menuView", },{ xtype:"carousel", cls:"bg-white wmView carousel-inner hView", css:"margin: 7px;border: 1px solid rgba(0,0,0,.125)", ref:"wmView", storeName:"storeWmView", bind:{ eventEmitter:"{reference.wmMenuNavigation}", bindEvent:"{reference.wmMenuNavigation}" }, itemName:"view", events:{ add:function(e){ let menu = Libra.data.reference.wmMenuNavigation, view = e.detail.view, vmd = view.vmd, ds=view.dataset, hash = ds.hash, menuNode = view.vmd.menuNode, menuItem = view.vmd.menuItem if( !menuNode ){ if( hash ) menuNode = view.vmd.menuNode = menu.shadowRoot.$( "tr[data-hash='" + hash + "']" ) if(view.vmd.menuNode)view.vmd.menuListener = menu } if( !menuNode ){ if( menuItem && !( menuItem instanceof HTMLElement )){ menu.addRecord( menuItem ) //view.vmd.menuItem = menu.vmd.lastAddedItem view.vmd.menuNode = menu.vmd.lastAddedItem view.vmd.menuListener = menu }} if( view.vmd.menuNode ) view.vmd.menuNode.vmd.view = view }, selectItem:function(e){X.changeView({ e: e })}} },{ xtype:"carousel", cls:"wmPocket card", css:"flex: 0 0 300px;margin: 7px 7px 7px 0px;", ref:"wmPocket", itemName:"pocket" }], cls:"d-flex flex-row","css":"height:100%;min-height:100%", xtype:"container" }]}]}, default:{ tag:"div", cls:"fit", id:"_libraWm", ref:"wm", items:[{ xtype:"container", items:[{ items:[{ tag:'div', attr:{"data-collapsed":0}, cls:"fa famr sidebar-brand d-flex align-items-center justify-content-center", css:"font-weight: 900;flex: 0 0 250px;background-color:#35baf6;border-bottom:1px solid #32404e !important", items:[{ xtype:"a",attr:{"data-collapsed":0}, css:'color:#fff', href:"#home", ref:"homeLink", lang:'title' },{ xtype:'button', iconCls:'fa-bars', css:'color:#fff', handler:function(){ let _ref = Libra.data.reference, nav = _ref.nav, navUp = _ref.navUp, homeLink = _ref.homeLink // for(let i in [nav,navUp]) // debug('thisb',nav,navUp,navUp.dataset) function clps(e,d=null,f=null){ let a,b,c if( e.dataset.collapsed === '0' ){ a = d===null?"50px":d b = '1' c=1 }else{ a = f===null?"250px":f b = '0' c=0 } e.style.width = a e.style.flex = "0 0 "+a e.dataset.collapsed = b Libra.data.navCollapsed=c } clps(nav) clps(navUp) clps(homeLink,"0","181px") } // cls:"navbar-toggler", // type:"button", // attr:{"data-toggle":"collapse","data-target":"#navbarToggleExternalContent","aria-controls":"navbarToggleExternalContent","aria-expanded":"false","aria-label":"Toggle navigation"}, // items:[{tag:'span',cls:"navbar-toggler-icon"}] }] },{ cls:"bg-white topbar d-flex flex-row static-top justify-content-center", css:"width:100%;border-bottom:1px solid rgba(0,0,0,.125)!important;display:-webkit-flex;-webkit-align-items:center;display:flex;align-items:center", items:[ { html:'' }, { xtype:"container", css:"right:10px;position:absolute", layout:"row", items:[{ xtype:"button", iconCls:"fa-shopping-cart", bind:{hidden:"{!isEcommerce}"} },{ xtype:"menu", // text:'a', // items:[] storeName:'storeLangs', html:' <img src="'+Libra.data.path.fw+'/img/flag_2_'+Libra.config.user.lang+'.jpg" style="width:24px;position:absolute;margin-top:10px;margin-left:5px">   ', defaults:{css:"clear:both;display:inline-block"}, /*html:'<div style="background-image: url(\''+Libra.data.path.fw+'/img/flag_2_it.jpg\');">azdf</div>' bind:{text:"{langsSelected}"}, bind:{text:"{langsSelected}"}, items:Libra.data.langsItems tpl:"a", tplName:'lang' store:{data:Libra.data.langs} items:[{ xtype:"a", iconCls:"fa-key", hash:"#register" }]*/ },{ xtype:"menu", bind:{"text":"{user.name}"}, items:[{ xtype:"a", iconCls:"fa-sign-in", bind:{hidden:"{user.id}"}, hash:"#login", lang:'signIn' },{ xtype:"a", iconCls:"fa-sign-out", bind:{hidden:"{!user.id}"}, handler:"logout", lang:"logout" },{ xtype:"a", iconCls:"fa-key", hash:"#register", lang:'register' }] },{ xtype:"button", href:'https://www.libraonline.net', target:'_self', iconCls:"fa-balance-scale", bind:{hidden:"{isLibra}"} },{ xtype:"button", iconCls:"fa-retweet", bind:{"hidden":"{!isError}"}, ui:"danger", handler: function(){window.location.reload()} }] }] }], tag:"header", cls:"d-flex flex-row bg-white topbar", css:"height:4rem" },{ items:[{ cls:"navbar-nav bg-gradient-primary sidebar sidebar-dark accordion", css:"flex: 0 0 250px;background-color: #32404e;color: #adb3b8! important;width: 250px !important;height:100% !important;min-height: 100% !important;", attr:{"data-collapsed":0}, items:[{ xtype:"nav", ref:"wmMenuNavigation", storeName:"storeWmMenuNavigation" }], tag:"nav" },{ xtype:"carousel", cls:"wmMenuView card hView", css:"flex: 0 0 250px;margin: 7px 0px 7px 7px;", ref:"wmMenuView", hidden:true, itemName:"menuView", },{ xtype:"carousel", cls:"bg-white wmView carousel-inner hView", css:"margin: 7px;border: 1px solid rgba(0,0,0,.125)", ref:"wmView", storeName:"storeWmView", bind:{ eventEmitter:"{reference.wmMenuNavigation}", bindEvent:"{reference.wmMenuNavigation}" }, itemName:"view", events:{ add:function(e){ let menu = Libra.data.reference.wmMenuNavigation, view = e.detail.view, vmd = view.vmd, ds=view.dataset, hash = ds.hash, menuNode = view.vmd.menuNode, menuItem = view.vmd.menuItem if( !menuNode ){ if( hash ) menuNode = view.vmd.menuNode = menu.shadowRoot.$( "tr[data-hash='" + hash + "']" ) if(view.vmd.menuNode)view.vmd.menuListener = menu } if( !menuNode ){ if( menuItem && !( menuItem instanceof HTMLElement )){ menu.addRecord( menuItem ) //view.vmd.menuItem = menu.vmd.lastAddedItem view.vmd.menuNode = menu.vmd.lastAddedItem view.vmd.menuListener = menu }} if( view.vmd.menuNode ) view.vmd.menuNode.vmd.view = view }, selectItem:function(e){X.changeView({ e: e })}} },{ xtype:"carousel", cls:"wmPocket card", css:"flex: 0 0 300px;margin: 7px 7px 7px 0px;", ref:"wmPocket", itemName:"pocket" }], cls:"d-flex flex-row","css":"height:100%;min-height:100%", xtype:"container" }]}]}}, login:{ cls:"card w-100 h-100 justify-content-center", items:[{ tag:"div", cls:"card card-container col-5 align-self-center", items:[ { html:" <br> " }, { tag:"div", cls:"d-flex justify-content-center align-self-center align-items-center", css:"font-size: 64px;background-color:#d6d6d6;width:100px;height:100px;border-radius:50%", items:[{ cls:"fa fa-user" }] }, { html:" " }, { html:"","tag":"p","cls":"profile-name-card","id":"profile-name" }, { tag:"form", cls:"form-signin", items:[{ tag:"span", cls:"reauth-email", id:"reauth-email" },{ tag:"input", cls:"form-control", id:"inputEmail", name:"login", attr:{ type:"text",placeholder:"Email address", required:1, autofocus:1 } }, { html:" "}, { tag:"input", cls:"form-control", id:"inputPassword", name:"password", attr:{ type:"password", placeholder:"Password", required:1 }}, { html:" "}, { tag:"div", id:"remember", class:"checkbox", items:[{ tag:"label", text:"Remember me ", items:[{ tag:"input", name:"remember", value :1, attr:{ type:"checkbox" }}] }]}, { html:" " }, { tag:"button", cls:"btn btn-lg btn-primary btn-block btn-signin", attr:{ type:"submit" }, text:"Sign in", events:{ render:function(){ this.onclick = () => { let form = this.up( 'form' ) form.addEventListener( 'submit', function(event){ event.preventDefault() let inputs = this.querySelectorAll( 'input' ), data = {} inputs.forEach( input => data[ input.name ] = input.value ) Libra.send( data,{ url:Libra.data.path.virtual + 'lib/server/login.php', fn:function(arg){if( arg.data && arg.data[ 0 ] ) Libra.viewController.logged( arg.data[ 0 ])}}) })}}}}]}, { html:" " }, { tag:"a", cls:"forgot-password", href:"#passwordreset", text:"Forgot the password" } ]}]}}, store:{ storeLangs:{ name:"data.store.storeLangs", modelName:"tree", data:[]}, storeWmView:{ name:"data.store.storeWmView", modelName:"object", data:[]}, storeWmMenuNavigation:{ modelName:"tree", name:"data.store.storeWmMenuNavigation", data:[{ iconCls:"fab fa-home", hash:"home", text:"home", viewName:"home" }]}}, model:{ tree:{ fields:[ "text" ]}, object:{ dinamic:true, fields:[ "property","value","configurable","enumerable","writable" ], storeClass:"libraStoreObject" }, modelDefault:{ fields:[ "text" ]}}}, X:{ setView: function(viewArg=null,arg=null){ /*viewArg: null string - from data.view object - viewCfg*/ let ref = Libra.data.reference, wmView = ref.wmView, view, //DOM - view viewName, //for cache of view TODO bene con hash viewCfg={}, //config view da creare hash, //hastag tgt = wmView, //target to add view menuNode, //linked node of menu if view is created after click menuListener, //parent of node e, //event det, //detail of event rec, //record of tree node fn = 'add', //function to add view of addRecord tabTitle, //title of tab for tabbed view tabbed, //tabbed config viewTabbed, //vabbed view to add internal view viewCfgTabbed //tabbed view config ,parse //parse di hash //,hashArr //debug('setView:1:',viewArg,arg) if( arg ){ if( arg.hash ) viewCfg.hash = arg.hash tgt = arg.target || tgt e = arg.e if( e ){ det = e.detail menuNode = det.menuItem || det.viewMenuLinkItem || det.viewMenuStoreItem if( menuNode ){ menuListener = e.target rec = menuNode.record view = menuNode.vmd.view if( !view && rec ){ if( rec.hash && !viewCfg.hash ) viewCfg.hash = rec.hash tabTitle = rec.text || rec.lang if( rec.view ) viewCfg = Libra.merge( rec.view, viewCfg ) else{ if( !rec.hash && !rec.path && !rec.view && !rec.viewName ) fn = 'addRecord' viewCfg = rec if( rec.viewName )viewName = rec.viewName } } } } } //debug('setView:2:',viewArg,viewCfg,view,rec) if( rec && Libra.Utils.analizeNode( rec )) return 1 if( !view ){ //not exist chached in menu if( viewArg ){ if( typeof viewArg === 'string' ){ viewCfg.hash = viewArg //arriva come hash if(Libra.data.xtype[viewArg])viewCfg.xtype=viewCfg } else viewCfg = viewArg } if( viewCfg.hash && !viewCfg.path ) viewCfg.path = viewCfg.hash //debug('setView:3:',viewArg,viewCfg,view) if( viewCfg.path && !viewCfg._pathParsed ){ parse = Libra.Path.parse( viewCfg ) //TODO cach rec se esiste e salvare parsato path //debug('setView:4:',parse) viewName = parse.viewName view = parse.view viewCfg = parse.viewCfg hash = parse.hash if( parse.tabbed ){ tabbed = parse.tabbed viewTabbed = tabbed.view }}} //debug('setView:5: view:',view,'viewCfg:',viewCfg ) if( !view ){ if( !viewCfg ) viewCfg = Libra.Template.use({ name:'viewNotFound', scope:{ viewName: viewName }}) }else{ if( view.dataset.tabbed ){ viewTabbed = view view = viewTabbed.vmd.itemSelected }else if( view.parentNode.dataset.tabbed ) viewTabbed = view.parentNode } //tabbed control if( tabbed || viewTabbed ){ //viewCfg = viewCfg || {} viewCfg.tabTitle = tabTitle if( viewTabbed ) tgt = viewTabbed.parentNode.selectItem( viewTabbed ) else{ hash = hash || viewCfg.xtype viewCfgTabbed = Libra.merge({ xtype:'tab', select:1, tabbed: viewCfg.xtype, _isTabbed:1, //? viewModel:{ data:{}}, events:{ selectItem:function( e ){X.changeView({ e: e })}} }, tabbed.config ) viewCfgTabbed.viewModel.data.menuItem = tabbed.menu//? tgt = tabbed.view = wmView.add( viewCfgTabbed ) } if( !view && viewCfg.id ) view = view||tgt.$( '#' + viewCfg.id ) // debug('---ctl id:',viewCfg,viewCfg.id,tgt,tgt.$( '#' + viewCfg.id )) } //view is not exist. Prepare view config - viewCfg if( !view ){ viewCfg = Libra.merge( viewCfg, { select:1, vmd:{}}) if( hash && !viewCfg.hash ) viewCfg.hash = hash if( fn !== 'add' ){ rec.view = viewCfg viewCfg = rec } //create view view = tgt[ fn ]( viewCfg ) view.vmd = view.vmd || {} if( viewName ) Libra.data.view[ viewName ] = view }else view.parentNode.selectItem( view ) if( menuNode && !view.vmd.menuNode ){ menuNode.vmd.view = view view.vmd.menuNode = view.vmd.menuNode || menuNode view.vmd.menuListener = view.vmd.menuListener || menuListener } // if( viewTabbed ) debug('setview end:',' - viewTabbed:',viewTabbed,' - viewTabbed.vmd:',viewTabbed.vmd) // debug('setview end:',' - view:',view,' - view.vmd:',view.vmd,' - menuNode:',menuNode,menuNode?' - menuNode.vmd:':'',menuNode?menuNode.vmd:'') return view }, changeView:function(arg){ /* let ref = Libra.data.reference, wmMenuView = ref.wmMenuView, wmPocket = ref.wmPocket, wmMenuViewBindEvent=ref.wmView, tgt = arg.target, view = arg.view, hash = view.dataset.hash, viewModel = view.viewModel, vmd, menuVisible=0, pocketVisible=0, menuItems=[], isBindEvent = 0*/ let e = arg.e, ref = Libra.data.reference, menu = ref.wmMenuNavigation, wmMenuView = ref.wmMenuView, wmView = ref.wmView, wmPocket = ref.wmPocket, view, tgt, menuItem, pocket, hash, vmd, menuItems = [], menuVisible = 0, pocketVisible = 0, i if(e){ view = e.detail.view || e.detail.tab tgt = e.target } //debug('changeView',arg,view) pocket = view.vmd.pocket menuItem = view.vmd.menuNode hash = view.dataset.hash vmd = view.vmd if( menuItem && !menuItem.dataset.selected ) view.vmd.menuListener.selectItem( menuItem, true ) if( pocket ){pocketVisible=1; wmPocket.selectItem( pocket, true )} if( hash )Libra.setHash( hash, true ) if( vmd.viewMenu ){ menuVisible = 1 wmMenuView.selectItem( vmd.viewMenu ) if( !view.wmMenuViewSilent ) for( i in vmd.viewMenu.vmd.items ) vmd.viewMenu.vmd.items[ i ].deselectItem() }else{ switch( view.tagName ){ case 'LIBRA-FORM': let prop, wmMenuViewLinkData = [], push, store, form = view, vmd = view.vmd, editing = view.dataset.hasOwnProperty('editing'), storeName = view.dataset.storeName if( editing && vmd.relation ){ wmMenuViewLinkData = [] for( prop in vmd.relation ){ let rel = vmd.relation[ prop ] for( i in rel.storeName ){ store = Libra.getStore( rel.storeName[ i ]) switch(rel.type){ case 'manytoone': wmMenuViewLinkData.push({ iconCls:'fa-plus', text:'add ' + store.text, view:{ xtype:'form', editing:1, storeName:rel.storeName[ i ], value:{}}}) break case 'onetomany': case 'onetoone': if( vmd.recordId ){ push = { iconCls:'fa-plus', text:'add ' + store.text, view:{ xtype:'form', editing:1, storeName:rel.storeName[ i ], value:{}}} push.view.value[ prop ] = vmd.recordId wmMenuViewLinkData.push( push ) push = { iconCls:'fa-table', text:store.text + 's', view:{ xtype:'table', editing:1, storeName:rel.storeName[ i ]}} if( vmd.record ) push.view.viewModel = { data:{ storeFilter:[{ property:prop, value:vmd.record[ Libra.data.eav.id ]}]}} wmMenuViewLinkData.push( push )} break }} //if( rel.storeName ) //else{ //push={ text:prop, view:{ xtype:'table', editing:1}} //if( rel.modelName ) push.view.modelName = rel.modelName //wmMenuViewLinkData.push( push ) //} }} if( wmMenuViewLinkData.length ) vmd.wmMenuViewLink = wmMenuViewLinkData break } if( vmd.wmMenuViewLink || vmd.wmMenuViewStore ){ menuVisible = 1 vmd.viewMenu = wmMenuView.add({ xtype:'container', id:'menu-' + view.id, select:1, items: menuItems }) /* if(vmd.wmMenuViewBindEvent){ isBindEvent = 1 wmMenuViewBindEvent = ref[ vmd.wmMenuViewBindEvent ]}*/ if( vmd.wmMenuViewLink ) vmd.viewMenu.vmd.viewMenuLink = vmd.viewMenu.add({ xtype:'tree', itemName:'viewMenuLinkItem', eventDetail: view.vmd.wmMenuViewEventTarget ? { target: ref[ view.vmd.wmMenuViewEventTarget ]} : {}, events:{ selectItem:function( e ){let arg = this.eventDetail || {}; arg.e = e; X.setView( null, arg )}}, /*viewModel:{data:{bindEventList:['selectItem'],bindEvent:wmMenuViewBindEvent}},*/ store:{ data:vmd.wmMenuViewLink} }) if( vmd.wmMenuViewStore ){ vmd.viewMenu.vmd.viewMenuStore = vmd.viewMenu.add({ xtype:'tree', itemName:'viewMenuStoreItem', cls:'overflow-auto', eventDetail: view.vmd.wmMenuViewEventTarget ? { target: ref[ view.vmd.wmMenuViewEventTarget ]} : {}, events: view.vmd.wmMenuViewEvents? view.vmd.wmMenuViewEvents:{ selectItem: function( e ){ let arg = this.eventDetail || {}; arg.e = e; X.setView( null, arg )}}, /*viewModel:{data:{bindEventList:['selectItem'],bindEvent:wmMenuViewBindEvent//wmMenuViewBindEvent}},*/ storeName:vmd.wmMenuViewStore }) //if(isBindEvent)wmMenuViewBindEvent.viewModel.data.bindEvent = vmd.viewMenu.vmd.store }}} wmMenuView.hidden = !menuVisible wmPocket.hidden = !pocketVisible /*let wmPocket = ref.wmPocket, wmMenuViewBindEvent=ref.wmView, tgt = arg.target, view = arg.view.dataset.tabbed&&arg.view.vmd.itemSelected?arg.view.vmd.itemSelected:arg.view, vmd = view.viewModel.data, hash = view.dataset.hash, menuVisible=0, pocketVisible=0, menuItems=[], isBindEvent = 0 if( !tgt.wmMenuViewSilent ){ //pocket if(view.vmd&&view.vmd.pocket){ pocketVisible=1 wmPocket.selectItem(vmd.pocket)} //menu} if(!tgt.wmMenuViewSilent)wmMenuView.hidden=!menuVisible wmPocket.hidden=!pocketVisible*/ /*if(tgt.wmMenuViewSilent){ //control select in menu if( view.viewModel.data.viewMenuFormenuItem) view.viewModel.data.viewMenuFormenuItem.selectItem(view.viewModel.data.menuItem,true)}*/ //pocket //TODO control if pocket /*wmPocket.delAll() if( !tgt.wmMenuViewSilent ) X.setMenuView( view ) if(view.vmd&&view.vmd.pocketPreview){ debug('pck',view.vmd,view.vmd.pocketPreview,view.vmd.pocketPreview.vmd.preview) wmPocket.add(view.vmd.pocketPreview.vmd.preview)*/ },"setViewByHash":function( hash ){ /*let ref = Libra.data.reference, menuViewItem = ref.wmMenuNavigation.shadowRoot.$( "td[hash='" + hash + "']" ) if( menuViewItem ){ menuViewItem = menuViewItem.parentNode ref.wmMenuNavigation.selectItem( menuViewItem ) //if(menuViewItem.viewModel.data.) }else*/ X.setView(null,{hash:hash}) }}},'window'); Libra.mergeConfig(window,{ "Libra":{ "data":{ "group":{"s_0":{"lang":"everyone"}}, // "x":{"wm":"default"}, "libraEditorCode":{"theme":"ambiance"}, "xtype":{"editorcode":{"tabbed":{"menu":{"text":"codes"},"config":{"adding":1,"defaults":{"xtype":"editorcode","closing":1}}}},"terminal":[],"oc":[]} } }, "debug":function(){console.log.apply( this, arguments )}, "class":{ "libraCodearea":{"extends":"HTMLTextAreaElement","customElementsDefine":"libra-codearea","requires":{"mod":["codemirror"]}},"libraCode":{"extends":"libraContainer","customElementsDefine":"libra-code","initConnect":function(){ let code = this.value||this.innerHTML this.dataset.layout = 'row' this.innerHTML = '' this.viewModel.data.codearea = this.add({ xtype: "codearea", value: code, cls:'w-50' }) this.viewModel.data.pocketPreview = this.add({ xtype: "pocket", type:'preview', cls:'w-50 border indent' }) }}}},'window'); //Libra.mergeConfig(window,)