@easydata/crud 1.4.20 → 1.4.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/css/ed-view.css +104 -0
- package/dist/easydata.crud.cjs.js +1520 -21
- package/dist/easydata.crud.esm.js +1507 -0
- package/package.json +8 -8
- package/dist/easydata.crud.cjs.js.map +0 -1
- package/dist/easydata.crud.es.js +0 -22
- package/dist/easydata.crud.es.js.map +0 -1
|
@@ -1,22 +1,1521 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
1
|
+
|
|
2
|
+
/*
|
|
3
|
+
* EasyData.JS CRUD v1.4.21
|
|
4
|
+
* Copyright 2020-2024 Korzh.com
|
|
4
5
|
* Licensed under MIT
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
!*/var t,e;!function(t){t[t.Unknown=0]="Unknown",t[t.String=1]="String",t[t.Byte=2]="Byte",t[t.Word=3]="Word",t[t.Int32=4]="Int32",t[t.Int64=5]="Int64",t[t.Bool=6]="Bool",t[t.Float=7]="Float",t[t.Currency=8]="Currency",t[t.BCD=9]="BCD",t[t.Date=10]="Date",t[t.Time=11]="Time",t[t.DateTime=12]="DateTime",t[t.Autoinc=13]="Autoinc",t[t.Memo=14]="Memo",t[t.Blob=15]="Blob",t[t.FixedChar=16]="FixedChar",t[t.Guid=17]="Guid",t[t.Geometry=18]="Geometry",t[t.Geography=19]="Geography"}(t||(t={})),function(t){t[t.Data=0]="Data",t[t.Virtual=1]="Virtual",t[t.Lookup=2]="Lookup"}(e||(e={}));const i="Unknown",s="EDIT",n="DATETIME",o="LIST",a="FILE";var r,l,d,h,c;!function(t){t.Trace="TRACE",t.Options="OPTIONS",t.Get="GET",t.Put="PUT",t.Post="POST",t.Delete="DELETE"}(r||(r={}));let u=class{constructor(t,e){this.xhr=t,this.method=e.method,this.url=e.url,this.headers=e.headers,this.queryParams=e.queryParams,this.data=e.data}setHeader(t,e){this.headers[t]=e}setQueryParam(t,e){this.queryParams[t]=e}getXMLHttpRequest(){return this.xhr}getResponseHeaders(){if(this.xhr.readyState==this.xhr.HEADERS_RECEIVED){const t=this.xhr.getAllResponseHeaders().trim().split(/[\r\n]+/),e={};for(const i of t){const t=i.split(": "),s=t.shift(),n=t.join(": ");e[s]=n}return e}return{}}open(){if(this.xhr.readyState!==this.xhr.UNSENT)return;let t=this.url;this.queryParams&&Object.keys(this.queryParams).length>0&&(t+=encodeURI("?"+Object.keys(this.queryParams).map((t=>t+"="+this.queryParams[t])).join("&"))),this.xhr.open(this.method,t,!0),this.xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");for(const t in this.headers)this.xhr.setRequestHeader(t,this.headers[t])}abort(){this.xhr.abort()}};!function(e){e.getAllDataTypes=function(){return Object.values(t).filter((t=>"number"==typeof t))},e.getDateDataTypes=function(){return[t.Time,t.Date,t.DateTime]},e.getStringDataTypes=function(){return[t.String,t.Memo,t.FixedChar]};const i=[t.Byte,t.Word,t.Int32,t.Int64,t.Float,t.Currency,t.Autoinc];e.getNumericDataTypes=function(){return i};const s=[t.Byte,t.Word,t.Int32,t.Int64,t.Autoinc];function n(t,e,i){e||(e={});for(let s of i)if(s)for(let i in s)if(s.hasOwnProperty(i)){let a=s[i];null!==a&&"object"==typeof a?t.has(a)?e[i]=t.get(a):Array.isArray(a)?(e[i]=o(a),t.set(a,e[i])):(void 0!==e[i]&&null!=e[i]||(e[i]=Object.create(Object.getPrototypeOf(a))),t.set(a,e[i]),n(t,e[i],[a])):e[i]=a}return e}function o(t){let e=[];for(let i of t)e.push(i);return e}e.assign=function(t,...e){for(let i=0;i<e.length;i++){let s=e[i];if(s)for(let e in s)s.hasOwnProperty(e)&&(t[e]=s[e])}return t},e.assignDeep=function(t,...e){return n(new WeakMap,t,e)},e.getIfDefined=function(t,e){return void 0!==t?t:e},e.IsDefinedAndNotNull=function(t){return null!=t},e.copyArrayTo=function(t,e){const i=t.length,s=e.length;for(let n=0;n<i&&n<s;n++)e[n]=t[n]},e.createArrayFrom=o,e.findItemById=function(t,e){for(var i=t.length,s=0;s<i;s++)if(t[s].id===e)return t[s];return null},e.findItemIndexById=function(t,e){for(var i=t.length,s=0;s<i;s++)if(t[s].id===e)return s;return-1},e.indexOfArrayItem=function(t,e){if(t.indexOf)return t.indexOf(e);{let i=t.length;for(let s=0;s<i;s++)if(e==t[s])return s;return-1}},e.moveArrayItem=function(t,e,i){if(e>=t.length)throw"Index out of bounds: "+e;i>=t.length&&(i=t.length-1);let s=t.splice(e,1)[0];t.splice(i,0,s)},e.removeArrayItem=function(t,e){let i=t.indexOf(e);if(-1!=i)return t.splice(i,1)[0]},e.insertArrayItem=function(t,e,i){t.splice(e,0,i)},e.fillArray=function(t,e,i=0,s){let n=t.length>>>0;var o=i>>0,a=o<0?Math.max(n+o,0):Math.min(o,n),r=void 0===s?n:s>>0;let l=r<0?Math.max(n+r,0):Math.min(r,n);for(;a<l;)t[a]=e,a++;return t},e.shiftToFitWindow=function(t,e){let i=document.getElementsByTagName("body")[0],s=window.innerWidth||document.documentElement.clientWidth||i.clientWidth;var n=t+e;let o=0;return n>s&&(o=s-n-10,t+o<0&&(o=10-t)),o},e.isObject=function(t){return null!==t&&("function"==typeof t||"object"==typeof t)},e.isNumericType=function(t){return i.indexOf(t)>=0},e.isIntType=function(t){return s.indexOf(t)>=0},e.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},e.areCompatibleDataTypes=function(e,i){return void 0===e||void 0===i||e==t.Unknown||i==t.Unknown||e==i||e==t.Date&&i==t.DateTime||e==t.DateTime&&i==t.Date},e.isPropSet=function(t,e){return t[e]||t[e.toLowerCase()]||t[e.toUpperCase()]};const a="0123456789abcdefghijklmnopqrstuvwxyz";function r(t,e){const i=t.length;if(i>e){let s=i/e,n="";n+=t[0];let o,a=s;for(let e=1;e<i;e++)o=t[e],e+1>a&&(n+=o,a+=s);return n}return t}function l(t,e){return Math.floor(Math.random()*(e-t))+t}function d(t){const e=parseInt(t);if(isNaN(e))throw`"${t}" is not a valid number`;return e}e.generateId=function(t){t||(t="easy");let e=t.length>4?function(t,e){let i=t.split("-"),s=1,n=4;i.length<4&&(s=4/i.length,n=i.length);let o="";for(let t=0;t<n;t++)o+=r(i[t],s);return o}(t):t;e&&e.length>0&&(e+="-");var i=a[l(0,36)]+a[l(0,36)]+a[l(0,36)],s=l(0,1e4);return e+i+function(t,e=36){var i="",s=t;do{i=a[s%e]+i,s=Math.floor(s/=e)}while(s>0);return i}(621355968e9+1e4*(new Date).getTime()-0x8d60e562e627800-s)},e.strToDateTime=function(t,e){if(!t||0==t.length)return new Date;const i=t.replace(/[^a-zA-Z0-9_]/g,"-"),s=e.replace(/[^a-zA-Z0-9_]/g,"-").split("-"),n=i.split("-"),o=s.indexOf("MM"),a=s.indexOf("dd"),r=s.indexOf("yyyy"),l=s.indexOf("HH"),h=s.indexOf("mm"),c=s.indexOf("ss"),u=new Date;try{const t=r>-1&&r<n.length?d(n[r]):u.getFullYear(),e=o>-1&&o<n.length?d(n[o])-1:u.getMonth()-1;if(e>11)throw"";const i=a>-1&&a<n.length?d(n[a]):u.getDate();if(i>function(t,e){return new Date(e,t+1,0).getDate()}(e,t))throw"";const s=l>-1&&l<n.length?d(n[l]):0;if(s>23)throw"";const p=h>-1&&h<n.length?d(n[h]):0;if(p>59)throw"";const g=c>-1&&c<n.length?d(n[c]):0;if(g>59)throw"";return new Date(t,e,i,s,p,g)}catch(e){throw`${t} is not a valid date.`}},e.strToTime=function(t){const e=t.split(":");try{const t=e.length>0?d(e[0]):0;if(t>23)throw"";const i=e.length>1?d(e[1]):0;if(i>59)throw"";const s=e.length>1?d(e[1]):0;if(s>59)throw"";return new Date(0,0,0,t,i,s)}catch(e){throw`${t} is not a valid time.`}}}(l||(l={}));class p{constructor(t,e){this.request=t,this.promise=e}getPromise(){return this.promise}getRequest(){return this.request}then(t,e){return this.promise.then(t,e)}catch(t){return this.promise.catch(t)}finally(t){return this.promise.finally(t)}}class g extends Error{constructor(t,e){super(e),this.status=t}}class m{get responseBody(){return this._responseBody}constructor(){this.defaultHeaders={},this.customPayload=void 0}get(t,e){return this.send(r.Get,t,null,e)}post(t,e,i){return this.send(r.Post,t,e,i)}put(t,e,i){return this.send(r.Put,t,e,i)}delete(t,e,i){return this.send(r.Delete,t,e,i)}send(t,e,i,s){const n=(s=s||{}).dataType||"json",o=s.contentType||"form-data"!==n?"application/json":null;i&&"form-data"!=n&&this.customPayload&&(i.data=l.assignDeep(i.data||{},this.customPayload));const a=new("onload"in new XMLHttpRequest?XMLHttpRequest:window.XDomainRequest),r={method:t,url:e,headers:Object.assign(Object.assign({},this.defaultHeaders),s.headers||{}),queryParams:s.queryParams||{},data:i};o&&(r.headers["Content-Type"]=o);const d=new u(a,r);this.beforeEachRequest&&(console.warn("HttpClient: 'beforeEachRequest' is deprecated and will be removed in future updates.\n Use 'onRequest' instead"),this.beforeEachRequest(d)),this.onRequest&&this.onRequest(d);const h=d.data&&"string"!=typeof d.data&&"json"==n?JSON.stringify(d.data):d.data;return d.open(),new p(d,new Promise(((t,i)=>{s.responseType&&(a.responseType=s.responseType),a.onerror=t=>{i(new g(a.status,a.responseText))},a.onreadystatechange=()=>{if(4!=a.readyState)return;const s=a.getResponseHeader("Content-Type")||"",n=a.status;if(0===n)i(new g(n,"Network error or the request was aborted"));else if(n>=200&&n<400){const e="arraybuffer"===a.responseType||"blob"===a.responseType?a.response:0==s.indexOf("application/json")?JSON.parse(a.responseText):a.responseText;this._responseBody=e,this.onResponse&&this.onResponse(a),t(e)}else("arraybuffer"===a.responseType||"blob"===a.responseType?m.decodeArrayBuffer(a.response):Promise.resolve(a.responseText)).then((t=>{const o=0==s.indexOf("application/json")?JSON.parse(t):t;this._responseBody=o;const a=o.message||(404==n?`No such endpoint: ${e}`:o);i(new g(n,a))}))},a.send(h)})))}static decodeArrayBuffer(t){var e=new FileReader;return new Promise((i=>{e.onloadend=function(){e.readyState==FileReader.DONE&&i(e.result)},e.readAsText(new Blob([t]))}))}}!function(e){let i,s={shortDateFormat:"MM/dd/yyyy",longDateFormat:"dd MMM, yyyy",editDateFormat:"MM/dd/yyyy",shortTimeFormat:"HH:mm",editTimeFormat:"HH:mm",longTimeFormat:"HH:mm:ss",shortMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],longMonthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],shortWeekDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],longWeekDayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],decimalSeparator:".",currency:"USD"},n={localeId:"en-US",englishName:"English",displayName:"English",texts:{ButtonOK:"OK",ButtonCancel:"Cancel",Yes:"Yes",No:"No",True:"True",False:"False"},settings:s},o={"en-US":n};const a=[];function r(t){for(const e of a)e(t)}function d(){return i.localeId}function h(t){const e=o[t];e?l.assignDeep(i,e):(i.englishName=t,i.displayName=t,i.texts=l.assignDeep({},n.texts)),i.localeId=t}function c(){return i.settings}function u(t){i.settings||(i.settings=l.assignDeep({},s)),i.settings=l.assignDeep(i.settings,t)}function p(t,e){r(e);let s=i;t&&(e.localeId||(e.localeId=t),s=o[t],s||(s=l.assignDeep({},n),o[t]=s)),l.assignDeep(s,e)}e.addMapper=function(t){a.push(t)},e.getLocales=function(){let t=[];for(let e in o)t.push({locale:e,englishName:o[e].englishName,displayName:o[e].displayName});return t.sort(((t,e)=>t.englishName>e.englishName?1:t.englishName===e.englishName?0:-1))},e.getCurrentLocale=d,e.setLocale=function(t){console.warn("This method is deprecated. Use setCurrentLocale instead"),h(t)},e.setCurrentLocale=h,e.getText=function(...t){let e=i.texts,s="";if(t&&t.length){const i=t.length;for(let n=0;n<i&&(s=e[t[n]],"object"==typeof s);n++)e=s}return s},e.getLocaleSettings=c,e.getOneLocaleSetting=function(t){return i.settings[t]},e.getShortMonthName=function(t){const e=c();if(t>0&&t<13)return e.shortMonthNames[t-1];throw"Wrong month number: "+t},e.getLongMonthName=function(t){const e=c();if(t>0&&t<13)return e.longMonthNames[t-1];throw"Wrong month number: "+t},e.getShortWeekDayName=function(t){const e=c();if(t>0&&t<8)return e.shortWeekDayNames.length>=t?e.shortWeekDayNames[t-1]:t.toString();throw"Wrong month number: "+t},e.getLongWeekDayName=function(t){const e=c();if(t>0&&t<8)return e.longWeekDayNames.length>=t?e.longWeekDayNames[t-1]:t.toString();throw"Wrong month number: "+t},e.updateLocaleSettings=u,e.updateLocaleTexts=function(t){"object"==typeof t?(r({localeId:i.localeId,texts:t}),l.assignDeep(i.texts,t)):console.error("Wrong parameter type in updateLocaleTexts function call.The first parameter (localeId) is not necessary. Use updateLocaleTexts(texts) instead")},e.updateDefaultTexts=function(t){for(let e in o){let i=o[e];i.texts=l.assignDeep({},t,i.texts)}i.texts=l.assignDeep({},t,i.texts)},e.updateLocaleInfo=p,e.addLocale=function(t,e){p(t,e)},e.resetLocales=function(){i||(i=l.assignDeep({},n),function(t){const e=new Date(2020,5,7,19,34,56,88),s=e.toLocaleDateString(t,{year:"numeric",month:"numeric",day:"numeric"}),n=e.toLocaleTimeString(t,{hour:"numeric",minute:"numeric",second:"numeric"});let o=s.replace("07","dd").replace("7","d").replace("06","MM").replace("6","M").replace("2020","yyyy").replace("20","yy"),a=n.replace("19","HH").replace("07","hh").replace("7","h").replace("34","mm").replace("56","ss").replace("PM","tt");i.settings||(i.settings={}),u({shortDateFormat:o,shortTimeFormat:a})}("object"==typeof navigator?navigator.language:void 0))};const g=/\[([^\]]+)]|y{2,4}|M{1,4}|d{1,2}|H{1,2}|h{1,2}|m{2}|s{2}|t{2}/g;function m(t,i){const s=t.getFullYear().toString(),n=t.getMonth()+1,o=t.getDate(),a=t.getHours(),r=t.getMinutes(),l=t.getSeconds(),d=a%12||12,h=a>11,c={yyyy:s,yy:s.substring(s.length-2),MMMM:e.getLongMonthName(n),MMM:e.getShortMonthName(n),MM:n<10?"0"+n:n.toString(),M:n.toString(),dd:o<10?"0"+o:o.toString(),d:o.toString(),HH:a<10?"0"+a:a.toString(),H:a.toString(),hh:d<10?"0"+d:d.toString(),h:d.toString(),tt:h?"PM":"AM",mm:r<10?"0"+r:r.toString(),ss:l<10?"0"+l:l.toString()};return i.replace(g,((t,e)=>e||c[t]))}function f(e){const i=c();let s;switch(e){case t.Date:s=i.shortDateFormat;break;case t.Time:s=i.shortTimeFormat;break;default:s=i.shortDateFormat+" "+i.shortTimeFormat}return s}function y(e){const i=c();let s;switch(e){case t.Date:s=i.longDateFormat;break;case t.Time:s=i.longTimeFormat;break;default:s=i.longDateFormat+" "+i.longTimeFormat}return s}e.dateTimeToStr=m,e.dateTimeToStrEx=function(e,i,s){return s?"d"==s?s=f(t.Date):"D"==s?s=y(t.Date):"f"==s?s=f(t.DateTime):"F"==s&&(s=y(t.DateTime)):s=f(i),m(e,s)},e.numberToStr=function(t,i,s){if(i&&i.length>0){const s=i.charAt(0).toUpperCase();if("S"===s)return function(t,i){if(!D[i]){const t=i.split("|").filter((t=>t.length>0)).map((t=>t.split("=")));if(D[i]={},t.length>0)if(t[0].length>1)for(const e of t)D[i][Number.parseInt(e[1])]=e[0];else t.forEach(((t,e)=>{D[i][e]=t[0]}))}const s=D[i];if(void 0!==s[t]){const i=s[t];return e.getText(i)||i}return t.toString()}(t,i.slice(1));if(["D","F","C"].indexOf(s)>=0){const e=d();return t.toLocaleString(e,function(t){const e=c(),i=t[0].toUpperCase(),s=t.length>1?Number.parseInt(t.slice(1)):"D"==i?1:2;switch(i){case"D":return{style:"decimal",useGrouping:!1,minimumIntegerDigits:s};case"C":return{style:"currency",currency:e.currency,minimumFractionDigits:s};default:return{style:"decimal",minimumFractionDigits:s,maximumFractionDigits:s}}}(i))}return function(t,e){let i=t.toString(),s="",n=i.length-1;for(let t=e.length-1;t>=0;t--){const o=e.charAt(t);"#"===o||"0"===o?n>=0?(s+=i.charAt(n),n--):"0"===o&&(s+=0):s+=o}return s.split("").reverse().join("")}(Math.trunc(t),i)}const n=c();return s=s||n.decimalSeparator,t.toString().replace(".",s)},e.booleanToStr=function(t,i){if(i&&i.length>0&&"S"===i.charAt(0).toUpperCase()){const s=i.slice(1).split("|");if(s.length>1){const i=s[t?1:0];return e.getText(i)||i}}return`${t}`};const D={}}(d||(d={}));class f{constructor(t){this.isEditable=!0,this.name="",this.caption="",this.description="",this.parent=t,this.attributes=new Array,this.subEntities=new Array}loadFromData(t,e){if(e){if(this.id=e.id,this.name=e.name,this.captionPlural=e.namePlur,this.caption=e.name,this.description=e.desc,void 0!==e.ied&&(this.isEditable=e.ied),this.subEntities=new Array,e.ents)for(let i=0;i<e.ents.length;i++){let s=t.createEntity(this);s.loadFromData(t,e.ents[i]),this.subEntities.push(s)}if(this.attributes=new Array,e.attrs)for(let i=0;i<e.attrs.length;i++){let s=t.createEntityAttr(this);s.loadFromData(t,e.attrs[i]),this.attributes.push(s)}}}scan(t,e){let i={stop:!1},s=n=>{if(e&&e(n,i),n.attributes){let e=n.attributes.length;for(let s=0;s<e&&!i.stop;s++){let e=n.attributes[s];if(t&&t(e,i),i.stop)return}}if(n.subEntities){let t=n.subEntities.length;for(let e=0;e<t&&!i.stop;e++)s(n.subEntities[e])}};s(this)}getFirstPrimaryAttr(){return this.getPrimaryAttrs()[0]}getPrimaryAttrs(){return this.attributes.filter((t=>t.isPrimaryKey))}}class y{constructor(i){this.id="",this.caption="{Unrecognized attribute}",this.dataType=t.String,this.size=0,this.isPrimaryKey=!1,this.isForeignKey=!1,this.isNullable=!0,this.showOnView=!0,this.isEditable=!0,this.showOnCreate=!0,this.showOnEdit=!0,this.showInLookup=!1,this.lookupAttr="",this.expr="",this.entity=i,this.kind=e.Data}loadFromData(t,e){if(e){this.id=e.id,this.description=e.desc,this.caption=e.cptn,this.dataType=e.dtype,this.isPrimaryKey=e.ipk,this.isForeignKey=e.ifk,this.size=e.size,this.lookupAttr=e.lattr,this.lookupEntity=e.lent,this.dataAttr=e.dattr,this.lookupDataAttr=e.ldattr;const i=l.getDateDataTypes().indexOf(this.dataType);this.defaultValue=e.defVal&&i?new Date(e.defVal):e.defVal,this.isNullable=l.getIfDefined(e.nul,this.isNullable),this.isEditable=l.getIfDefined(e.ied,this.isEditable),this.showOnView=l.getIfDefined(e.ivis||e.sov,this.showOnView),this.showOnCreate=l.getIfDefined(e.soc,this.showOnCreate),this.showOnEdit=l.getIfDefined(e.soe,this.showOnEdit),this.showInLookup=l.getIfDefined(e.sil,this.showInLookup),this.kind=e.kind,this.displayFormat=e.dfmt,e.udata&&(this.userData=e.udata),e.edtr&&(this.defaultEditor=t.getEditorById(e.edtr)||t.createValueEditor())}}}class D{constructor(){this.id="",this.tag=i,this.resType=t.Unknown,this.defValue=""}loadFromData(t){t&&(this.id=t.id,this.tag=t.tag,this.defValue=t.defval,this.resType=t.rtype,this.accept=t.accept,this.multiline=t.multiline,t.subType&&(this.resType=t.subType),t.name&&(this.name=t.name),t.values&&(this.values=t.values))}getValueText(t){let e="";if(!this.values)return e;if(Array.isArray(t))for(let i of this.values)t.indexOf(i.id)>=0&&(e+=i.text+",");else for(let i of this.values)i.id===t&&(e+=i.text+",");return e&&(e=e.substring(0,e.length-1)),e}}class v{constructor(){this.mainEntity=null,this.id="__none",this.name="Empty model",this.rootEntity=this.createEntity(),this.displayFormats=new Map}getMainEntity(){return this.mainEntity}createEntity(t){return new f(t)}createEntityAttr(t){return new y(t)}createValueEditor(){return new D}loadFromJSON(t){let e=JSON.parse(t);this.loadFromData(e)}loadFromData(e){if(this.id=e.id,this.name=e.name,this.version=e.vers,this.editors=new Array,e.editors)for(let t=0;t<e.editors.length;t++){let i=this.createValueEditor();i.loadFromData(e.editors[t]),this.editors.push(i)}if(this.rootEntity.loadFromData(this,e.entroot),this.displayFormats=new Map,e.displayFormats)for(const i in e.displayFormats){const s=t[i],n=e.displayFormats[i]||new Array;this.displayFormats.set(s,n)}}getDisplayFormats(){return this.displayFormats}getDisplayFormatsForType(t){return this.displayFormats.has(t)?this.displayFormats.get(t):[]}getDefaultFormat(t){return this.displayFormats.has(t)?this.displayFormats.get(t).filter((t=>t.isdef))[0]:null}setData(t){"string"==typeof t?this.loadFromJSON(t):this.loadFromData(t)}isEmpty(){return 0===this.rootEntity.subEntities.length&&0===this.rootEntity.attributes.length}getId(){return this.id}getName(){return this.name}getRootEntity(){return this.rootEntity}getEditorById(t){for(let e of this.editors)if(e.id===t)return e;return null}getAttributeById(t){return this.getEntityAttrById(this.getRootEntity(),t)||null}checkAttrProperty(t,e){let i=this.getAttributeById(t);if(i){if(void 0===i[e])throw"No such property: "+e;return!!i[e]||!!i.lookupAttr&&(t=i.lookupAttr,i=this.getAttributeById(t),i&&i[e])}return!1}getEntityAttrById(t,e){let i,s;if(t.attributes){let s=t.attributes.length;for(i=0;i<s;i++)if(t.attributes[i].id==e)return t.attributes[i]}if(t.subEntities){let n=t.subEntities.length;for(i=0;i<n;i++)if(s=this.getEntityAttrById(t.subEntities[i],e),s)return s}return null}listByEntityWithFilter(t,e){let i,s=new Array,n=null;if(t.subEntities){let o=t.subEntities.length;for(let a=0;a<o;a++)if(n=t.subEntities[a],!e||e(n,null)){i=d.getText("Entities",n.name),i||(i=n.caption);let t=l.assign(this.createEntity(),{id:n.name,text:i,items:[],isEntity:!0});t.items=this.listByEntityWithFilter(n,e),t.items.length>0&&s.push(t)}}let o=null;if(t.attributes){let n=t.attributes.length;for(let a=0;a<n;a++)if(o=t.attributes[a],!e||e(t,o)){i=d.getText("Attributes",o.id),i||(i=o.caption);let t=l.assign(this.createEntity(),{id:o.id,text:i,dataType:o.dataType});s.push(t)}}return s}listByEntity(t,e,i){e=e||{};let s,n=[],o=[],a=null;if(t.subEntities){let o=t.subEntities.length;for(let r=0;r<o;r++)if(a=t.subEntities[r],!i||i(a,null)){s=d.getText("Entities",a.name)||a.caption;let t=l.assign(this.createEntity(),{id:a.name,text:s,items:[],isEntity:!0,description:a.description}),o=l.assign({},e);o.includeRootData=!1,t.items=this.listByEntity(a,o,i),t.items.length>0&&n.push(t)}}let r=null;if(t.attributes){let e=t.attributes.length;for(let n=0;n<e;n++)r=t.attributes[n],i&&!i(t,r)||(s=d.getText("Attributes",r.id)||r.caption,o.push(l.assign(this.createEntityAttr(t),{id:r.id,text:s,dataType:r.dataType,lookupAttr:r.lookupAttr,description:r.description})))}let h,c=(t,e)=>t.text.toLowerCase()==e.text.toLowerCase()?0:t.text.toLowerCase()>e.text.toLowerCase()?1:-1;return e.sortEntities&&(n.sort(c),o.sort(c)),h=e.attrPlacement&&0!=e.attrPlacement?o.concat(n):n.concat(o),2==e.attrPlacement&&h.sort(c),e.includeRootData?(s=d.getText("Entities",t.name),s||(s=t.caption),{id:t.name,text:s,items:h}):h}clear(){this.rootEntity=this.createEntity(),this.editors=[],this.version=""}addDefaultValueEditors(){let e;e=this.addOrUpdateValueEditor("_DTE",s,t.String),e.defValue="",this.addOrUpdateValueEditor("_DPDE",n,t.DateTime),this.addOrUpdateValueEditor("_DPTE",n,t.DateTime)}addOrUpdateValueEditor(t,e,i){let s=l.findItemById(this.editors,t);return s||(s=this.createValueEditor(),s.id=t,this.editors.push(s)),s.tag=e,s.resType=i,s}getEntitiesTree(t,e){return this.listByEntity(this.getRootEntity(),t,e)}getEntitiesTreeWithFilter(t){return this.listByEntityWithFilter(this.getRootEntity(),t)}getFullEntityPathByAttr(t,e){return e=e||" ",this.getEntityPathByAttr(this.getRootEntity(),t,e,!0)}getEntityPathByAttr(t,e,i,s){if(!t)return"";i=i||" ";let n="";if(t.caption&&!s){n=d.getText("Entities",t.caption)||t.caption}if(t.attributes){let i=t.attributes.length;for(let s=0;s<i;s++)if(t.attributes[s].id==e)return n}if(t.subEntities){let s=t.subEntities.length;for(let o=0;o<s;o++){let s=t.subEntities[o],a=this.getEntityPathByAttr(s,e,i,!1);if(""!==a)return""!==n&&(a=n+i+a),a}}return""}getAttributeText(t,e){let i=d.getText("Attributes",t.id);if(i||(i=t.caption),!e)return i;let s="",n=this.getFullEntityPathByAttr(t.id," ");return n?(s=e.replace(new RegExp("{attr}","g"),i),s=s.replace(new RegExp("{entity}","g"),n)):s=i,s.trim()}runThroughEntities(t,e){this.getRootEntity().scan(t,e)}getFirstAttributeByFilter(t){let e=null;return this.runThroughEntities((function(i,s){t(i)&&(s.stop=!0,e=i)}),null),e}}!function(t){t[t.None=0]="None",t[t.Left=1]="Left",t[t.Center=2]="Center",t[t.Right=3]="Right"}(h||(h={}));class C{constructor(e){if(!e)throw Error("Options are required");if(!e.id)throw Error("Field Id is required");if(!e.label)throw Error("Label is required");this.id=e.id,this.type=l.getIfDefined(e.type,t.String),this.label=e.label,this.originAttrId=e.originAttrId,this.isAggr=e.isAggr||!1,this.displayFormat=e.dfmt,this.groupFooterColumnTemplate=e.gfct,this.style=e.style||{},this.description=e.description,this.calculatedWidth=0}}class w{constructor(){this.items=[],this.mapper={},this._dateColumnIdx=[]}get count(){return this.items.length}add(e){let i;i=e instanceof C?e:new C(e);const s=this.items.length;return this.items.push(i),this.mapper[i.id]=s,[t.Date,t.DateTime,t.Time].indexOf(i.type)>=0&&this._dateColumnIdx.push(s),s}updateDateColumnIdx(){this._dateColumnIdx=this.getItems().filter((e=>[t.Date,t.DateTime,t.Time].indexOf(e.type)>=0)).map(((t,e)=>e))}put(t,e){t>=0&&t<this.count&&(this.items[t]=e,this.updateDateColumnIdx())}move(t,e){let i=this.items.indexOf(t);i>=0&&i!=e&&(l.moveArrayItem(this.items,i,e),this.updateDateColumnIdx())}get(t){return t>=0&&t<this.count?this.items[t]:null}getIndex(t){return this.mapper[t]}getItems(){return this.items}getDateColumnIndexes(){return this._dateColumnIdx}removeAt(t){const e=this.get(t);this.items.splice(t,1);const i=this._dateColumnIdx.indexOf(t);i>=0&&this._dateColumnIdx.splice(i,1),delete this.mapper[e.id]}clear(){this.items=[],this._dateColumnIdx=[],this.mapper={}}}class T{constructor(t,e){this.columns=t,this.values=e}toArray(){return Array.from(this.values)}size(){return this.values.length}getValue(t){let e;if("string"==typeof t){if(e=this.columns.getIndex(t),void 0===e)throw new RangeError(`No column with id '${t}'`)}else e=t;if(e>=this.values.length)throw new RangeError("Out of range: "+e);return this.values[e]}setValue(t,e){let i;if("string"==typeof t){if(i=this.columns.getIndex(t),void 0===i)throw new RangeError(`No column with id '${t}'`)}else i=t;if(i>=this.values.length)throw new RangeError("Out of range: "+i);this.values[i]=e}}let b=class{constructor(t){if(this._chunkSize=1e3,this._elasticChunks=!1,this.cachedRows=[],this.total=0,this.loader=null,this.needTotal=!0,this.isInMemory=!1,t=t||{},this._chunkSize=t.chunkSize||this._chunkSize,this._elasticChunks=t.elasticChunks||this._elasticChunks,this.loader=t.loader,void 0!==t.inMemory&&(this.isInMemory=t.inMemory),this.isInMemory&&(this.needTotal=!1),this._columns=new w,this.onUpdate=t.onUpdate,t.columns)for(const e of t.columns)this._columns.add(e);if(t.rows)for(const e of t.rows){const t=this.createRow(e);this.addRow(t)}this.needTotal=!this._elasticChunks}get columns(){return this._columns}get chunkSize(){return this._chunkSize}set chunkSize(t){this._chunkSize=t,this.total=0,this.needTotal=!this.elasticChunks,this.cachedRows=[]}get elasticChunks(){return this._elasticChunks}set elasticChunks(t){this._elasticChunks=t,this.total=0,this.needTotal=!this.elasticChunks,this.cachedRows=[]}getRows(t){let e=0,i=this._chunkSize;t&&("page"in t?(e=t.pageSize*(t.page-1),i=t.pageSize):(e=t.offset,i=t.limit));let s=e+i;if(!this.needTotal&&!this.elasticChunks){if(e>=this.total)return Promise.resolve([]);s>this.total&&(s=this.total)}if(this.isInMemory&&s>this.cachedRows.length&&(s=this.cachedRows.length),s<=this.cachedRows.length)return Promise.resolve(this.cachedRows.slice(e,s));if(!this.loader)throw`Loader is not defined. Can't get the rows from ${e} to ${s}`;const n=this.needTotal;this.needTotal&&(this.needTotal=!1);let o=this.cachedRows.length,a=s-o;return a<this._chunkSize&&(a=this._chunkSize),this.loader.loadChunk({offset:o,limit:a,needTotal:n}).then((t=>(n&&(this.total=t.total),Array.prototype.push.apply(this.cachedRows,t.table.getCachedRows()),s>this.cachedRows.length&&(s=this.cachedRows.length),this.elasticChunks&&t.table.getCachedCount()<a&&(this.total=this.cachedRows.length),this.fireUpdated(),this.cachedRows.slice(e,s))))}getRow(t){return this.getRows({offset:t,limit:1}).then((t=>t.length>0?t[0]:null))}getTotal(){return this.total}setTotal(t){this.total=t,this.needTotal=!1}getCachedCount(){return this.cachedRows.length}clear(){this.columns.clear(),this.cachedRows=[],this.total=0,this.needTotal=!this._elasticChunks,this.fireUpdated()}createRow(t){const e=this._columns.getDateColumnIndexes(),i=new Array(this._columns.count),s=t instanceof T?e=>t.getValue(e):e=>t[e];return t&&this.columns.getItems().forEach((t=>{const n=s(t.id),o=this.columns.getIndex(t.id);i[o]=e.indexOf(o)>=0?this.mapDate(n,t.type):n})),new T(this._columns,i)}mapDate(e,i){if(e){let s=new Date(e);return isNaN(s.getTime())&&i==t.Time&&(s=l.strToTime(e)),s}return null}addRow(t){let e;if(Array.isArray(t)){let i=t;const s=this._columns.getDateColumnIndexes();if(s.length>0)for(const t of s)i[t]&&(i[t]=this.mapDate(i[t],this._columns.get(t).type));e=new T(this._columns,i)}else e=this.createRow(t);this.cachedRows.push(e);const i=this.getCachedCount();return i>this.total&&(this.total=i),e}getCachedRows(){return this.cachedRows}totalIsKnown(){return this.elasticChunks?this.getCachedCount()===this.total:!this.needTotal}fireUpdated(){this.onUpdate&&this.onUpdate(this)}};function x(t,e){let i=t;return null!=i&&i.length>0?("/"!=i.charAt(i.length-1)&&(i+="/"),i+=e):i=e,i}(c||(c={})).renderLiquidTemplate=function(t,e){let i=t;if(e)for(let t in e){const s=new RegExp("{{"+t+"}}","g");i=i.replace(s,e[t])}return i},d.resetLocales(),"function"!=typeof Object.values&&(Object.values=function(t){return Object.keys(t).map((e=>t[e]))}),"function"!=typeof Math.trunc&&(Math.trunc=function(t){return isNaN(t)?NaN:t>0?Math.floor(t):Math.ceil(t)});class E{constructor(t,e,i,s=!1){this.loader=t,this.sourceTable=e,this.sourceId=i,this.isLookup=s,this.filterValue="",this.justServerSide=!1}getValue(){return this.filterValue}apply(t){return this.filterValue=t,this.filterValue?this.applyCore():this.clear()}clear(){return this.filterValue="",Promise.resolve(this.sourceTable)}applyCore(){if(this.sourceTable.getTotal()!=this.sourceTable.getCachedCount()||this.justServerSide){const t=[{class:"__substring",value:this.filterValue}];return this.loader.loadChunk({offset:0,limit:this.sourceTable.chunkSize,needTotal:!0,filters:t,sourceId:this.sourceId,lookup:this.isLookup}).then((e=>{const i=new b({chunkSize:this.sourceTable.chunkSize,loader:{loadChunk:e=>this.loader.loadChunk(Object.assign(Object.assign({},e),{filters:t,sourceId:this.sourceId,lookup:this.isLookup}))}});for(const t of this.sourceTable.columns.getItems())i.columns.add(t);i.setTotal(e.total);for(const t of e.table.getCachedRows())i.addRow(t);return i}))}return this.applyInMemoryFilter()}applyInMemoryFilter(){return new Promise(((t,e)=>{const i=new b({chunkSize:this.sourceTable.chunkSize,inMemory:!0});for(const t of this.sourceTable.columns.getItems())i.columns.add(t);const s=this.filterValue.split("||").map((t=>t.trim().toLowerCase())),n=this.sourceTable.columns.getItems().filter((t=>l.isNumericType(t.type)||l.getStringDataTypes().indexOf(t.type)>=0)),o=t=>{for(const e of n){const i=t.getValue(e.id);if(i){const t=i.toString().toLowerCase();for(const e of s)if(t.indexOf(e)>=0)return!0}}return!1};for(const t of this.sourceTable.getCachedRows())o(t)&&i.addRow(t);i.setTotal(i.getCachedCount()),t(i)}))}}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
!*/var I,S,M,R,k,A,P,O;!function(t){t[t.Unknown=0]="Unknown",t[t.String=1]="String",t[t.Byte=2]="Byte",t[t.Word=3]="Word",t[t.Int32=4]="Int32",t[t.Int64=5]="Int64",t[t.Bool=6]="Bool",t[t.Float=7]="Float",t[t.Currency=8]="Currency",t[t.BCD=9]="BCD",t[t.Date=10]="Date",t[t.Time=11]="Time",t[t.DateTime=12]="DateTime",t[t.Autoinc=13]="Autoinc",t[t.Memo=14]="Memo",t[t.Blob=15]="Blob",t[t.FixedChar=16]="FixedChar",t[t.Guid=17]="Guid",t[t.Geometry=18]="Geometry",t[t.Geography=19]="Geography"}(I||(I={})),function(t){t[t.Data=0]="Data",t[t.Virtual=1]="Virtual",t[t.Lookup=2]="Lookup"}(S||(S={})),function(t){t.Trace="TRACE",t.Options="OPTIONS",t.Get="GET",t.Put="PUT",t.Post="POST",t.Delete="DELETE"}(M||(M={})),function(t){t.getAllDataTypes=function(){return Object.values(I).filter((t=>"number"==typeof t))},t.getDateDataTypes=function(){return[I.Time,I.Date,I.DateTime]},t.getStringDataTypes=function(){return[I.String,I.Memo,I.FixedChar]};const e=[I.Byte,I.Word,I.Int32,I.Int64,I.Float,I.Currency,I.Autoinc];t.getNumericDataTypes=function(){return e};const i=[I.Byte,I.Word,I.Int32,I.Int64,I.Autoinc];function s(t,e,i){e||(e={});for(let o of i)if(o)for(let i in o)if(o.hasOwnProperty(i)){let a=o[i];null!==a&&"object"==typeof a?t.has(a)?e[i]=t.get(a):Array.isArray(a)?(e[i]=n(a),t.set(a,e[i])):(void 0!==e[i]&&null!=e[i]||(e[i]=Object.create(Object.getPrototypeOf(a))),t.set(a,e[i]),s(t,e[i],[a])):e[i]=a}return e}function n(t){let e=[];for(let i of t)e.push(i);return e}t.assign=function(t,...e){for(let i=0;i<e.length;i++){let s=e[i];if(s)for(let e in s)s.hasOwnProperty(e)&&(t[e]=s[e])}return t},t.assignDeep=function(t,...e){return s(new WeakMap,t,e)},t.getIfDefined=function(t,e){return void 0!==t?t:e},t.IsDefinedAndNotNull=function(t){return null!=t},t.copyArrayTo=function(t,e){const i=t.length,s=e.length;for(let n=0;n<i&&n<s;n++)e[n]=t[n]},t.createArrayFrom=n,t.findItemById=function(t,e){for(var i=t.length,s=0;s<i;s++)if(t[s].id===e)return t[s];return null},t.findItemIndexById=function(t,e){for(var i=t.length,s=0;s<i;s++)if(t[s].id===e)return s;return-1},t.indexOfArrayItem=function(t,e){if(t.indexOf)return t.indexOf(e);{let i=t.length;for(let s=0;s<i;s++)if(e==t[s])return s;return-1}},t.moveArrayItem=function(t,e,i){if(e>=t.length)throw"Index out of bounds: "+e;i>=t.length&&(i=t.length-1);let s=t.splice(e,1)[0];t.splice(i,0,s)},t.removeArrayItem=function(t,e){let i=t.indexOf(e);if(-1!=i)return t.splice(i,1)[0]},t.insertArrayItem=function(t,e,i){t.splice(e,0,i)},t.fillArray=function(t,e,i=0,s){let n=t.length>>>0;var o=i>>0,a=o<0?Math.max(n+o,0):Math.min(o,n),r=void 0===s?n:s>>0;let l=r<0?Math.max(n+r,0):Math.min(r,n);for(;a<l;)t[a]=e,a++;return t},t.shiftToFitWindow=function(t,e){let i=document.getElementsByTagName("body")[0],s=window.innerWidth||document.documentElement.clientWidth||i.clientWidth;var n=t+e;let o=0;return n>s&&(o=s-n-10,t+o<0&&(o=10-t)),o},t.isObject=function(t){return null!==t&&("function"==typeof t||"object"==typeof t)},t.isNumericType=function(t){return e.indexOf(t)>=0},t.isIntType=function(t){return i.indexOf(t)>=0},t.isNumeric=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},t.areCompatibleDataTypes=function(t,e){return void 0===t||void 0===e||t==I.Unknown||e==I.Unknown||t==e||t==I.Date&&e==I.DateTime||t==I.DateTime&&e==I.Date},t.isPropSet=function(t,e){return t[e]||t[e.toLowerCase()]||t[e.toUpperCase()]};const o="0123456789abcdefghijklmnopqrstuvwxyz";function a(t,e){const i=t.length;if(i>e){let s=i/e,n="";n+=t[0];let o,a=s;for(let e=1;e<i;e++)o=t[e],e+1>a&&(n+=o,a+=s);return n}return t}function r(t,e){return Math.floor(Math.random()*(e-t))+t}function l(t){const e=parseInt(t);if(isNaN(e))throw`"${t}" is not a valid number`;return e}t.generateId=function(t){t||(t="easy");let e=t.length>4?function(t,e){let i=t.split("-"),s=1,n=4;i.length<4&&(s=4/i.length,n=i.length);let o="";for(let t=0;t<n;t++)o+=a(i[t],s);return o}(t):t;e&&e.length>0&&(e+="-");var i=o[r(0,36)]+o[r(0,36)]+o[r(0,36)],s=r(0,1e4);return e+i+function(t,e=36){var i="",s=t;do{i=o[s%e]+i,s=Math.floor(s/=e)}while(s>0);return i}(621355968e9+1e4*(new Date).getTime()-0x8d60e562e627800-s)},t.strToDateTime=function(t,e){if(!t||0==t.length)return new Date;const i=t.replace(/[^a-zA-Z0-9_]/g,"-"),s=e.replace(/[^a-zA-Z0-9_]/g,"-").split("-"),n=i.split("-"),o=s.indexOf("MM"),a=s.indexOf("dd"),r=s.indexOf("yyyy"),d=s.indexOf("HH"),h=s.indexOf("mm"),c=s.indexOf("ss"),u=new Date;try{const t=r>-1&&r<n.length?l(n[r]):u.getFullYear(),e=o>-1&&o<n.length?l(n[o])-1:u.getMonth()-1;if(e>11)throw"";const i=a>-1&&a<n.length?l(n[a]):u.getDate();if(i>function(t,e){return new Date(e,t+1,0).getDate()}(e,t))throw"";const s=d>-1&&d<n.length?l(n[d]):0;if(s>23)throw"";const p=h>-1&&h<n.length?l(n[h]):0;if(p>59)throw"";const g=c>-1&&c<n.length?l(n[c]):0;if(g>59)throw"";return new Date(t,e,i,s,p,g)}catch(e){throw`${t} is not a valid date.`}},t.strToTime=function(t){const e=t.split(":");try{const t=e.length>0?l(e[0]):0;if(t>23)throw"";const i=e.length>1?l(e[1]):0;if(i>59)throw"";const s=e.length>1?l(e[1]):0;if(s>59)throw"";return new Date(0,0,0,t,i,s)}catch(e){throw`${t} is not a valid time.`}}}(R||(R={})),function(t){let e,i={shortDateFormat:"MM/dd/yyyy",longDateFormat:"dd MMM, yyyy",editDateFormat:"MM/dd/yyyy",shortTimeFormat:"HH:mm",editTimeFormat:"HH:mm",longTimeFormat:"HH:mm:ss",shortMonthNames:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],longMonthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],shortWeekDayNames:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],longWeekDayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],decimalSeparator:".",currency:"USD"},s={localeId:"en-US",englishName:"English",displayName:"English",texts:{ButtonOK:"OK",ButtonCancel:"Cancel",Yes:"Yes",No:"No",True:"True",False:"False"},settings:i},n={"en-US":s};const o=[];function a(t){for(const e of o)e(t)}function r(){return e.localeId}function l(t){const i=n[t];i?R.assignDeep(e,i):(e.englishName=t,e.displayName=t,e.texts=R.assignDeep({},s.texts)),e.localeId=t}function d(){return e.settings}function h(t){e.settings||(e.settings=R.assignDeep({},i)),e.settings=R.assignDeep(e.settings,t)}function c(t,i){a(i);let o=e;t&&(i.localeId||(i.localeId=t),o=n[t],o||(o=R.assignDeep({},s),n[t]=o)),R.assignDeep(o,i)}t.addMapper=function(t){o.push(t)},t.getLocales=function(){let t=[];for(let e in n)t.push({locale:e,englishName:n[e].englishName,displayName:n[e].displayName});return t.sort(((t,e)=>t.englishName>e.englishName?1:t.englishName===e.englishName?0:-1))},t.getCurrentLocale=r,t.setLocale=function(t){console.warn("This method is deprecated. Use setCurrentLocale instead"),l(t)},t.setCurrentLocale=l,t.getText=function(...t){let i=e.texts,s="";if(t&&t.length){const e=t.length;for(let n=0;n<e&&(s=i[t[n]],"object"==typeof s);n++)i=s}return s},t.getLocaleSettings=d,t.getOneLocaleSetting=function(t){return e.settings[t]},t.getShortMonthName=function(t){const e=d();if(t>0&&t<13)return e.shortMonthNames[t-1];throw"Wrong month number: "+t},t.getLongMonthName=function(t){const e=d();if(t>0&&t<13)return e.longMonthNames[t-1];throw"Wrong month number: "+t},t.getShortWeekDayName=function(t){const e=d();if(t>0&&t<8)return e.shortWeekDayNames.length>=t?e.shortWeekDayNames[t-1]:t.toString();throw"Wrong month number: "+t},t.getLongWeekDayName=function(t){const e=d();if(t>0&&t<8)return e.longWeekDayNames.length>=t?e.longWeekDayNames[t-1]:t.toString();throw"Wrong month number: "+t},t.updateLocaleSettings=h,t.updateLocaleTexts=function(t){"object"==typeof t?(a({localeId:e.localeId,texts:t}),R.assignDeep(e.texts,t)):console.error("Wrong parameter type in updateLocaleTexts function call.The first parameter (localeId) is not necessary. Use updateLocaleTexts(texts) instead")},t.updateDefaultTexts=function(t){for(let e in n){let i=n[e];i.texts=R.assignDeep({},t,i.texts)}e.texts=R.assignDeep({},t,e.texts)},t.updateLocaleInfo=c,t.addLocale=function(t,e){c(t,e)},t.resetLocales=function(){e||(e=R.assignDeep({},s),function(t){const i=new Date(2020,5,7,19,34,56,88),s=i.toLocaleDateString(t,{year:"numeric",month:"numeric",day:"numeric"}),n=i.toLocaleTimeString(t,{hour:"numeric",minute:"numeric",second:"numeric"});let o=s.replace("07","dd").replace("7","d").replace("06","MM").replace("6","M").replace("2020","yyyy").replace("20","yy"),a=n.replace("19","HH").replace("07","hh").replace("7","h").replace("34","mm").replace("56","ss").replace("PM","tt");e.settings||(e.settings={}),h({shortDateFormat:o,shortTimeFormat:a})}("object"==typeof navigator?navigator.language:void 0))};const u=/\[([^\]]+)]|y{2,4}|M{1,4}|d{1,2}|H{1,2}|h{1,2}|m{2}|s{2}|t{2}/g;function p(e,i){const s=e.getFullYear().toString(),n=e.getMonth()+1,o=e.getDate(),a=e.getHours(),r=e.getMinutes(),l=e.getSeconds(),d=a%12||12,h=a>11,c={yyyy:s,yy:s.substring(s.length-2),MMMM:t.getLongMonthName(n),MMM:t.getShortMonthName(n),MM:n<10?"0"+n:n.toString(),M:n.toString(),dd:o<10?"0"+o:o.toString(),d:o.toString(),HH:a<10?"0"+a:a.toString(),H:a.toString(),hh:d<10?"0"+d:d.toString(),h:d.toString(),tt:h?"PM":"AM",mm:r<10?"0"+r:r.toString(),ss:l<10?"0"+l:l.toString()};return i.replace(u,((t,e)=>e||c[t]))}function g(t){const e=d();let i;switch(t){case I.Date:i=e.shortDateFormat;break;case I.Time:i=e.shortTimeFormat;break;default:i=e.shortDateFormat+" "+e.shortTimeFormat}return i}function m(t){const e=d();let i;switch(t){case I.Date:i=e.longDateFormat;break;case I.Time:i=e.longTimeFormat;break;default:i=e.longDateFormat+" "+e.longTimeFormat}return i}t.dateTimeToStr=p,t.dateTimeToStrEx=function(t,e,i){return i?"d"==i?i=g(I.Date):"D"==i?i=m(I.Date):"f"==i?i=g(I.DateTime):"F"==i&&(i=m(I.DateTime)):i=g(e),p(t,i)},t.numberToStr=function(e,i,s){if(i&&i.length>0){const s=i.charAt(0).toUpperCase();if("S"===s)return function(e,i){if(!f[i]){const t=i.split("|").filter((t=>t.length>0)).map((t=>t.split("=")));if(f[i]={},t.length>0)if(t[0].length>1)for(const e of t)f[i][Number.parseInt(e[1])]=e[0];else t.forEach(((t,e)=>{f[i][e]=t[0]}))}const s=f[i];if(void 0!==s[e]){const i=s[e];return t.getText(i)||i}return e.toString()}(e,i.slice(1));if(["D","F","C"].indexOf(s)>=0){const t=r();return e.toLocaleString(t,function(t){const e=d(),i=t[0].toUpperCase(),s=t.length>1?Number.parseInt(t.slice(1)):"D"==i?1:2;switch(i){case"D":return{style:"decimal",useGrouping:!1,minimumIntegerDigits:s};case"C":return{style:"currency",currency:e.currency,minimumFractionDigits:s};default:return{style:"decimal",minimumFractionDigits:s,maximumFractionDigits:s}}}(i))}return function(t,e){let i=t.toString(),s="",n=i.length-1;for(let t=e.length-1;t>=0;t--){const o=e.charAt(t);"#"===o||"0"===o?n>=0?(s+=i.charAt(n),n--):"0"===o&&(s+=0):s+=o}return s.split("").reverse().join("")}(Math.trunc(e),i)}const n=d();return s=s||n.decimalSeparator,e.toString().replace(".",s)},t.booleanToStr=function(e,i){if(i&&i.length>0&&"S"===i.charAt(0).toUpperCase()){const s=i.slice(1).split("|");if(s.length>1){const i=s[e?1:0];return t.getText(i)||i}}return`${e}`};const f={}}(k||(k={})),function(t){t[t.None=0]="None",t[t.Left=1]="Left",t[t.Center=2]="Center",t[t.Right=3]="Right"}(A||(A={}));class L{constructor(t,e){this.columns=t,this.values=e}toArray(){return Array.from(this.values)}size(){return this.values.length}getValue(t){let e;if("string"==typeof t){if(e=this.columns.getIndex(t),void 0===e)throw new RangeError(`No column with id '${t}'`)}else e=t;if(e>=this.values.length)throw new RangeError("Out of range: "+e);return this.values[e]}setValue(t,e){let i;if("string"==typeof t){if(i=this.columns.getIndex(t),void 0===i)throw new RangeError(`No column with id '${t}'`)}else i=t;if(i>=this.values.length)throw new RangeError("Out of range: "+i);this.values[i]=e}}class N{static newGuid(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(t){var e=16*Math.random()|0;return("x"==t?e:3&e|8).toString(16)}))}}class F{constructor(t){this.silentMode=0,this.events=new Array,this.source=t}subscribe(t,e){let i=this.getEventRecByType(t);const s={id:N.newGuid(),callback:e};return i?i.eventCallbacks.push(s):(i={type:t,eventCallbacks:new Array(s)},this.events.push(i)),s.id}unsubscribe(t,e){let i=this.getEventRecByType(t);if(i){let t=-1;for(t=0;t<i.eventCallbacks.length&&i.eventCallbacks[t].id!==e;t++);t>=0&&i.eventCallbacks.splice(t,1)}}fire(t,e,i=0,s=!1){if(this.silentMode&&!s)return;let n=this.getEventRecByType(t);if(n){const s={type:t,source:this.source,data:e};let o=()=>{for(let t of n.eventCallbacks)t.callback(s)};i>0?setTimeout(o,i):o()}}enterSilentMode(){this.silentMode++}exitSilentMode(){this.silentMode&&this.silentMode--}isSilent(){return this.silentMode>0}getEventRecByType(t){for(let e of this.events)if(e.type==t)return e;return null}}function $(t){let e={x:0,y:0};if(null!==t){const i=function(t){const e={top:0,right:0,bottom:0,left:0,width:0,height:0};let i;try{i=t.getBoundingClientRect()}catch(t){i=e}const s=document.body,n=document.documentElement,o=function(){const t=document.body,e=document.documentElement;return{top:window.pageYOffset||e.scrollTop||t.scrollTop,left:window.pageXOffset||e.scrollLeft||t.scrollLeft}}(),a=o.top,r=o.left,l=n.clientTop||s.clientTop||0,d=n.clientLeft||s.clientLeft||0,h=i.top+a-l,c=i.left+r-d;return{top:Math.round(h),left:Math.round(c)}}(t);e={x:i.left,y:i.top}}return e}(P||(P={})).renderLiquidTemplate=function(t,e){let i=t;if(e)for(let t in e){const s=new RegExp("{{"+t+"}}","g");i=i.replace(s,e[t])}return i},k.resetLocales(),"function"!=typeof Object.values&&(Object.values=function(t){return Object.keys(t).map((e=>t[e]))}),"function"!=typeof Math.trunc&&(Math.trunc=function(t){return isNaN(t)?NaN:t>0?Math.floor(t):Math.ceil(t)}),function(t){let e=null,i=null;function s(){if(null===i){const t=navigator.userAgent;i=t.indexOf("MSIE ")>-1||t.indexOf("Trident/")>-1}return i}t.IsIE=s,t.IsEdge=function(){const t=window.navigator.userAgent;return!s()&&t.includes("Edge/")},t.IsFirefox=function(){if(null===e){const t=navigator.userAgent;e=t.toLowerCase().indexOf("firefox")>-1}return e};let n,o,a=!1,r=()=>{const t=l();a=window.matchMedia("only screen and (max-width: 840px)").matches||window.matchMedia("only screen and (max-height: 420px)").matches;const e=l();e!==t&&o&&o(e)};function l(){return void 0!==n?n:a}r(),window.addEventListener("resize",(()=>r())),t.isMobileMode=l,t.setIsMobileMode=function(t){const e=l();n=t;const i=l();i!==e&&o&&o(i)},t.onMobileModeChanged=function(t){o=t},t.getMobileCssClass=function(){return l()?"k-mobile":null}}(O||(O={}));const B="eqjs";class H{constructor(t,e){this.element="string"==typeof t?document.createElement(t):t,e&&this.element.parentElement!==e&&e.appendChild(this.element)}addChild(t,e){const i=z(t,this.element);return e&&e(i),this}addChildElement(t){return t&&this.element.appendChild(t),this}attr(t,e){return this.element.setAttribute(t,e),this}id(t){return this.attr("id",t)}focus(){return this.element.focus(),this}title(t){return this.attr("title",t)}data(t,e=null){return null===e?(this.element.removeAttribute("data-"+t),this):this.attr("data-"+t,e)}show(){return this.removeStyle("display")}hide(t=!0){return t?this.setStyle("display","none"):this}visible(t=!0){return t?this.setStyle("visibility","visible"):this.setStyle("visibility","hidden")}isVisible(){return!!(this.element.offsetWidth||this.element.offsetHeight||this.element.getClientRects().length)}addClass(t,...e){if(t){const i=[...t.trim().split(" "),...e];for(let t=0;t<i.length;t++)this.element.classList.add(i[t])}return this}removeClass(t,...e){if(t){const i=[...t.trim().split(" "),...e];for(let t=0;t<i.length;t++)this.element.classList.remove(i[t])}return this}toggleClass(t,e=void 0){return t&&this.element.classList.toggle(t,e),this}on(t,e){const i=t.split(" ");for(let t=0;t<i.length;t++)this.element.addEventListener(i[t],e);return this}off(t,e){const i=t.split(" ");for(let t=0;t<i.length;t++)this.element.removeEventListener(i[t],e);return this}setStyle(t,e){return this.element.style.setProperty(t,e),this}removeStyle(t){return this.element.style.removeProperty(t),this}text(t){return this.element.innerText=t,this}html(t){return this.element.innerHTML=t,this}clear(){const t=this.element;this.element=document.createElement(this.element.tagName),t.replaceWith(this.element)}addText(t){const e=document.createTextNode(t);return this.element.appendChild(e),this}addHtml(t){return this.element.innerHTML+=t,this}toDOM(){return this.element}appendTo(t){return t&&t.appendChild(this.element),this}}class V extends H{constructor(t,e){super(t||"textarea",e)}name(t){return this.element.name=t,this}rows(t){return this.element.rows=t,this}cols(t){return this.element.cols=t,this}value(t){return this.element.value=t,this}}class _ extends H{constructor(t,e){super(t||"input",e)}name(t){return this.element.name=t,this}type(t){return this.element.type=t,this}size(t){return this.element.size=t,this}value(t){return t instanceof Date?this.element.valueAsDate=t:"number"==typeof t?this.element.valueAsNumber=t:this.element.value=t,this}mask(t){return function(t,e){const i={9:"[0-9]",a:"[a-z]"},s=e.split(""),n=e=>{if("focus"===e.type&&""!==t.value)return;let n=[],o=t.selectionStart;s.forEach(((e,s)=>{if(i[e]){let o=new RegExp(i[e],"i").test(t.value.charAt(s));n.push(o?t.value.charAt(s):"_")}else n.push(e)})),t.value=n.join(""),t.selectionStart=t.selectionEnd=o};t.addEventListener("keydown",(e=>{if(8===e.keyCode||46===e.keyCode){e.preventDefault();let n=[],o=t.selectionStart;if(0==o)return;let a=o,r=!0;for(let e=s.length-1;e>=0;e--){const l=s[e];if(i[l]){let s=new RegExp(i[l],"i").test(t.value.charAt(e));s&&e!=o-1&&(r=!1),e===o-1&&a--,n.push(s&&e!=o-1?t.value.charAt(e):"_")}else e===a-1&&a--,o-1===e&&o--,n.push(l)}t.value=r?"":n.reverse().join(""),t.selectionStart=t.selectionEnd=a<0?0:a;const l=document.createEvent("Event");l.initEvent("input",!0,!0),t.dispatchEvent(l)}})),t.addEventListener("keypress",(e=>{const n=String.fromCharCode(e.charCode);if(n){e.preventDefault();let o=[],a=t.selectionStart,r=a;s.forEach(((e,s)=>{if(i[e]){const l=s!=a?t.value.charAt(s):n;let d=new RegExp(i[e],"i").test(l);o.push(d?l:"_"),d&&a===s&&r++}else o.push(e),r===s&&r++,a===s&&a++})),t.value=o.join(""),t.selectionStart=t.selectionEnd=r;const l=document.createEvent("Event");l.initEvent("input",!0,!0),t.dispatchEvent(l)}})),t.addEventListener("input",n),t.addEventListener("focus",n)}(this.element,t),this}}class W extends H{constructor(t,e){super(t||"select",e)}addOption(t){const e=document.createElement("option");return"string"==typeof t?(e.value=t,e.innerHTML=t):(e.value=t.value,e.innerHTML=t.title||t.value,e.selected=t.selected||!1),this.element.appendChild(e),this}value(t){return this.element.value=t,this}}function z(t,e){return"div"===t||t instanceof HTMLDivElement||"span"===t||t instanceof HTMLSpanElement||"a"===t||t instanceof HTMLAnchorElement||"button"===t||t instanceof HTMLButtonElement||"img"===t||t instanceof HTMLImageElement?new H(t,e):"input"===t||t instanceof HTMLInputElement?new _(t instanceof HTMLInputElement?t:null,e):"textarea"===t||t instanceof HTMLTextAreaElement?new V(t instanceof HTMLTextAreaElement?t:null,e):"select"===t||t instanceof HTMLSelectElement?new W(t instanceof HTMLSelectElement?t:null,e):new H(t,e)}const j="undefined"!=typeof TouchEvent;var G;!function(t){t.None="none",t.Allow="allow",t.Forbid="forbid"}(G||(G={}));class U{constructor(t,e,i){this.dropEffect=G.Allow,this.pageX=0,this.pageY=0,this.item=t,this.dragImage=e,this.data=t.data,this.sourceEvent=i,i&&i instanceof MouseEvent&&(this.pageX=i.pageX,this.pageY=i.pageY),i&&j&&i instanceof TouchEvent&&i.touches[0]&&(this.pageX=i.touches[0].pageX,this.pageY=i.touches[0].pageY)}}class q{constructor(t){t&&t instanceof MouseEvent&&(this.x=t.pageX,this.y=t.pageY),t&&j&&t instanceof TouchEvent&&t.touches[0]&&(this.x=t.touches[0].pageX,this.y=t.touches[0].pageY)}}const Y=new class{constructor(){this.delta=5,this.draggableItem=null,this.dragImage=null,this.finishedSuccessfully=!1,this.mouseDownPosition=null,this.containerDescriptors=[],this.containerDescriptorIndex=-1,this.dropEffect=G.None,this.classPrefix="eqjs-drop",this.DRAG_DISABLED_ATTR="drag-disabled"}registerDraggableItem(t){const e=t.element;if(!e)throw Error("Element in draggle item is null or undefined");e.ondragstart=function(){return!1};const i=t=>{if(e.hasAttribute(this.DRAG_DISABLED_ATTR))return;t.preventDefault(),t instanceof MouseEvent&&t.stopPropagation();const i=new q(t);(Math.abs(i.x-this.mouseDownPosition.x)>this.delta||Math.abs(i.y-this.mouseDownPosition.y)>this.delta)&&n(t)},s=t=>{this.mouseMoveDragListener(t)},n=n=>{n.preventDefault(),n.stopPropagation(),e.removeEventListener("mousemove",i),e.removeEventListener("touchmove",i),this.finishedSuccessfully=!1,t.beforeDragStart&&t.beforeDragStart(),this.dragImage=z("div").setStyle("position","absolute").setStyle("z-index","65530").toDOM(),document.body.appendChild(this.dragImage),this.dragImage.appendChild(e.cloneNode(!0)),t.renderer&&t.renderer(this.dragImage),this.dropEffect=G.None,this.updateCusror(this.dropEffect),this.updateImageClass(this.dropEffect),this.draggableItem={element:e,scope:t.scope,data:t.data},this.updateDragItemPosition(n);const o=new U(this.draggableItem,this.dragImage,n);o.dropEffect=this.dropEffect,t.onDragStart&&t.onDragStart(o),this.dropEffect!==o.dropEffect&&(this.dropEffect=o.dropEffect,this.updateImageClass(this.dropEffect)),document.addEventListener("mousemove",s,!0),document.addEventListener("touchmove",s,!0)},o=t=>{j&&t instanceof TouchEvent&&t.preventDefault(),this.mouseDownPosition=new q(t),e.addEventListener("mousemove",i),e.addEventListener("touchmove",i),document.addEventListener("mouseup",a),document.addEventListener("touchend",a)};e.addEventListener("mousedown",o),e.addEventListener("touchstart",o);const a=t=>{this.mouseDownPosition=null,e.removeEventListener("mousemove",i),e.removeEventListener("touchmove",i),document.removeEventListener("mousemove",s,!0),document.removeEventListener("touchmove",s,!0),this.draggableItem&&r(t)},r=e=>{try{if(this.containerDescriptorIndex>=0){const t=this.containerDescriptors[this.containerDescriptorIndex],i={element:t.element,scopes:t.scopes,data:t.data},s=new U(this.draggableItem,this.dragImage,e);try{i.scopes.indexOf(this.draggableItem.scope)>=0&&this.dropEffect===G.Allow&&(this.finishedSuccessfully=!0,t.onDrop&&t.onDrop(i,s))}finally{t.onDragLeave&&t.onDragLeave(i,s)}}}finally{try{const i=new U(this.draggableItem,this.dragImage,e);i.data.finishedSuccessfully=this.finishedSuccessfully,t.onDragEnd&&t.onDragEnd(i)}finally{this.draggableItem=null,this.dragImage&&this.dragImage.parentElement&&this.dragImage.parentElement.removeChild(this.dragImage),this.dragImage=null,this.finishedSuccessfully=!1,document.removeEventListener("mouseup",a),document.removeEventListener("touchend",a)}}}}registerDropContainer(t){if(!t.element)throw Error("Element in drop container is null or undefined");this.containerDescriptors.push(t)}removeDropContainer(t){const e=this.containerDescriptors.filter((e=>e===t||e.element==t));if(e)for(const t of e)R.removeArrayItem(this.containerDescriptors,t)}mouseMoveDragListener(t){if(t instanceof MouseEvent&&t.preventDefault(),t.stopPropagation(),this.updateDragItemPosition(t),-1==this.containerDescriptorIndex){for(let e=0;e<this.containerDescriptors.length;e++){const i=this.containerDescriptors[e];if(this.detectDragEnterEvent(i.element,t)){this.containerDescriptorIndex=e;break}}this.containerDescriptorIndex>=0&&this.dragEnterEvent(t)}else{const e=this.containerDescriptors[this.containerDescriptorIndex];this.detectDragLeaveEvent(e.element,t)&&(this.dragLeaveEvent(t),this.containerDescriptorIndex=-1)}if(this.containerDescriptorIndex>=0){const e=this.containerDescriptors[this.containerDescriptorIndex],i={element:e.element,scopes:e.scopes,data:e.data};if(i.scopes.indexOf(this.draggableItem.scope)>=0){const s=new U(this.draggableItem,this.dragImage,t);s.dropEffect=this.dropEffect,e.onDragOver&&e.onDragOver(i,s)}}}updateCusror(t){switch(t){case G.Allow:this.setCursorStyle(this.dragImage,"grabbing");break;case G.Forbid:this.setCursorStyle(this.dragImage,"no-drop");break;default:this.setCursorStyle(this.dragImage,"grabbing")}}updateImageClass(t){switch(this.dragImage.classList.remove(`${this.classPrefix}-allow`),this.dragImage.classList.remove(`${this.classPrefix}-forbid`),this.dragImage.classList.remove(`${this.classPrefix}-none`),t){case G.Allow:this.dragImage.classList.add(`${this.classPrefix}-allow`);break;case G.None:this.dragImage.classList.add(`${this.classPrefix}-none`);break;case G.Forbid:this.dragImage.classList.add(`${this.classPrefix}-forbid`);break;default:this.dragImage.classList.add(`${this.classPrefix}-none`)}}setCursorStyle(t,e){if(t){t.style.cursor=e;for(let i=0;i<t.children.length;i++)this.setCursorStyle(t.children[i],e)}}updateDragItemPosition(t){if(this.dragImage){const e=new q(t);this.dragImage.style.top=e.y-this.dragImage.offsetHeight/2+"px",this.dragImage.style.left=e.x-this.dragImage.offsetWidth/2+"px"}}dragEnterEvent(t){const e=this.containerDescriptors[this.containerDescriptorIndex],i={element:e.element,scopes:e.scopes,data:e.data};if(i.scopes.indexOf(this.draggableItem.scope)>=0){const s=new U(this.draggableItem,this.dragImage,t);s.dropEffect=G.Allow,e.onDragEnter&&e.onDragEnter(i,s),this.dropEffect=s.dropEffect,this.updateCusror(this.dropEffect),this.updateImageClass(this.dropEffect)}else this.dropEffect!==G.Forbid&&(this.dropEffect=G.None,this.updateCusror(this.dropEffect),this.updateImageClass(this.dropEffect))}dragLeaveEvent(t){const e=this.containerDescriptors[this.containerDescriptorIndex],i={element:e.element,scopes:e.scopes,data:e.data};if(i.scopes.indexOf(this.draggableItem.scope)>=0){const s=new U(this.draggableItem,this.dragImage,t);s.dropEffect=G.None,e.onDragLeave&&e.onDragLeave(i,s),this.dropEffect=s.dropEffect,this.updateCusror(this.dropEffect),this.updateImageClass(this.dropEffect)}}detectDragEnterEvent(t,e){const i=$(t),s=new q(e);return!(s.y<i.y||s.y>i.y+t.offsetHeight||s.x<i.x||s.x>i.x+t.offsetWidth)}detectDragLeaveEvent(t,e){const i=$(t),s=new q(e);return!(s.y>i.y&&s.y<i.y+t.offsetHeight&&s.x>i.x&&s.x<i.x+t.offsetWidth)}};var K,J;!function(t){t[t.Always=0]="Always",t[t.Once=1]="Once",t[t.Never=2]="Never"}(K||(K={})),function(t){t[t.NONE=1]="NONE",t[t.LEFT=2]="LEFT",t[t.CENTER=3]="CENTER",t[t.RIGHT=4]="RIGHT"}(J||(J={}));class X{constructor(t,e,i=!1){this._label=null,this._description=null,this.align=J.NONE,this.isVisible=!0,this.isRowNum=!1,this.dataColumn=t,this.grid=e;const s=e.options.columnWidths||{};t?(t.style.alignment&&(this.align=function(t){switch(t){case A.Left:return J.LEFT;case A.Center:return J.CENTER;case A.Right:return J.RIGHT;default:return J.NONE}}(t.style.alignment)),this.width=s&&s[this.type]?s[this.type].default:250,this._description=t.description):i&&(this.isRowNum=!0,this.width=s&&s.rowNumColumn?s.rowNumColumn.default:60,this._label="")}get label(){return this._label?this._label:this.isRowNum?"":this.dataColumn.label}set label(t){this._label=this.label}get description(){return this._description}get type(){return this.dataColumn?this.dataColumn.type:null}}class Q{constructor(t,e){this.items=[],this.grid=e,this.sync(t)}sync(t,e=!0){this.clear();const i=new X(null,this.grid,!0);if(this.add(i),e||(i.isVisible=!1),t)for(let e of t.getItems()){const t=new X(e,this.grid);this.grid.options.onSyncGridColumn&&this.grid.options.onSyncGridColumn(t),this.add(t)}}get count(){return this.items.length}add(t){const e=this.items.length;return this.items.push(t),e}put(t,e){t>=0&&t<this.items.length&&(this.items[t]=e)}move(t,e){let i=this.items.indexOf(t);i>=0&&i!=e&&R.moveArrayItem(this.items,i,e)}get(t){return t>=0&&t<this.items.length?this.items[t]:null}getItems(){return this.items}removeAt(t){this.get(t),this.items.splice(t,1)}clear(){this.items=[]}}const Z="keg",tt=/{0:(.*?)}/g;var et;!function(t){t[t.STRING=1]="STRING",t[t.NUMBER=2]="NUMBER",t[t.DATETIME=3]="DATETIME",t[t.BOOL=4]="BOOL"}(et||(et={}));const it=(t,e,i,s)=>{const n=t?t.toString().replace(/\n/g,"↵ "):"";i.innerText=n,i.title=n,e.align==J.NONE&&i.classList.add(`${Z}-cell-value-align-left`)},st=(t,e,i,s)=>{let n=(t||"").toString();"number"==typeof t&&(n=e.dataColumn&&e.dataColumn.displayFormat&&tt.test(e.dataColumn.displayFormat)?e.dataColumn.displayFormat.replace(tt,((e,i)=>k.numberToStr(t,i))):t.toLocaleString()),i.innerText=n,i.title=n,e.align==J.NONE&&i.classList.add(`${Z}-cell-value-align-right`)},nt=(t,e,i,s)=>{const n="[object Date]"===Object.prototype.toString.call(t);let o=(t||"").toString();if(n)if(e.dataColumn&&e.dataColumn.displayFormat&&tt.test(e.dataColumn.displayFormat))o=e.dataColumn.displayFormat.replace(tt,((i,s)=>k.dateTimeToStrEx(t,e.type,s)));else{const i=k.getCurrentLocale(),s={hour:"numeric",minute:"numeric",second:"numeric"};switch(e.type){case I.Date:o=t.toLocaleDateString(i);break;case I.Time:o=t.toLocaleTimeString(i,s);break;case I.DateTime:o=`${t.toLocaleDateString(i)} ${t.toLocaleTimeString(i,s)}`}}i.innerText=o,i.title=o,e.align==J.NONE&&i.classList.add(`${Z}-cell-value-align-right`)},ot=(t,e,i,s)=>{if(e.dataColumn&&e.dataColumn.displayFormat&&tt.test(e.dataColumn.displayFormat)){const s=e.dataColumn.displayFormat.replace(tt,((e,i)=>k.booleanToStr(t,i)));return it(s,e,i)}i.classList.add(`${Z}-cell-value-bool`),i.classList.add(`${Z}-${t?"cell-value-true":"cell-value-false"}`)};class at{constructor(t){this.renderers={},this.defaultRenderers={},this.registerRenderer("StringDefault",it),this.setDefaultRenderer(et.STRING,it),this.registerRenderer("NumberDefault",st),this.setDefaultRenderer(et.NUMBER,st),this.registerRenderer("DateTimeDefault",nt),this.setDefaultRenderer(et.DATETIME,nt),this.registerRenderer("BoolDefault",ot),this.setDefaultRenderer(et.BOOL,ot)}getDefaultRenderer(t){const e=this.getCellType(t);return this.defaultRenderers[et[e]]}getDefaultRendererByType(t){return this.defaultRenderers[et[t]]}setDefaultRenderer(t,e){e&&(this.defaultRenderers[et[t]]=e)}getRenderer(t){return this.renderers[t]}registerRenderer(t,e){this.renderers[t]=e}getCellType(t){switch(t){case I.Autoinc:case I.Byte:case I.Word:case I.Currency:case I.Float:case I.Int32:case I.Int64:return et.NUMBER;case I.Date:case I.DateTime:case I.Time:return et.DATETIME;case I.Bool:return et.BOOL;default:return et.STRING}}}class rt{constructor(t){if(this.cssPrefix="keg",this.pagination={page:1,pageSize:30,total:0},this.paginationOptions={maxButtonCount:10,useBootstrap:!1},this.defaultDataGridOptions={slot:null,dataTable:null,fixHeightOnFirstRender:!1,syncGridColumns:!0,useRowNumeration:!0,allowDragDrop:!1,aggregates:{settings:null,calculator:null},paging:{enabled:!0,pageSize:30,pageSizeItems:[20,30,50,100,200]},columnWidths:{autoResize:K.Always,stringColumns:{min:100,max:500,default:250},numberColumns:{min:60,default:120},boolColumns:{min:50,default:80},dateColumns:{min:80,default:200},otherColumns:{min:100,max:500,default:250},rowNumColumn:{min:40,default:60}},showPlusButton:!1,viewportRowsCount:null,showActiveRow:!0},this.rowsOnPagePromise=null,this.containerInitialHeight=0,this.firstRender=!0,this.prevRowTotals=null,this.landingIndex=-1,this.landingSlot=z("div").addClass(`${this.cssPrefix}-col-landing-slot`).addChildElement(z("div").toDOM()).toDOM(),this._activeRowIndex=-1,t&&t.paging&&(t.paging=R.assign(this.defaultDataGridOptions.paging,t.paging)),this.options=this.mergeOptions(t),this.processColumnWidthsOptions(),!this.options.slot)throw Error('"slot" parameter is required to initialize EasyDataGrid');if(!this.options.dataTable)throw Error('"dataTable" parameter is required to initialize EasyDataGrid');this.dataTable=t.dataTable,this.eventEmitter=new F(this),this.cellRendererStore=new at(t),this.columns=new Q(this.dataTable.columns,this),this.setSlot(this.options.slot),this.init(this.options)}mergeOptions(t){const e=R.assignDeep({},this.defaultDataGridOptions.columnWidths,t.columnWidths),i=R.assignDeep({},this.defaultDataGridOptions.paging,t.paging),s=R.assign({},this.defaultDataGridOptions,t);return s.columnWidths=e,s.paging=i,s}processColumnWidthsOptions(){const t=this.options.columnWidths;if(!t)return;R.getStringDataTypes().forEach((e=>{t[e]=Object.assign(Object.assign({},t.stringColumns),t[e])})),R.getNumericDataTypes().forEach((e=>{t[e]=Object.assign(Object.assign({},t.numberColumns),t[e])})),t[I.Bool]=Object.assign(Object.assign({},t.boolColumns),t[I.Bool]),R.getDateDataTypes().forEach((e=>{t[e]=Object.assign(Object.assign({},t.dateColumns),t[e])}));const e=[...R.getStringDataTypes(),...R.getNumericDataTypes(),...R.getDateDataTypes(),I.Bool];R.getAllDataTypes().forEach((i=>{i in e||(t[i]=Object.assign(Object.assign({},t.otherColumns),t[i]))})),t[I.Unknown]=t.otherColumns}setSlot(t){if("string"==typeof t){if(t.length)if("#"===t[0])this.slot=document.getElementById(t.substring(1));else{if("."!==t[0])throw Error("Unrecognized slot parameter (Must be id, class or HTMLElement): "+t);{const e=document.getElementsByClassName(t.substring(1));e.length&&(this.slot=e[0])}}}else this.slot=t}init(t){t.onInit&&this.addEventListener("init",t.onInit),t.onRowClick&&this.addEventListener("rowClick",t.onRowClick),t.onRowDbClick&&this.addEventListener("rowDbClick",t.onRowDbClick),t.onPlusButtonClick&&this.addEventListener("plusButtonClick",t.onPlusButtonClick),t.onColumnChanged&&this.addEventListener("columnChanged",t.onColumnChanged),t.onColumnDeleted&&this.addEventListener("columnDeleted",t.onColumnDeleted),t.onColumnMoved&&this.addEventListener("columnMoved",t.onColumnMoved),t.onPageChanged&&this.addEventListener("pageChanged",t.onPageChanged),t.onActiveRowChanged&&this.addEventListener("activeRowChanged",t.onActiveRowChanged),this.addEventListener("pageChanged",(t=>this.activeRowIndex=-1)),R.assignDeep(this.paginationOptions,t.pagination),this.pagination.pageSize=this.options.paging.pageSize||this.pagination.pageSize,this.options.allowDragDrop&&Y.registerDropContainer({element:this.slot,scopes:["gridColumnMove"],onDragEnter:(t,e)=>{this.slot.classList.add(`${B}-drophover`),this.showLandingSlot(e.pageX,e.pageY)},onDragOver:(t,e)=>{this.showLandingSlot(e.pageX,e.pageY)},onDragLeave:(t,e)=>{e.dropEffect=G.Forbid,this.slot.classList.remove(`${B}-drophover`),this.hideLandingSlot()},onDrop:(t,e)=>{this.dataTable.columns.move(e.data.column,this.landingIndex),this.refresh(),this.fireEvent({type:"columnMoved",columnId:e.data.column.id,newIndex:this.landingIndex})}}),this.refresh(),this.fireEvent("init")}fireEvent(t){"string"==typeof t?this.eventEmitter.fire(t):this.eventEmitter.fire(t.type,t)}setData(t){this.dataTable=t,this.clear(),this.refresh()}getData(){return this.dataTable}getColumns(){return this.columns}destroy(){this.slot.innerHTML=""}refresh(){this.clearDOM(),this.render()}clearDOM(){this.slot.innerHTML=""}clear(){this.pagination.page=1,this.clearDOM()}render(){if(!this.hasData()&&!this.options.showPlusButton)return;this.containerInitialHeight=this.slot.clientHeight,this.rootDiv=document.createElement("div"),this.rootDiv.style.width="100%",this.rootDiv.classList.add(`${this.cssPrefix}-root`),this.columns.sync(this.dataTable.columns,this.options.useRowNumeration),this.renderHeader(),this.rootDiv.appendChild(this.headerDiv),this.renderBody(),this.rootDiv.appendChild(this.bodyDiv),this.renderFooter(),this.rootDiv.appendChild(this.footerDiv);let t=document.createElement("div");t.classList.add(`${this.cssPrefix}-container`),t.appendChild(this.rootDiv),this.slot.appendChild(t);const e=this.options.columnWidths.autoResize!==K.Never;this.rowsOnPagePromise?this.rowsOnPagePromise.then((()=>this.updateHeight())).then((()=>{this.firstRender=!1,this.rowsOnPagePromise=null})):setTimeout((()=>{this.updateHeight().then((()=>{this.firstRender=!1,e&&this.resizeColumns()}))}),100)}updateHeight(){return new Promise((t=>{if(this.options.viewportRowsCount){const e=this.bodyCellContainerDiv.firstElementChild;let i=(e?e.offsetHeight:36)*this.options.viewportRowsCount;return z(this.bodyViewportDiv).setStyle("height",`${i}px`),void setTimeout((()=>{const e=this.bodyViewportDiv.offsetHeight-this.bodyViewportDiv.clientHeight;i+=e,z(this.bodyViewportDiv).setStyle("height",`${i}px`),t()}),100)}this.containerInitialHeight,t()})).then((()=>{this.options.fixHeightOnFirstRender&&this.firstRender&&(this.slot.style.height=`${this.slot.offsetHeight}px`)}))}getContainerWidth(){return this.columns.getItems().filter((t=>t.isVisible)).map((t=>t.width)).reduce(((t,e)=>t+e))}renderHeader(){this.headerDiv=z("div").addClass(`${this.cssPrefix}-header`).toDOM(),this.headerViewportDiv=z("div",this.headerDiv).addClass(`${this.cssPrefix}-header-viewport`).toDOM(),this.headerCellContainerDiv=z("div",this.headerViewportDiv).addClass(`${this.cssPrefix}-header-cell-container`).toDOM(),this.headerRowDiv=z("div",this.headerCellContainerDiv).addClass(`${this.cssPrefix}-header-row`).toDOM(),this.columns.getItems().forEach(((t,e)=>{if(!t.isVisible)return;let i=this.renderColumnHeader(t,e);this.headerRowDiv.appendChild(i),t.isRowNum&&z(i).addChildElement(this.renderHeaderButtons())}));const t=this.getContainerWidth();z(this.headerCellContainerDiv).setStyle("width",`${t}px`)}hasData(){return this.dataTable.columns.count>0}renderColumnHeader(t,e){let i=z("div").addClass(`${this.cssPrefix}-header-cell`).data("col-idx",`${e}`).setStyle("width",`${t.width}px`);t.dataColumn&&i.data("col-id",`${t.dataColumn.id}`);let s=i.toDOM();return z("div",s).addClass(`${this.cssPrefix}-header-cell-resize`),t.isRowNum||z("div",s).addClass(`${this.cssPrefix}-header-cell-label`).text(t.label),t.description&&z("div",s).addClass("question-mark").title(t.description),this.options.allowDragDrop&&Y.registerDraggableItem({element:s,scope:"gridColumnMove",data:{column:t},renderer:e=>{e.innerHTML="";const i=document.createElement("div");i.innerText=t.label,e.classList.add(`${this.cssPrefix}-sortable-helper`),e.appendChild(i)},onDragStart:t=>{t.dropEffect=G.Allow}}),s}renderBody(){this.bodyDiv=z("div").addClass(`${this.cssPrefix}-body`).toDOM(),this.bodyViewportDiv=z("div",this.bodyDiv).addClass(`${this.cssPrefix}-body-viewport`).attr("tabIndex","0").toDOM(),this.bodyCellContainerDiv=z("div",this.bodyViewportDiv).addClass(`${this.cssPrefix}-cell-container`).toDOM();const t=this.canShowAggregates();this.dataTable&&(this.showProgress(),this.rowsOnPagePromise=this.getRowsToRender().then((e=>{this.pagination.total=this.dataTable.getTotal(),this.hideProgress(),this.bodyCellContainerDiv.innerHTML="",this.prevRowTotals=null;let i=0;if(e.length){const s=t?this.options.aggregates.settings.getGroups():[];i=e.length<this.pagination.pageSize?e.length:this.pagination.pageSize,e.forEach(((e,n)=>{if(t&&this.updateTotalsState(s,e),n<i){const t=this.renderRow(e,n);this.bodyCellContainerDiv.appendChild(t)}}));const n=this.options.aggregates&&this.options.aggregates.showGrandTotalsOnEachPage;if(t&&(this.isLastPage()||n)){const t=new L(this.dataTable.columns,new Array(this.dataTable.columns.count));this.updateTotalsState(s,t,!0)}}if(this.options.columnWidths.autoResize!==K.Never)this.resizeColumns();else{const t=this.getContainerWidth();z(this.bodyCellContainerDiv).setStyle("width",`${t}px`)}return i})).catch((t=>(console.error(t),0)))),this.bodyViewportDiv.addEventListener("scroll",(t=>{z(this.headerViewportDiv).setStyle("margin-left",`-${this.bodyViewportDiv.scrollLeft}px`)})),this.bodyViewportDiv.addEventListener("keydown",this.onViewportKeydown.bind(this))}isLastPage(){return this.dataTable.elasticChunks?this.dataTable.totalIsKnown()&&this.pagination.page*this.pagination.pageSize>=this.pagination.total:this.pagination.page*this.pagination.pageSize>=this.pagination.total}canShowAggregates(){if(!this.options||!this.options.aggregates||!this.options.aggregates.settings)return!1;const t=this.options.aggregates.settings;return(t.hasAggregates()||t.hasRecordCount())&&(t.hasGroups()||t.hasGrandTotals())}updateTotalsState(t,e,i=!1){const s=this.options.aggregates.settings;if(this.prevRowTotals&&s.hasGroups()){let i=-1;for(let n=1;n<=t.length;n++){const o=t[n-1];for(const t of o.columns)if(!s.compareValues(this.prevRowTotals.getValue(t),e.getValue(t))){i=n;break}if(-1!==i)break}if(-1!==i)for(let e=t.length;e>=i;e--){const t=new L(this.dataTable.columns,this.prevRowTotals.toArray()),i=this.renderTotalsRow(e,t);this.bodyCellContainerDiv.appendChild(i)}}if(i&&s.hasGrandTotals()&&s.hasAggregates()){const t=this.renderTotalsRow(0,e);this.bodyCellContainerDiv.appendChild(t)}this.prevRowTotals=e}applyGroupColumnTemplate(t,e,i){let s=t.replace(/{{\s*GroupValue\s*}}/g,e?`${e}`:"-");return s=s.replace(/{{\s*GroupCount\s*}}/g,i?`${i}`:"-"),s}renderTotalsRow(t,e){const i=this.options.aggregates.settings,s=t>0?i.getGroups()[t-1]:{columns:[],aggregates:i.getAggregates()},n=z("div").addClass(`${this.cssPrefix}-row`).addClass(`${this.cssPrefix}-row-totals`).addClass(`${this.cssPrefix}-totals-lv${t}`).data("totals-level",`${t}`).attr("tabindex","-1").toDOM();this.columns.getItems().forEach(((t,i)=>{if(!t.isVisible)return;let o="";const a=t.isRowNum?-1:this.dataTable.columns.getIndex(t.dataColumn.id);!t.isRowNum&&t.dataColumn&&s.columns.indexOf(t.dataColumn.id)>=0&&(o=e.getValue(a)),a==this.dataTable.columns.count-1&&(o=". . . . . ."),n.appendChild(this.renderCell(t,i,o,n))}));const o=this.options.aggregates.calculator.getAggrContainer(),a=i.getAggregates().map((t=>t.colId)),r=i.buildGroupKey(s,e);return o.getAggregateData(t,r).then((o=>{for(const t of a)e.setValue(t,o[t]);n.innerHTML="",this.columns.getItems().forEach(((r,l)=>{if(!r.isVisible)return;let d="";const h=r.isRowNum?-1:this.dataTable.columns.getIndex(r.dataColumn.id);if(!r.isRowNum){let c=!1;if(r.dataColumn){const i=s.columns.indexOf(r.dataColumn.id),n=a.indexOf(r.dataColumn.id);c=t>0?i==s.columns.length-1:0==h,(i>=0||n>=0)&&(d=e.getValue(h))}let u="";t>0&&(u=r.dataColumn.groupFooterColumnTemplate,!u&&i.hasRecordCount()&&c&&(u="{{GroupValue}} ({{GroupCount}})")),u&&(d=this.renderCell(r,l,d,n).firstChild.innerHTML,d=this.applyGroupColumnTemplate(u,d,o[i.COUNT_FIELD_NAME]))}const c=this.renderCell(r,l,d,n);n.appendChild(c)}))})).catch((t=>console.error(t))),n}onViewportKeydown(t){if(this.options.showActiveRow){const e=this.bodyCellContainerDiv.querySelectorAll(`.${this.cssPrefix}-row`).length;let i;switch(t.key){case"ArrowLeft":case"ArrowRight":break;case"ArrowUp":t.preventDefault(),i=this.activeRowIndex<0||this.activeRowIndex>=e?e-1:this.activeRowIndex-1,this.activeRowIndex=i>=0?i:0;break;case"ArrowDown":t.preventDefault(),i=this.activeRowIndex<0||this.activeRowIndex>=e?0:this.activeRowIndex+1,this.activeRowIndex=i<e?i:e-1}}}ensureRowVisibility(t){const e="number"==typeof t?this.getDataRow(t):t;if(e){let t=e.getBoundingClientRect();const i=this.bodyViewportDiv.getBoundingClientRect(),s=t.top-i.top,n=t.bottom-i.top,o=this.bodyViewportDiv.clientHeight,a=window.innerHeight||document.documentElement.clientHeight;if(s>0&&n<=o&&t.top>0&&t.bottom<a)return;s<0?this.bodyViewportDiv.scrollTop=this.bodyViewportDiv.scrollTop+s:n>o&&(this.bodyViewportDiv.scrollTop=this.bodyViewportDiv.scrollTop+n-o),t=e.getBoundingClientRect(),t.top<0?document.documentElement.scrollTop=document.documentElement.scrollTop+t.top:t.bottom>a&&(document.documentElement.scrollTop=document.documentElement.scrollTop+t.bottom-a)}}getRowsToRender(){return!1===this.options.paging.enabled?Promise.resolve(this.dataTable.getCachedRows()):this.dataTable.getRows({offset:(this.pagination.page-1)*this.pagination.pageSize,limit:this.pagination.pageSize+1}).catch((t=>(console.error(t),[])))}renderFooter(){this.footerDiv=z("div").addClass(`${this.cssPrefix}-footer`).toDOM(),this.rowsOnPagePromise&&this.rowsOnPagePromise.then((t=>{this.footerDiv.innerHTML="",this.footerPaginateDiv=this.renderPageNavigator(),this.footerDiv.appendChild(this.footerPaginateDiv);const e=this.renderPageInfoBlock(t);this.footerDiv.appendChild(e)}))}renderPageInfoBlock(t){const e=z("div").addClass(`${this.cssPrefix}-page-info`).toDOM();if(this.dataTable.getTotal()>0){const i=t?(this.pagination.page-1)*this.pagination.pageSize+1:0,s=t?i+t-1:0;let n=this.dataTable.getTotal().toString();this.dataTable.elasticChunks&&this.dataTable.getCachedCount()!==this.dataTable.getTotal()&&(n="?"),e.innerHTML=k.getText("GridPageInfo").replace("{FirstPageRecordNum}",`<span>${i.toString()}</span>`).replace("{LastPageRecordNum}",`<span>${s.toString()}</span>`).replace("{Total}",`<span>${n}</span>`)}return e}showProgress(){}hideProgress(){}getLocalIndexByGlobal(t){return this.pagination?t%this.pagination.pageSize:t}getGlobalIndexByLocal(t){return this.pagination?(this.pagination.page-1)*this.pagination.pageSize+t:t}renderRow(t,e){let i=this.getGlobalIndexByLocal(e),s=z("div").addClass(`${this.cssPrefix}-row`).addClass(`${this.cssPrefix}-row-${e%2==1?"odd":"even"}`).data("row-idx",`${i}`).attr("tabindex","-1").on("click",(i=>{this.activeRowIndex=e,this.fireEvent({type:"rowClick",row:t,rowIndex:e,sourceEvent:i})})).on("dblclick",(i=>{this.fireEvent({type:"rowDbClick",row:t,rowIndex:e,sourceEvent:i})}));0==e&&s.addClass(`${this.cssPrefix}-row-first`);let n=s.toDOM();return this.options.showActiveRow&&e==this.activeRowIndex&&s.addClass(`${this.cssPrefix}-row-active`),this.columns.getItems().forEach(((e,s)=>{if(!e.isVisible)return;const o=e.isRowNum?-1:this.dataTable.columns.getIndex(e.dataColumn.id);let a=e.isRowNum?i+1:t.getValue(o);n.appendChild(this.renderCell(e,s,a,n))})),n}renderCell(t,e,i,s){const n=z("div").addClass(`${this.cssPrefix}-cell`).data("col-idx",`${e}`).attr("tabindex","-1").setStyle("width",`${t.width}px`);t.align==J.LEFT?n.addClass(`${this.cssPrefix}-cell-align-left`):t.align==J.RIGHT?n.addClass(`${this.cssPrefix}-cell-align-right`):t.align==J.CENTER&&n.addClass(`${this.cssPrefix}-cell-align-center`);const o=n.toDOM(),a=o.appendChild(z("div").addClass(`${this.cssPrefix}-cell-value`).toDOM()),r=this.getCellRenderer(t);return r&&r(i,t,a,s),o}getCellRenderer(t){let e;return e=t.isRowNum?this.cellRendererStore.getDefaultRendererByType(et.NUMBER):this.cellRendererStore.getDefaultRenderer(t.type),this.options&&this.options.onGetCellRenderer&&(e=this.options.onGetCellRenderer(t,e)||e),e}setPage(t){this.pagination.page=t,this.fireEvent({type:"pageChanged",page:t}),this.refresh(),this.bodyViewportDiv.focus()}renderPageNavigator(){let t=document.createElement("div");t.className=`${this.cssPrefix}-pagination-wrapper`;const e=this.dataTable.getTotal();if(this.options.paging&&this.options.paging.enabled&&e>0){const e=this.paginationOptions.useBootstrap?"":`${this.cssPrefix}-`,i=t=>{const e=t.target;if(e.hasAttribute("data-page")){const t=parseInt(e.getAttribute("data-page"));this.setPage(t)}},s=(t,s,n,o,a)=>{const r=document.createElement("li");if(r.className=`${e}page-item`,!o){a&&(r.className+=" active");const n=document.createElement("a");return n.setAttribute("href","javascript:void(0)"),n.innerHTML=s||t.toString(),n.setAttribute("data-page",`${t}`),n.className=`${e}page-link`,n.addEventListener("click",i),r.appendChild(n),r}let l=document.createElement("span");if(l.setAttribute("aria-hidden","true"),l.className=`${e}page-link`,n)r.className+=" disabled";else{if(this.paginationOptions.useBootstrap)l=document.createElement("a"),l.setAttribute("href","javascript:void(0)"),l.setAttribute("data-page",`${t}`);else{let e=document.createElement("a");e.setAttribute("href","javascript:void(0)"),e.setAttribute("data-page",`${t}`),l=e}l.className=`${e}page-link`,l.addEventListener("click",i)}return l.innerHTML=s,r.appendChild(l),r};if(this.dataTable.elasticChunks){const i=this.pagination.page||1;let n=document.createElement("ul");n.className=`${e}pagination`;let o=s(i-1,"«",1==i,!0,!1);n.appendChild(o),o=s(i+1,"»",this.isLastPage(),!0,!1),n.appendChild(o),t.appendChild(n)}else if(this.pagination.total>this.pagination.pageSize){const i=this.pagination.page||1,n=Math.ceil(this.pagination.total/this.pagination.pageSize)||1,o=this.paginationOptions.maxButtonCount||10,a=i-1;let r=a-a%o+1,l=r+o-1;l>n&&(l=n);let d=document.createElement("ul");d.className=`${e}pagination`;let h=s(r-1,"«",1==r,!0,!1);d.appendChild(h);for(let t=r;t<=l;t++)h=s(t,t.toString(),!1,!1,t==i),d.appendChild(h);h=s(l+1,"»",l==n,!0,!1),d.appendChild(h),t.appendChild(d)}if(this.options.paging.allowPageSizeChange){const e=t=>{const e=parseInt(t.target.value);this.pagination.pageSize=e,this.pagination.page=1,this.refresh()},i=document.createElement("div");i.className=`${this.cssPrefix}-page-sizes`;const s=document.createElement("div");s.className=`kfrm-select ${this.cssPrefix}-page-sizes-select`,i.appendChild(s);const n=document.createElement("select"),o=this.options.paging.pageSizeItems||[],a=new Set(o);a.add(this.options.paging.pageSize||20),Array.from(a).forEach((t=>{const e=document.createElement("option");e.value=t.toString(),e.text=t.toString(),n.appendChild(e)})),n.value=(this.pagination.pageSize||20).toString(),s.appendChild(n),n.addEventListener("change",e);const r=document.createElement("div");r.className=`${this.cssPrefix}-page-sizes-label`,i.appendChild(r);const l=document.createElement("span");l.innerText=k.getText("GridItemsPerPage"),r.appendChild(l),t.appendChild(i)}}return t}addEventListener(t,e){return this.eventEmitter.subscribe(t,(t=>e(t.data)))}removeEventListener(t,e){this.eventEmitter.unsubscribe(t,e)}renderHeaderButtons(){return this.options.showPlusButton?z("div").addClass(`${this.cssPrefix}-header-btn-plus`).title(this.options.plusButtonTitle||"Add").addChild("a",(t=>t.attr("href","javascript:void(0)").on("click",(t=>{t.preventDefault(),this.fireEvent({type:"plusButtonClick",sourceEvent:t})})))).toDOM():z("span").addText("#").toDOM()}showLandingSlot(t,e){const i=this.headerRowDiv.querySelectorAll(`[class*=${this.cssPrefix}-table-col]`),s=[];for(let t=1;t<i.length;t++){const e=i[t];"none"!==e.style.display&&s.push(e)}if(0===s.length)return this.landingIndex=0,void this.headerRowDiv.appendChild(this.landingSlot);const n=$(this.landingSlot);if(t>=n.x&&t<=n.x+this.landingSlot.offsetWidth)return;let o=this.landingIndex;for(let e of s){const i=$(e),s=e.offsetWidth;t>i.x&&t<i.x+s&&(o=parseInt(e.getAttribute("data-col-idx"))-1)}o!=this.landingIndex&&(this.landingIndex=o,this.landingIndex<s.length?this.headerRowDiv.insertBefore(this.landingSlot,s[this.landingIndex]):this.headerRowDiv.appendChild(this.landingSlot))}hideLandingSlot(){this.landingIndex=-1,setTimeout((()=>{this.landingSlot.parentElement&&this.landingSlot.parentElement.removeChild(this.landingSlot)}),10)}get activeRowIndex(){return this._activeRowIndex}set activeRowIndex(t){if(t!==this._activeRowIndex){const e=this._activeRowIndex;this._activeRowIndex=t,this.updateActiveRow(),this.fireEvent({type:"activeRowChanged",oldValue:e,newValue:this.activeRowIndex,rowIndex:this.getGlobalIndexByLocal(this.activeRowIndex)})}}updateActiveRow(){if(this.options.showActiveRow){this.bodyCellContainerDiv.querySelectorAll(`[class*=${this.cssPrefix}-row-active]`).forEach((t=>{t.classList.remove(`${this.cssPrefix}-row-active`)}));const t=this.getActiveRow();t&&(t.classList.add(`${this.cssPrefix}-row-active`),this.ensureRowVisibility(this.activeRowIndex))}}getActiveRow(){return this.getDataRow(this.activeRowIndex)}getDataRow(t){const e=Array.from(this.bodyCellContainerDiv.querySelectorAll(`.${this.cssPrefix}-row:not(.${this.cssPrefix}-row-totals)`));return t>=0&&t<e.length?e[t]:null}focus(){this.bodyViewportDiv.focus()}resizeColumns(){if(this.options.columnWidths.autoResize===K.Never)return;const t=this.bodyCellContainerDiv.style.width;this.bodyCellContainerDiv.style.visibility="hidden",this.bodyCellContainerDiv.style.width="1px",this.headerRowDiv.style.width="1px";let e=0;const i=this.columns.getItems(),s=this.headerCellContainerDiv.querySelectorAll(`.${this.cssPrefix}-header-cell`);let n=0;for(let t=0;t<this.columns.count;t++){const o=i[t];if(!o.isVisible)continue;const a=this.options.columnWidths.autoResize!==K.Always&&o.dataColumn?o.dataColumn.calculatedWidth:0,r=this.bodyCellContainerDiv.querySelectorAll(`.${this.cssPrefix}-cell[data-col-idx="${t}"] > .${this.cssPrefix}-cell-value`);let l=0;if(a>0)e+=a,o.width=a,r.forEach((t=>{t.parentElement.style.width=`${a}px`})),s[n].style.width=`${a}px`;else if(0==r.length&&(s[n].style.width=null,s[n].style.whiteSpace="nowrap"),l=s[n].offsetWidth,r.length>0){r.forEach((t=>{t.parentElement.style.width=null;const e=t.parentElement.offsetWidth;e>l&&(l=e)})),l+=3;const t=o.isRowNum?this.options.columnWidths.rowNumColumn.max||500:this.options.columnWidths[o.dataColumn.type].max||2e3,i=o.isRowNum?this.options.columnWidths.rowNumColumn.min||0:this.options.columnWidths[o.dataColumn.type].min||20;l>t&&(l=t),l<i&&(l=i),R.isNumericType(o.type)&&(l=Math.round(1.3*l)),e+=l,o.width=l,r.forEach((t=>{t.parentElement.style.width=`${l}px`})),s[n].style.width=`${l}px`,o.dataColumn&&(o.dataColumn.calculatedWidth=l)}else e+=l;n++}e>0?(this.bodyCellContainerDiv.style.width=`${e}px`,this.headerCellContainerDiv.style.width=`${e}px`):(this.bodyCellContainerDiv.style.width=t,this.headerCellContainerDiv.style.width=t),this.bodyCellContainerDiv.style.visibility=null,this.headerRowDiv.removeAttribute("style")}}class lt{get cssPrefix(){return"kdtp-cal"}constructor(t,e){this.slot=t,this.options=e||{},this.options.yearRange||(this.options.yearRange="c-10:c+10")}setDate(t){this.currentDate=new Date(t)}getDate(){return new Date(this.currentDate)}dateChanged(t){this.options.onDateChanged&&this.options.onDateChanged(this.currentDate,t)}}class dt{get cssPrefix(){return"kdtp"}constructor(t){this.calendar=null,this.timePicker=null,this.options=t,this.render()}setDateTime(t){this.currentDateTime=new Date(t),this.calendar&&this.calendar.setDate(this.currentDateTime),this.timePicker&&this.timePicker.setTime(this.currentDateTime)}getDateTime(){return new Date(this.currentDateTime)}render(){this.options.showCalendar&&(this.calendar=this.createCalendar({yearRange:this.options.yearRange,showDateTimeInput:this.options.showDateTimeInput,timePickerIsUsed:this.options.showTimePicker,oneClickDateSelection:this.options.oneClickDateSelection,onDateChanged:(t,e)=>{this.currentDateTime=t,this.timePicker&&this.timePicker.setTime(this.currentDateTime),this.options.showTimePicker&&this.dateTimeChanged(),e&&this.apply(this.currentDateTime)}}),this.calendar&&this.calendar.render()),this.options.showTimePicker&&(this.timePicker=this.createTimePicker({onTimeChanged:t=>{this.currentDateTime.setHours(t.getHours()),this.currentDateTime.setMinutes(t.getMinutes()),this.calendar&&this.calendar.setDate(this.currentDateTime),this.dateTimeChanged()}}),this.timePicker&&this.timePicker.render()),this.setDateTime(new Date)}createCalendar(t){return null}createTimePicker(t){return null}show(t){this.options.beforeShow&&this.options.beforeShow();const e=$(t||document.body);this.slot.style.top=e.y+t.clientHeight+"px",this.slot.style.left=e.x+"px"}apply(t){this.options.onApply&&this.options.onApply(t),this.destroy()}cancel(){this.options.onCancel&&this.options.onCancel(),this.destroy()}destroy(){this.slot&&this.slot.parentElement&&this.slot.parentElement.removeChild(this.slot)}dateTimeChanged(){this.options.onDateTimeChanged&&this.options.onDateTimeChanged(this.currentDateTime)}}class ht extends lt{constructor(t,e){super(t,e),this.daysOfWeek=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],this.months=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],this.calendarBody=null,this.isManualInputChanging=!1;for(let t=0;t<this.daysOfWeek.length;t++)this.daysOfWeek[t]=k.getShortWeekDayName(t+1);for(let t=0;t<this.months.length;t++)this.months[t]=k.getLongMonthName(t+1)}setDate(t){super.setDate(t),this.selectedMonth=this.currentDate.getMonth(),this.selectedYear=this.currentDate.getFullYear(),this.rerenderMonth()}render(){const t=z("div",this.slot).addClass(`${this.cssPrefix}-header`);this.options.showDateTimeInput?t.addChildElement(this.renderManualDateInput()):t.addChild("span",(t=>this.headerTextElem=t.toDOM())),z(this.slot).addChildElement(this.renderCalendarButtons()),this.calendarBody=z("div",this.slot).addClass(`${this.cssPrefix}-body`).toDOM()}getInputDateFormat(){const t=k.getLocaleSettings();return this.options.timePickerIsUsed?`${t.editDateFormat} ${t.editTimeFormat}`:t.editDateFormat}renderManualDateInput(){const t=this.getInputDateFormat(),e=z("input").attr("placeholder",t).addClass(`${this.cssPrefix}-header-input`);return e.mask(t.replace("yyyy","9999").replace("MM","99").replace("dd","99").replace("HH","99").replace("mm","99").replace("ss","99")).on("input",(i=>{e.removeClass("error");try{this.isManualInputChanging=!0;const e=R.strToDateTime(this.manualInputElem.value,t);this.currentDate=e,this.jump(this.currentDate.getFullYear(),this.currentDate.getMonth()),this.dateChanged(!1)}catch(t){e.addClass("error")}finally{this.isManualInputChanging=!1}})).on("keydown",(t=>{13===t.keyCode&&(t.preventDefault(),t.stopPropagation(),this.manualInputElem.className.indexOf("error")<0&&!this.isManualInputChanging&&this.dateChanged(!0))})).on("focus",(()=>{setTimeout((()=>{this.manualInputElem.selectionStart=0,this.manualInputElem.selectionEnd=0}),50)})),this.manualInputElem=e.toDOM(),this.manualInputElem}updateDisplayedDateValue(){if(this.manualInputElem){if(!this.isManualInputChanging){const t=this.getInputDateFormat();this.manualInputElem.value=k.dateTimeToStr(this.currentDate,t),this.manualInputElem.focus()}}else if(this.headerTextElem){const t=k.getCurrentLocale();this.headerTextElem.innerText=this.currentDate.toLocaleString("en"==t?void 0:t,{year:"numeric",month:"long",day:"numeric"})}}renderCalendarButtons(){return z("nav").addClass(`${this.cssPrefix}-nav`).addChild("div",(t=>t.addClass(`${this.cssPrefix}-nav-prev`).on("click",(()=>{this.prev()})).addChild("span",(t=>t.html("‹"))))).addChild("div",(t=>t.addClass(`${this.cssPrefix}-nav-selectors`).addChild("div",(t=>t.addClass(`${this.cssPrefix}-nav-month`).addChild("select",(t=>{t.on("change",(()=>{this.jump(this.selectedYear,parseInt(this.selectMonthElem.value))}));for(let e=0;e<this.months.length;e++)t.addChild("option",(t=>t.attr("value",e.toString()).text(this.months[e])));this.selectMonthElem=t.toDOM()})))).addChild("div",(t=>t.addClass(`${this.cssPrefix}-nav-year`).addChild("select",(t=>this.selectYearElem=t.on("change",(()=>{this.jump(parseInt(this.selectYearElem.value),this.selectedMonth)})).toDOM())))))).addChild("div",(t=>t.addClass(`${this.cssPrefix}-nav-next`).on("click",(()=>{this.next()})).addChild("span",(t=>t.html("›"))))).toDOM()}prev(){this.selectedYear=0===this.selectedMonth?this.selectedYear-1:this.selectedYear,this.selectedMonth=0===this.selectedMonth?11:this.selectedMonth-1,this.rerenderMonth()}next(){this.selectedYear=11===this.selectedMonth?this.selectedYear+1:this.selectedYear,this.selectedMonth=(this.selectedMonth+1)%12,this.rerenderMonth()}rerenderSelectYear(){const t=/c-(\d*):c\+(\d*)/g.exec(this.options.yearRange);let e=0,i=1;null!==t&&(e=parseInt(t[1]),i=parseInt(t[2])),this.selectYearElem.innerHTML="";for(let t=0;t<=e+i;t++){let i=document.createElement("option"),s=this.selectedYear-e+t;i.value=s.toString(),i.innerText=s.toString(),this.selectYearElem.appendChild(i)}}jump(t,e){this.selectedYear=t,this.selectedMonth=e,this.rerenderMonth()}rerenderMonth(){this.updateDisplayedDateValue(),this.rerenderSelectYear();let t=new Date(this.selectedYear,this.selectedMonth).getDay(),e=new Date(this.selectedYear,this.selectedMonth+1,0).getDate();this.calendarBody.innerHTML="",this.selectYearElem.value=this.selectedYear.toString(),this.selectMonthElem.value=this.selectedMonth.toString(),this.daysOfWeek.forEach(((t,e)=>{z("div",this.calendarBody).addClass(`${this.cssPrefix}-weekday`).addClass(0==e||6==e?`${this.cssPrefix}-weekend`:"").text(t)}));for(let e=0;e<t;e++)z("div",this.calendarBody).addClass(`${this.cssPrefix}-day-empty`);const i=new Date;for(let s=1;s<=e;s++){const e=z("div",this.calendarBody).addClass(`${this.cssPrefix}-day`).attr("data-date",s.toString()).text(s.toString()).on("click",(t=>{this.currentDate.setFullYear(this.selectedYear),this.currentDate.setMonth(this.selectedMonth),this.currentDate.setDate(parseInt(t.target.getAttribute("data-date"))),this.dateChanged(this.options.oneClickDateSelection)}));s===i.getDate()&&this.selectedYear===i.getFullYear()&&this.selectedMonth===i.getMonth()&&e.addClass(`${this.cssPrefix}-day-current`),s===this.currentDate.getDate()&&this.selectedYear===this.currentDate.getFullYear()&&this.selectedMonth===this.currentDate.getMonth()&&e.addClass(`${this.cssPrefix}-day-selected`);const n=(t+s-1)%7;0!=n&&6!=n||e.addClass(`${this.cssPrefix}-weekend`),"function"==typeof this.options.onDrawDay&&this.options.onDrawDay.apply(e.toDOM(),[e.toDOM(),new Date(this.selectedYear,this.selectedMonth,s)])}const s=(t+e)%7,n=0==s?0:7-s;for(let t=0;t<n;t++)z("div",this.calendarBody).addClass(`${this.cssPrefix}-day-empty`)}dateChanged(t){super.dateChanged(t),this.rerenderMonth()}}class ct{get cssPrefix(){return"kdtp-tp"}constructor(t,e){this.slot=t,this.options=e||{}}setTime(t){this.currentTime=new Date(t)}getTime(){return new Date(this.currentTime)}timeChanged(){this.options.onTimeChanged&&this.options.onTimeChanged(this.currentTime)}}class ut extends ct{setTime(t){super.setTime(t),this.updateDisplayedTime(),this.hoursInput.valueAsNumber=t.getHours(),this.minutesInput.valueAsNumber=t.getMinutes()}render(){z("div",this.slot).addClass(`${this.cssPrefix}-time`).addChild("span",(t=>this.timeText=t.toDOM())).toDOM();const t=z("div",this.slot).addClass(`${this.cssPrefix}-sliders`);return t.addChild("div",(t=>t.addClass(`${this.cssPrefix}-time-row`).title("Hours").addChild("input",(t=>this.hoursInput=t.addClass(`${this.cssPrefix}-input-hours`).type("range").attr("min","0").attr("max","23").attr("step","1").on("input",(t=>{this.currentTime.setHours(this.hoursInput.valueAsNumber),this.updateDisplayedTime(),this.timeChanged()})).toDOM())))),t.addChild("div",(t=>t.addClass(`${this.cssPrefix}-time-row`).title("Minutes").addChild("input",(t=>this.minutesInput=t.addClass(`${this.cssPrefix}-input-minutes`).type("range").attr("min","0").attr("max","59").attr("step","1").on("input",(t=>{this.currentTime.setMinutes(this.minutesInput.valueAsNumber),this.updateDisplayedTime(),this.timeChanged()})).toDOM())))),this.slot}updateDisplayedTime(){const t=k.getCurrentLocale(),e=this.currentTime.toLocaleString("en"==t?void 0:t,{hour:"numeric",minute:"numeric"});this.timeText.innerText=e}}class pt extends dt{render(){const t=z("div",document.body).addClass(`${this.cssPrefix}`).attr("tabIndex","0").setStyle("position","absolute").setStyle("top","-1000px").setStyle("left","-1000px").on("keydown",(t=>(27===t.keyCode?this.cancel():13===t.keyCode&&this.apply(this.getDateTime()),!1)));this.options.zIndex&&t.setStyle("z-index",`${this.options.zIndex}`),this.slot=t.toDOM(),super.render(),this.renderButtons(),this.globalMouseDownHandler=t=>{let e=window.event||t;return e.srcElement||e.target,!this.slot.contains(e.target)&&(document.removeEventListener("mousedown",this.globalMouseDownHandler,!0),this.cancel()),!0}}renderButtons(){const t=z("div",this.slot).addClass(`${this.cssPrefix}-buttons`).addChild("button",(t=>this.nowButton=t.addClass(`${this.cssPrefix}-button ${this.cssPrefix}-button-now`).text(k.getText("ButtonNow")).on("click",(()=>(this.setDateTime(new Date),this.dateTimeChanged(),!1))).toDOM()));!this.options.showTimePicker&&this.options.oneClickDateSelection||t.addChild("button",(t=>this.submitButton=t.addClass(`${this.cssPrefix}-button ${this.cssPrefix}-button-apply`).text(k.getText("ButtonApply")).on("click",(()=>(this.apply(this.getDateTime()),!1))).toDOM())),t.addChild("button",(t=>this.submitButton=t.addClass(`${this.cssPrefix}-button ${this.cssPrefix}-button-cancel`).text(k.getText("ButtonCancel")).on("click",(()=>(this.cancel(),!1))).toDOM()))}createCalendar(t){return this.calendarSlot=z("div",this.slot).addClass(`${this.cssPrefix}-cal`).toDOM(),new ht(this.calendarSlot,t)}createTimePicker(t){return this.timePickerSlot=z("div",this.slot).addClass(`${this.cssPrefix}-tp`).toDOM(),new ut(this.timePickerSlot,t)}show(t){if(this.options.showDateTimeInput){this.options.beforeShow&&this.options.beforeShow();const e=$(t||document.body),i=$(t?t.parentElement||t:document.body);this.slot.style.top=i.y+"px",this.slot.style.left=e.x+"px"}else super.show(t),this.slot.focus();setTimeout((()=>{document.addEventListener("mousedown",this.globalMouseDownHandler,!0)}),1)}}var gt;!function(t){t[t.Left=1]="Left",t[t.Center=2]="Center",t[t.Right=3]="Right"}(gt||(gt={}));const mt="kdlg";class ft{openConfirm(t,e,i){const s={title:t,closable:!1,submitable:!0,cancelable:!0,body:`<div id="${mt}-dialog-confirm">${e}</div>`};return i?(s.onSubmit=()=>{i(!0)},s.onCancel=()=>{i(!1)},void this.open(s)):new Promise((t=>{s.onSubmit=()=>{t(!0)},s.onCancel=()=>{t(!1)},this.open(s)}))}openPrompt(t,e,i,s){const n={title:t,submitable:!0,closable:!0,cancelable:!0,submitOnEnter:!0,body:`<div id="${mt}-dialog-form" class="kfrm-form">\n <div class="kfrm-fields label-above">\n <label for="${mt}-dialog-form-input" id="${mt}-dialog-form-content">${e}</label>\n <input type="text" name="${mt}-dialog-form-input" id="${mt}-dialog-form-input" />\n </div>\n </div>`,arrangeParents:!1,beforeOpen:()=>{const t=document.getElementById(`${mt}-dialog-form-input`);i&&(t.value=i),t.focus()}},o=t=>{const e=document.getElementById(`${mt}-dialog-form-input`),i=e.value;return i&&i.replace(/\s/g,"").length>0?(t(i),!0):(e.classList.add("eqjs-invalid"),!1)};return s?(n.onSubmit=()=>o(s),n.onCancel=()=>{s("")},void this.open(n)):new Promise((t=>{n.onSubmit=()=>o(t),n.onCancel=()=>{t("")},this.open(n)}))}open(t,e){const i=new yt(t,e),s=t.onDestroy;return t.onDestroy=t=>{this.untrack(t),s&&s(t)},i.open(),this.track(i),i}createSet(t){return new vt(t,this)}untrack(t){const e=ft.openDialogs.indexOf(t);e>=0&&ft.openDialogs.splice(e,1)}track(t){ft.openDialogs.push(t)}openProgress(t){const e=new Dt(t),i=t.onDestroy;return t.onDestroy=t=>{this.untrack(t),i&&i(t)},e.open(),this.track(e),e}getAllDialogs(){return Array.from(ft.openDialogs)}closeAllDialogs(){for(const t of Array.from(ft.openDialogs))t.close()}}ft.openDialogs=[];class yt{constructor(t,e){this.options=t,this.submitHandler=t=>!(this.options.onSubmit&&!1===this.options.onSubmit(this,t)||(this.destroy(),0)),this.cancelHandler=()=>{this.options.onCancel&&this.options.onCancel(this),this.destroy()},this.keydownHandler=t=>13!=t.keyCode||!this.isActiveDialog()||(t.preventDefault(),t.stopPropagation(),!this.submitHandler())||(window.removeEventListener("keydown",this.keydownHandler,!1),!1),this.dialogId=R.generateId("dlg"),this.data=e,this.slot=z("div",document.body).attr("tab-index","-1").data("dialog-id",this.dialogId).addClass(`${mt}-modal`,"is-active").focus().addChild("div",(t=>t.addClass("kdlg-modal-background"))).addChild("div",(i=>this.windowElement=i.addClass(`${mt}-modal-window`).addChild("header",(e=>{this.headerElement=e.addClass(`${mt}-header`).addChild("p",(e=>e.addClass(`${mt}-header-title`).addText(t.title))).toDOM(),!1!==t.closable&&e.addChild("button",(t=>t.addClass(`${mt}-modal-close`).on("click",(()=>{this.cancelHandler()})).focus()))})).addChild("div",(t=>{t.addClass(`${mt}-alert-container`),this.alertElement=t.toDOM()})).addChild("section",(i=>{if(this.bodyElement=i.addClass(`${mt}-body`).toDOM(),"string"==typeof t.body){const s=P.renderLiquidTemplate(t.body,e);i.addHtml(s)}else i.addChildElement(t.body)})).addChild("footer",(e=>{let i=null;i=t.footerAlignment&&t.footerAlignment==gt.Center?"align-center":"align-right",this.footerElement=e.addClass(`${mt}-footer`).toDOM(),e.addClass(i),!1!==t.submitable&&(e.addChild("button",(e=>{e.id(this.dialogId+"-btn-submit").addClass("kfrm-button","is-info").addText(t.submitButtonText||k.getText("ButtonOK")),t.recaptchaSiteKey?(e.data("sitekey",t.recaptchaSiteKey),e.addClass("g-recaptcha"),e.on("click",(e=>{grecaptcha?grecaptcha.ready((()=>{grecaptcha.execute(t.recaptchaSiteKey,{action:"submit"}).then((t=>{this.submitHandler(t)}))})):this.submitHandler()}))):e.on("click",(t=>{this.submitHandler()})),e.focus()})),!1!==t.cancelable&&e.addChild("button",(e=>e.id(this.dialogId+"-btn-cancel").addClass("kfrm-button").addText(t.cancelButtonText||k.getText("ButtonCancel")).on("click",(t=>{this.cancelHandler()})))))})).toDOM())).toDOM()}getData(){return this.data}getRootElement(){return this.slot}getSubmitButtonElement(){return document.getElementById(this.dialogId+"-btn-submit")}getCancelButtonElement(){return document.getElementById(this.dialogId+"-btn-cancel")}open(){this.options.beforeOpen&&this.options.beforeOpen(this),z(this.slot).show(),this.options.arrangeParents&&this.arrangeParents(!0);const t=this.slot.querySelector(`.${mt}-modal-window`);this.options.height&&(t.style.height="string"==typeof this.options.height?this.options.height:`${this.options.height}px`),this.options.width&&(t.style.width="string"==typeof this.options.width?this.options.width:`${this.options.width}px`),this.options.submitOnEnter&&window.addEventListener("keydown",this.keydownHandler,!1),this.slot.querySelectorAll("input").forEach((t=>t.addEventListener("input",(()=>{this.clearAlert(),this.options.onInput&&this.options.onInput(this)})))),this.options.onShow&&this.options.onShow(this)}submit(){this.submitHandler()}cancel(){this.cancelHandler()}close(){this.destroy()}disableButtons(){this.slot.querySelectorAll("button").forEach((t=>t.disabled=!0))}enableButtons(){this.slot.querySelectorAll("button").forEach((t=>t.disabled=!1))}showAlert(t,e,i){let s=z("div").addClass(`${mt}-alert ${e||""}`).addChild("span",(t=>t.addClass(`${mt}-alert-closebtn`).text("×").on("click",(t=>{const e=t.target.parentElement;e.parentElement.removeChild(e)})))).addText(t).toDOM();!0===i&&this.clearAlert(),this.alertElement.appendChild(s)}clearAlert(){this.alertElement.innerHTML=""}destroy(){document.querySelectorAll(`[data-dialog-id="${this.dialogId}"]`).length<=0||(this.options.arrangeParents&&this.arrangeParents(!1),document.body.removeChild(this.slot),this.options.submitOnEnter&&window.removeEventListener("keydown",this.keydownHandler,!1),this.options.onDestroy&&this.options.onDestroy(this))}isActiveDialog(){const t=document.documentElement.querySelectorAll(".kdlg-modal");return t[t.length-1]===this.slot}arrangeParents(t){const e=document.documentElement.querySelectorAll(".kdlg-modal-window");for(let i=0;i<e.length-1;i++)if(t){const t=0==i?20:40*i+20;z(e[i]).setStyle("margin-top",`${t}px`).setStyle("margin-left",`${t}px`)}else z(e[i]).removeStyle("margin-top").removeStyle("margin-left")}}class Dt extends yt{constructor(t,e){let i,s;const n=z("div").addChild("div",(e=>i=e.text(t.content||"").toDOM())).addChild("div",(e=>{e.addClass(`${mt}-progress-line`).addChild("div",(e=>{s=e.addClass("fill").toDOM(),t.determinated?e.setStyle("width","0%"):e.addClass("indeterminate")}))})).toDOM();super({title:t.title,body:n,beforeOpen:t.beforeOpen,onSubmit:t.onSubmit,width:t.width,height:t.height,submitable:!1,cancelable:!1,closable:!1,onDestroy:t.onDestroy},e),this.contentElement=i,this.progressElement=s}updateContent(t){this.contentElement.innerText=t}updateProgress(t){t=this.in01(t),this.progressElement.style.width=100*t+"%",1===t&&setTimeout((()=>{this.submit()}),500)}in01(t){return t>1?1:t<0?0:t}}class vt{constructor(t,e){this.options=t,this.dialogService=e,this.currentDialog=null,this.currentIndex=0,this.options=t,this.dialogService=e}getCurrent(){return this.currentDialog}openNext(t){return this.open(this.currentIndex+1,t)}openPrev(t){return this.open(this.currentIndex-1,t)}open(t,e){if(t<0?this.currentIndex=0:t>=this.options.length?this.currentIndex=this.options.length-1:this.currentIndex=t,this.currentDialog)try{this.currentDialog.close()}catch(t){}const i=this.options[this.currentIndex];return this.currentDialog=this.dialogService.open(i,e),this.currentDialog}close(){this.currentDialog&&(this.currentDialog.close(),this.currentDialog=null)}}var Ct,wt;k.updateDefaultTexts({GridPageInfo:"{FirstPageRecordNum} - {LastPageRecordNum} of {Total} records",GridItemsPerPage:"items per page",ButtonOK:"OK",ButtonCancel:"Cancel",ButtonApply:"Apply",ButtonNow:"Now",LblTotal:"Total"}),function(t){t[t.THIS_WEEK=0]="THIS_WEEK",t[t.LAST_WEEK=1]="LAST_WEEK",t[t.THIS_MONTH=2]="THIS_MONTH",t[t.FIRST_MONTH=3]="FIRST_MONTH",t[t.LAST_MONTH=4]="LAST_MONTH",t[t.THIS_YEAR=5]="THIS_YEAR",t[t.QUARTER_1=6]="QUARTER_1",t[t.QUARTER_2=7]="QUARTER_2",t[t.QUARTER_3=8]="QUARTER_3",t[t.QUARTER_4=9]="QUARTER_4"}(Ct||(Ct={})),function(t){t.UNDEF="-1",t.TODAY="1",t.YESTERDAY="2",t.TOMORROW="3",t.WEEK_START="4",t.WEEK_END="5",t.MONTH_START="6",t.MONTH_END="7",t.YEAR_START="8",t.YEAR_END="9"}(wt||(wt={}));const Tt="yyyy-MM-dd",bt="HH:mm",xt=e=>{const i=d.getLocaleSettings();return e==t.Date?i.editDateFormat:e==t.Time?i.editTimeFormat:`${i.editDateFormat} ${i.editTimeFormat}`},Et=t=>{const e=window.history.state;history.pushState(e,document.title,t),window.dispatchEvent(new Event("ed_set_location"))};class It{}class St extends It{constructor(){super(),this.name="DateTime"}validate(t,e){if(!l.IsDefinedAndNotNull(e)||""==e)return{successed:!0};if(l.getDateDataTypes().indexOf(t.dataType)>=0)try{const i=xt(t.dataType);l.strToDateTime(e,i)}catch(t){return{successed:!1,messages:[d.getText("DateTimeError")]}}return{successed:!0}}}class Mt{constructor(t){this.context=t,this.validators=[new St]}getHtml(){return this.html}setHtmlInt(t){this.html=t,this.errorsDiv=this.html.querySelector(".errors-block")}validate(){this.clearErrors();const t=Array.from(this.html.querySelectorAll("input, select"));let e=!0;for(const i of t){const t=this.context.getMetaData().getAttributeById(i.name);if("checkbox"===i.type)continue;const s=this.validateValue(t,i.value);if(!s.successed){e&&z(this.errorsDiv).addChild("ul"),e=!1;for(const e of s.messages)this.errorsDiv.firstElementChild.innerHTML+=`<li>${t.caption}: ${e}</li>`}this.markInputValid(i,s.successed)}return e}getData(){return new Promise(((t,e)=>{const i=[],s=Array.from(this.html.querySelectorAll("input, select, textarea"));let n={};for(const t of s){const e=t.name.substring(t.name.lastIndexOf(".")+1),s=this.context.getMetaData().getAttributeById(t.name);"checkbox"===t.type?n[e]=t.checked:"file"===t.type?i.push(this.fileToBase64(t.files[0]).then((t=>n[e]=t))):n[e]=this.mapValue(s.dataType,t.value)}Promise.all(i).then((()=>t(n))).catch((t=>e(t)))}))}fileToBase64(t){return new Promise(((e,i)=>{const s=new FileReader;s.readAsDataURL(t),s.onload=()=>{const t=s.result.toString();e(t.substring(t.indexOf(",")+1))},s.onerror=t=>i(t)}))}useValidator(...t){this.useValidators(t)}useValidators(t){this.validators=this.validators.concat(t)}mapValue(e,i){if(l.getDateDataTypes().indexOf(e)>=0){if(e!==t.Time&&i&&i.length){const n=xt(e),o=(s=e)==t.Date?Tt:s==t.Time?bt:`${Tt}T${bt}`,a=l.strToDateTime(i,n);return d.dateTimeToStr(a,o)}return i&&i.length?i:null}var s;return l.isIntType(e)?parseInt(i):l.isNumericType(e)?parseFloat(i):i}clearErrors(){this.errorsDiv.innerHTML="",this.html.querySelectorAll("input, select").forEach((t=>{t.classList.remove("is-valid"),t.classList.remove("is-invalid")}))}markInputValid(t,e){t.classList.add(e?"is-valid":"is-invalid")}validateValue(t,e){const i={successed:!0,messages:[]};for(const s of this.validators){const n=s.validate(t,e);n.successed||(i.successed=!1,i.messages=i.messages.concat(n.messages))}return i}}class Rt{constructor(t,e,i,s){this.slot=t,this.grid=e,this.filter=i,this.options={focus:!1,instantMode:!1,instantTimeout:1e3},this.options=l.assignDeep(this.options,s||{});const n=this.grid.cellRendererStore.getDefaultRendererByType(et.STRING);this.grid.cellRendererStore.setDefaultRenderer(et.STRING,((t,e,i,s)=>this.highlightCellRenderer(n,t,e,i,s)));const o=this.grid.cellRendererStore.getDefaultRendererByType(et.NUMBER);this.grid.cellRendererStore.setDefaultRenderer(et.NUMBER,((t,e,i,s)=>this.highlightCellRenderer(o,t,e,i,s))),this.render()}render(){const t=O.IsIE()?"kfrm-fields-ie is-horizontal":"kfrm-fields is-horizontal",e=O.IsIE()||O.IsEdge();z(this.slot).addClass(t).addChild("div",(t=>{t.addClass("control").addChild("input",(t=>{this.filterInput=t.toDOM(),t.attr("placeholder",d.getText("SearchInputPlaceholder")).type("text"),t.on("keydown",this.inputKeydownHandler.bind(this)),this.options.instantMode&&t.on("keyup",this.inputKeyupHandler.bind(this))})),e||t.addClass("has-icons-right").addChild("span",(t=>{t.addClass("icon").addClass("is-right").addClass("is-clickable").html("🗙").on("click",this.clearButtonClickHander.bind(this))}))})),this.options.instantMode||z(this.slot).addChild("button",(t=>t.addClass("kfrm-button").addText(d.getText("SearchBtn")).on("click",this.searchButtonClickHandler.bind(this)))),this.options.focus&&this.filterInput.focus()}inputKeydownHandler(t){13==t.keyCode&&this.applyFilter(!0)}inputKeyupHandler(){this.applyFilterTimeout&&clearTimeout(this.applyFilterTimeout),this.applyFilterTimeout=setTimeout((()=>{this.applyFilter(!0)}),this.options.instantTimeout)}clearButtonClickHander(){this.filterInput.value="",this.filterInput.focus(),this.applyFilter(!0)}searchButtonClickHandler(){this.applyFilter(!0)}applyFilter(t){this.applyFilterTimeout&&clearTimeout(this.applyFilterTimeout);const e=this.filter.getValue();return(!t||e!=this.filterInput.value)&&(this.filter.apply(this.filterInput.value).then((t=>{this.grid.setData(t)})),!0)}highlightCellRenderer(t,e,i,s,n){if((l.isNumericType(i.type)||l.getStringDataTypes().indexOf(i.type)>=0)&&e){e=i.dataColumn&&i.dataColumn.displayFormat&&tt.test(i.dataColumn.displayFormat)?i.dataColumn.displayFormat.replace(tt,((t,i)=>d.numberToStr(e,i))):e.toLocaleString();const t=this.highlightText(e.toString());if(t instanceof HTMLElement)return s.title=e,void s.appendChild(t)}t(e,i,s,n)}highlightText(t){const e=t.toLowerCase(),i=this.filter.getValue().toString();if(i&&i.length>0&&t&&t.length>0){const s=[],n=i.split("||").map((t=>t.trim().toLowerCase()));for(let i=0;i<n.length;i++){let o=0;const a=n[i];if(a.length){if(a===e){const e=document.createElement("span");return e.style.backgroundColor="yellow",e.innerText=t,e}for(;o<t.length-1;){const t=e.indexOf(a,o);t>=0?(s.push({index:t,length:n[i].length}),o=t+a.length):o++}}}if(s.length>0){s.sort(((t,e)=>t.index>e.index?1:t.index==e.index2?0:-1));for(let t=0;t<s.length-1;){const e=s[t+1].index-(s[t].index+s[t].length);if(e<0){const i=s[t+1].length+e;i>0&&(s[t].length+=i),s.splice(t+1,1)}else t++}const e=document.createElement("div");for(let i=0;i<s.length;i++){if(0===i){const n=document.createTextNode(t.substring(0,s[i].index));e.appendChild(n)}const n=document.createElement("span");n.style.backgroundColor="yellow",n.innerText=t.substring(s[i].index,s[i].index+s[i].length),e.appendChild(n);const o=i<s.length-1?document.createTextNode(t.substring(s[i].index+s[i].length,s[i+1].index)):document.createTextNode(t.substring(s[i].index+s[i].length));e.appendChild(o)}return e}}return t}}const kt=O.IsIE();class At{constructor(t,e){this.context=t,this.params=e,this.params=e||{},this.reset()}reset(){this.form=new Mt(this.context)}setupLookupField(t,e,i,s){const n=this.context.getMetaData().getRootEntity().subEntities.filter((t=>t.id==e.lookupEntity))[0],o=this.context.getMetaData().getAttributeById(e.dataAttr);if(!o)return;i=i||!o.isEditable,s=this.params.values?this.params.values.getValue(o.id):void 0;const a=kt?"kfrm-fields-ie is-horizontal":"kfrm-fields is-horizontal";let r;z(t).addChild("div",(t=>{t.addClass(a).addChild("input",(t=>{r=t.toDOM(),t.attr("readonly",""),t.name(o.id),t.type(this.resolveInputType(o.dataType)),t.value(l.IsDefinedAndNotNull(s)?s.toString():"")})),i||t.addChild("button",(t=>t.addClass("kfrm-button").attr("title",d.getText("NavigationBtnTitle")).addText("...").on("click",(i=>{const s=new b({loader:{loadChunk:t=>this.context.getDataLoader().loadChunk(Object.assign(Object.assign({},t),{id:n.id}))}});this.context.getDataLoader().loadChunk({offset:0,limit:1e3,needTotal:!0,sourceId:n.id}).then((i=>{for(const t of i.table.columns.getItems()){const e=n.attributes.filter((e=>e.id==t.id&&(e.isPrimaryKey||e.showInLookup)));e.length&&s.columns.add(t)}s.setTotal(i.total);for(const t of i.table.getCachedRows())s.addRow(t);const o=new ft;let a,l=null,h=null;const c=z("div").addClass("kfrm-form").addChild("div",(t=>t.addClass("kfrm-field").addChild("label",(t=>t.addText(d.getText("LookupSelectedItem")).toDOM())).addChild("div",(t=>h=t.addText("None").toDOM())))).addChild("div",(t=>a=t.toDOM())).addChild("div",(t=>t.addClass("kfrm-control").addChild("div",(t=>l=t.toDOM())))).toDOM();let u=r.value;const p=t=>{h.innerHTML=s.columns.getItems().map((e=>`<b>${e.label}:</b> ${((t,e)=>t instanceof T?t.getValue(e):t[e.substring(e.lastIndexOf(".")+1)])(t,e.id)}`)).join(", ")};if(u){const t=n.getFirstPrimaryAttr(),e=t.id.substring(t.id.lastIndexOf(".")+1);this.context.fetchRecord({[e]:u},n.id).then((t=>{t.entity&&p(t.entity)})).catch((t=>{console.error(t)}))}const g=new rt({slot:l,dataTable:s,fixHeightOnFirstRender:!0,paging:{pageSize:10},onActiveRowChanged:t=>{g.getData().getRow(t.rowIndex).then((t=>{u=t.getValue(e.lookupDataAttr),p(t)}))}});o.open({title:d.getText("LookupDlgCaption").replace("{entity}",n.caption),body:c,arrangeParents:!0,beforeOpen:()=>{const t=this.context.createFilter(n.id,g.getData(),!0);new Rt(a,g,t,{instantMode:!0,focus:!0})},onSubmit:()=>(r.value=u,!0),onDestroy:()=>{g.destroy(),t.toDOM().focus()}})}))}))))}))}setupDateTimeField(e,i,s,n,o){const a=kt?"kfrm-fields-ie is-horizontal":"kfrm-fields is-horizontal",r=xt(i.dataType);let h;const c=r.replace("yyyy","9999").replace("MM","99").replace("dd","99").replace("HH","99").replace("mm","99").replace("ss","99");z(e).addChild("div",(e=>{e.addClass(a).addChild("input",(t=>{h=t.toDOM(),t.name(i.id),t.type(o?"hidden":this.resolveInputType(i.dataType)),n?t.attr("readonly",""):(t.mask(c),t.on("keypress",(t=>this.applySumbit(t))).on("input",(e=>{t.removeClass("is-invalid");try{l.strToDateTime(h.value,r)}catch(e){t.addClass("is-invalid")}})).on("blur",(t=>{h.value===c.replace(/[9]/g,"_")&&(h.value="")}))),t.value(l.IsDefinedAndNotNull(s)?d.dateTimeToStr(s,r):"")})),n||e.addChild("button",(e=>e.addClass("kfrm-button").attr("title",d.getText(i.dataType!==t.Time?"CalendarBtnTitle":"TimerBtnTitle")).addChild("i",(e=>e.addClass(i.dataType!==t.Time?"ed-calendar-icon":"ed-timer-icon"))).on("click",(e=>{let s;try{s=h.value.length?i.dataType!==t.Time?l.strToDateTime(h.value,r):l.strToTime(h.value):new Date((new Date).setSeconds(0))}catch(t){s=new Date((new Date).setSeconds(0))}const n={zIndex:9999999999,showCalendar:i.dataType!==t.Time,showTimePicker:i.dataType!==t.Date,onApply:t=>{t.setSeconds(0),t.setMilliseconds(0),h.value=d.dateTimeToStr(t,r)}},o=new pt(n);o.setDateTime(s),o.show(e.target)})).toDOM()))}))}setupListField(t,e,i,s,n){z(t).addChild("div",(t=>t.addClass("kfrm-select full-width").addChild("select",(t=>{if(n&&t.attr("readonly",""),t.attr("name",e.id),t.on("keypress",(t=>this.applySumbit(t))),s)for(let e=0;e<s.length;e++){const i=s[e];t.addOption({value:i.id,title:i.text,selected:0===e})}t.value(i)}))))}setupFileField(t,e,i,s){z(t).addChild("input",(t=>{i&&t.attr("readonly",""),t.name(e.id).type(this.resolveInputType(e.dataType)),t.attr("accept",s)}))}setupTextField(e,i,s,n,o){z(e).addChild("input",(e=>{n&&e.attr("readonly",""),e.type(o?"hidden":this.resolveInputType(i.dataType)),e.name(i.id).type(this.resolveInputType(i.dataType)),i.dataType==t.Bool?s&&e.attr("checked",""):e.on("keypress",(t=>this.applySumbit(t))).value(l.IsDefinedAndNotNull(s)?s.toString():"")}))}setupTextArea(t,e,i,s){z(t).addChild("textarea",(t=>{s&&t.attr("readonly",""),t.attr("name",e.id),t.setStyle("height","120px"),t.value(l.IsDefinedAndNotNull(i)?i.toString():"")}))}addFormField(t,i){const s=this.params.values&&i.kind!==e.Lookup?this.params.values.getValue(i.id):this.params.isEditForm?void 0:i.defaultValue,r=this.resolveEditor(i),l=this.params.isEditForm&&(i.isPrimaryKey||!i.isEditable),d=!i.isNullable;kt&&(t=z("div",t).addClass("kfrm-field-ie").toDOM()),z(t).addChild("label",(t=>{t.attr("for",i.id),t.addHtml(`${i.caption} ${d?'<sup style="color: red">*</sup>':""}: `),i.description&&t.addChild("div",(t=>t.attr("title",i.description).addClass("question-mark").setStyle("vertical-align","middle").setStyle("display","inline-block")))}));const h=i.isPrimaryKey;if(i.kind!==e.Lookup)switch(r.tag){case n:this.setupDateTimeField(t,i,s,l,h);break;case o:this.setupListField(t,i,s,r.values,l);break;case a:this.setupFileField(t,i,l,r.accept);break;default:r.multiline?this.setupTextArea(t,i,s,l):this.setupTextField(t,i,s,l,h)}else this.setupLookupField(t,i,l,s)}resolveInputType(e){return e===t.Bool?"checkbox":e===t.Blob?"file":"text"}resolveEditor(t){let e=t.defaultEditor||new D;return e.tag==i&&(l.getDateDataTypes().indexOf(t.dataType)>=0?e.tag=n:e.tag=s),e}applySumbit(t){return 13===t.keyCode&&(this.sumbitCallback&&this.sumbitCallback(),!1)}onSubmit(t){return this.sumbitCallback=t,this}build(){let t;const e=z("div").addClass("kfrm-form").addChild("div",(t=>t.addClass("errors-block").toDOM())).addChild("div",(e=>{e.addClass(""+(kt?"kfrm-fields-ie col-ie-1-4 label-align-right":"kfrm-fields col-a-1 label-align-right")),t=e})).toDOM();this.form.setHtmlInt(e);for(const e of this.context.getActiveEntity().attributes)(this.params.isEditForm||e.showOnCreate)&&(e.isPrimaryKey||!this.params.isEditForm||e.showOnEdit)&&this.addFormField(t.toDOM(),e);return this.form}}class Pt{constructor(t){this.slot=t,this.hide(),this.slot.classList.add("ed-progress-bar")}show(){this.slot.style.removeProperty("display")}hide(){this.slot.style.display="none"}}class Ot{constructor(t){this.context=t}loadChunk(t){const e=this.context.resolveEndpoint("FetchDataset",{sourceId:t.sourceId||this.context.getActiveEntity().id});delete t.sourceId,this.context.startProcess();return this.context.getHttpClient().post(e,t).then((e=>{const i=new b({chunkSize:1e3}),s=e.resultSet;for(const t of s.cols)i.columns.add(t);for(const t of s.rows)i.addRow(t);let n=0;return e.meta&&e.meta.totalRecords&&(n=e.meta.totalRecords),{table:i,total:n,hasNext:!t.needTotal||t.offset+t.limit<n}})).finally((()=>{this.context.endProcess()}))}}class Lt{constructor(t){this.endpoints=new Map,this.endpointVarsRegex=/\{.*?\}/g,this.options=t||{},this.http=new m,this.model=new v,this.model.id=t.metaDataId||"__default",this.dataLoader=new Ot(this);const e=Object.assign({loader:this.dataLoader},t.dataTable);this.data=new b(e),this.setDefaultEndpoints(this.options.endpoint||"/api/easydata")}getActiveEntity(){return this.activeEntity}setActiveSource(t){this.activeEntity=this.model.getRootEntity().subEntities.filter((e=>e.id==t))[0]}getMetaData(){return this.model}getData(){return this.data}getDataLoader(){return this.dataLoader}createFilter(t,e,i){return new E(this.dataLoader,e||this.getData(),t||this.activeEntity.id,i)}loadMetaData(){const t=this.resolveEndpoint("GetMetaData");return this.startProcess(),this.http.get(t).then((t=>(t.model&&this.model.loadFromData(t.model),this.model))).catch((t=>(console.error(`Error: ${t.message}. Source: ${t.sourceError}`),null))).finally((()=>{this.endProcess()}))}getHttpClient(){return this.http}fetchDataset(){return this.data.clear(),this.dataLoader.loadChunk({offset:0,limit:this.data.chunkSize,needTotal:!0}).then((t=>{for(const e of t.table.columns.getItems())this.data.columns.add(e);this.data.setTotal(t.total);for(const e of t.table.getCachedRows())this.data.addRow(e);return this.data}))}fetchRecord(t,e){const i=this.resolveEndpoint("FetchRecord",{sourceId:e||this.activeEntity.id});return this.startProcess(),this.http.get(i,{queryParams:t}).finally((()=>this.endProcess()))}createRecord(t,e){const i=this.resolveEndpoint("CreateRecord",{sourceId:e||this.activeEntity.id});return this.startProcess(),this.http.post(i,t,{dataType:"json"}).finally((()=>this.endProcess()))}updateRecord(t,e){const i=this.resolveEndpoint("UpdateRecord",{sourceId:e||this.activeEntity.id});return this.startProcess(),this.http.post(i,t,{dataType:"json"}).finally((()=>this.endProcess()))}deleteRecord(t,e){const i=this.resolveEndpoint("DeleteRecord",{sourceId:e||this.activeEntity.id});return this.startProcess(),this.http.post(i,t,{dataType:"json"}).finally((()=>this.endProcess()))}setEndpoint(t,e){this.endpoints.set(t,e)}setEnpointIfNotExist(t,e){this.endpoints.has(t)||this.endpoints.set(t,e)}resolveEndpoint(t,e){e=e||{};let i=this.endpoints.get(t);if(!i)throw t+" endpoint is not defined";let s=i.match(this.endpointVarsRegex);if(s)for(let t of s){let s=t.substring(1,t.length-1),n=e[s];if(!n)if("modelId"==s)n=this.model.getId();else{if("sourceId"!=s)throw`Parameter [${s}] is not defined`;n=this.activeEntity.id}i=i.replace(t,n)}return i}startProcess(){this.options.onProcessStart&&this.options.onProcessStart()}endProcess(){this.options.onProcessEnd&&this.options.onProcessEnd()}setDefaultEndpoints(t){this.setEnpointIfNotExist("GetMetaData",x(t,"models/{modelId}")),this.setEnpointIfNotExist("FetchDataset",x(t,"models/{modelId}/sources/{sourceId}/fetch")),this.setEnpointIfNotExist("FetchRecord",x(t,"models/{modelId}/sources/{sourceId}/fetch")),this.setEnpointIfNotExist("CreateRecord",x(t,"models/{modelId}/sources/{sourceId}/create")),this.setEnpointIfNotExist("UpdateRecord",x(t,"models/{modelId}/sources/{sourceId}/update")),this.setEnpointIfNotExist("DeleteRecord",x(t,"models/{modelId}/sources/{sourceId}/delete"))}}class Nt extends It{constructor(){super(),this.name="Type"}validate(t,e){if(!l.IsDefinedAndNotNull(e)||""==e)return{successed:!0};if(l.isNumericType(t.dataType)){if(!l.isNumeric(e))return{successed:!1,messages:[d.getText("NumberError")]};if(l.isIntType(t.dataType)&&!Number.isInteger(Number.parseFloat(e)))return{successed:!1,messages:[d.getText("IntNumberError")]}}return{successed:!0}}}class Ft extends It{constructor(){super(),this.name="Required"}validate(t,e){return t.isNullable||l.IsDefinedAndNotNull(e)&&""!==e?{successed:!0}:{successed:!1,messages:[d.getText("RequiredError")]}}}class $t{constructor(t,e,i,s){this.slot=t,this.context=e,this.basePath=i,this.options={showFilterBox:!0,showBackToEntities:!0},this.defaultValidators=[new Ft,new Nt],this.options=l.assignDeep(this.options,s||{}),this.dlg=new ft;const n=this.context.getActiveEntity();if(!n)throw"Can't find active entity for "+window.location.pathname;this.slot.innerHTML+=`<h1>${n.captionPlural||n.caption}</h1>`,this.options.showBackToEntities&&z(this.slot).addChild("a",(t=>t.attr("href","javascript:void(0)").text(`← ${d.getText("BackToEntities")}`).on("click",(t=>{t.preventDefault(),Et(this.basePath)})))),this.renderGrid()}syncGridColumnHandler(t){if(t.dataColumn){const e=this.context.getMetaData().getAttributeById(t.dataColumn.id);e&&(t.isVisible=e.showOnView)}}renderGrid(){this.context.fetchDataset().then((t=>{const e=document.createElement("div");if(this.slot.appendChild(e),e.id="Grid",this.grid=new rt(l.assignDeep({slot:e,dataTable:t,paging:{pageSize:15,allowPageSizeChange:!0,pageSizeItems:[15,30,50,100,200]},showPlusButton:this.context.getActiveEntity().isEditable,plusButtonTitle:d.getText("AddRecordBtnTitle"),showActiveRow:!1,onPlusButtonClick:this.addClickHandler.bind(this),onGetCellRenderer:this.manageCellRenderer.bind(this),onRowDbClick:this.rowDbClickHandler.bind(this),onSyncGridColumn:this.syncGridColumnHandler.bind(this)},this.options.grid||{})),this.options.showFilterBox){let t;const i=z("div").addClass("kfrm-form").setStyle("margin","10px 0px").addChild("div",(e=>t=e.toDOM())).toDOM();this.slot.insertBefore(i,e);const s=this.context.createFilter();this.filterWidget=new Rt(t,this.grid,s)}}))}manageCellRenderer(t,e){if(t.isRowNum)return t.width=110,(t,e,i,s)=>{const n=z("div",i).addClass("keg-cell-value");this.context.getActiveEntity().isEditable&&n.addChild("a",(t=>t.attr("href","javascript:void(0)").text(d.getText("EditBtn")).on("click",(t=>this.editClickHandler(t,parseInt(s.getAttribute("data-row-idx"))))))).addChild("span",(t=>t.text(" | "))).addChild("a",(t=>t.attr("href","javascript:void(0)").text(d.getText("DeleteBtn")).on("click",(t=>this.deleteClickHandler(t,parseInt(s.getAttribute("data-row-idx")))))))}}addClickHandler(){const t=this.context.getActiveEntity(),e=new At(this.context).onSubmit((()=>i.submit())).build();e.useValidators(this.defaultValidators);const i=this.dlg.open({title:d.getText("AddDlgCaption").replace("{entity}",t.caption),body:e.getHtml(),onSubmit:()=>{if(!e.validate())return!1;e.getData().then((t=>this.context.createRecord(t))).then((()=>this.refreshData())).catch((t=>{this.processError(t)}))}})}editClickHandler(t,e){this.grid.getData().getRow(e).then((t=>{t&&this.showEditForm(t)}))}showEditForm(t){const e=this.context.getActiveEntity(),i=new At(this.context,{isEditForm:!0,values:t}).onSubmit((()=>s.submit())).build();i.useValidators(this.defaultValidators);const s=this.dlg.open({title:d.getText("EditDlgCaption").replace("{entity}",e.caption),body:i.getHtml(),onSubmit:()=>{if(!i.validate())return!1;i.getData().then((t=>this.context.updateRecord(t))).then((()=>this.refreshData())).catch((t=>{this.processError(t)}))}})}rowDbClickHandler(t){this.context.getActiveEntity().isEditable&&this.showEditForm(t.row)}deleteClickHandler(t,e){this.grid.getData().getRow(e).then((t=>{if(t){const e=this.context.getActiveEntity(),i=e.getPrimaryAttrs(),s=i.map((e=>t.getValue(e.id))),n=i.reduce(((t,e,i)=>(t[e.id.substring(e.id.lastIndexOf(".")+1)]=s[i],t)),{});this.dlg.openConfirm(d.getText("DeleteDlgCaption").replace("{entity}",e.caption),d.getText("DeleteDlgMessage").replace("{recordId}",Object.keys(n).map((t=>`${t}:${n[t]}`)).join(";"))).then((t=>{t&&this.context.deleteRecord(n).then((()=>this.refreshData())).catch((t=>{this.processError(t)}))}))}}))}processError(t){this.dlg.open({title:"Ooops, something went wrong",body:t.message,closable:!0,cancelable:!1})}refreshData(){return this.context.fetchDataset().then((()=>{let t=!1;this.filterWidget&&(t=this.filterWidget.applyFilter(!1)),t||this.grid.refresh()}))}}class Bt{constructor(t,e,i){this.slot=t,this.context=e,this.basePath=i,this.metaData=this.context.getMetaData(),this.slot.innerHTML+=`<h1>${d.getText("RootViewTitle")}</h1>`,this.renderEntitySelector()}renderEntitySelector(){const t=this.metaData.getRootEntity().subEntities;this.slot&&z(this.slot).addChild("div",(e=>e.addClass("ed-root").addChild("div",(t=>t.addClass("ed-menu-description").addText(d.getText(this.metaData.isEmpty()?"ModelIsEmpty":"EntityMenuDesc")))).addChild("ul",(e=>{e.addClass("ed-entity-menu"),t.forEach((t=>{e.addChild("li",(e=>{e.addClass("ed-entity-item").on("click",(()=>{Et(`${this.basePath}/${decodeURIComponent(t.id)}`)})).addChild("div",(e=>{e.addClass("ed-entity-item-caption").addText(t.captionPlural||t.caption)})),t.description&&e.addChild("div",(e=>{e.addClass("ed-entity-item-descr").addText(`${t.description}`)}))}))}))}))))}}d.updateDefaultTexts({RequiredError:"Value is required.",NumberError:"Value should be a number",IntNumberError:"Value should be an integer number",DateTimeError:"Invalid date or time value",LookupSelectedItem:"Selected item: ",LookupDlgCaption:"Select {entity}",None:"None",NavigationBtnTitle:"Navigation values",CalendarBtnTitle:"Open calendar",TimerBtnTitle:"Open timer",AddBtnTitle:"Add",AddRecordBtnTitle:"Add record",EditBtn:"Edit",DeleteBtn:"Delete",SelectLink:"[ select ]",AddDlgCaption:"Create {entity}",EditDlgCaption:"Edit {entity}",DeleteDlgCaption:"Delete {entity}",DeleteDlgMessage:"Are you sure you want to remove this record: {{recordId}}?",EntityMenuDesc:"Click on an entity to view/edit its content",BackToEntities:"Back to entities",SearchBtn:"Search",SearchInputPlaceholder:"Search...",RootViewTitle:"Entities",ModelIsEmpty:"No entity was found."}),exports.DataContext=Lt,exports.EasyDataServerLoader=Ot,exports.EasyDataViewDispatcher=class{constructor(t){this.options={container:"#EasyDataContainer",basePath:"easydata"},this.onSetLocation=()=>{this.setActiveView()},this.attach=()=>{window.addEventListener("ed_set_location",this.onSetLocation),window.addEventListener("popstate",this.onSetLocation)},this.options=l.assign(this.options,t||{}),this.options.rootEntity?(this.options.showBackToEntities=!1,this.basePath="/"):this.basePath=this.normalizeBasePath(this.options.basePath),this.setContainer(this.options.container);const e=document.createElement("div"),i=new Pt(e),s=this.container.parentElement;s.insertBefore(e,s.firstElementChild),this.context=new Lt({endpoint:this.options.endpoint,dataTable:this.options.dataTable,onProcessStart:()=>i.show(),onProcessEnd:()=>i.hide()})}normalizeBasePath(t){t=this.trimSlashes(t);const e=decodeURIComponent(window.location.pathname),i=e.toLocaleLowerCase().indexOf(t);return i>=0?e.substring(0,i+t.length):"/"}trimSlashes(t){return t.replace(/^\/|\/$/g,"")}setContainer(t){if(!t)throw"Container is undefined";if("string"==typeof t){if(t.length){if("."===t[0]){const e=document.getElementsByClassName(t.substring(1));e.length&&(this.container=e[0])}else"#"===t[0]&&(t=t.substring(1)),this.container=document.getElementById(t);if(!this.container)throw Error("Unrecognized `container` parameter: "+t+"\nIt must be an element ID, a class name (starting with .) or an HTMLElement object itself.")}}else this.container=t}getActiveSourceId(){if(this.options.rootEntity)return this.options.rootEntity;const t=decodeURIComponent(window.location.pathname),e=this.basePath.length+1;return e<t.length?t.substring(e):null}run(){return this.attach(),this.context.loadMetaData().then((()=>{this.setActiveView()})).catch((t=>console.error(t)))}setActiveView(){this.clear();const t=this.getActiveSourceId();t?(this.context.setActiveSource(t),window.EDView=new $t(this.container,this.context,this.basePath,this.options)):window.EDView=new Bt(this.container,this.context,this.basePath)}clear(){this.container.innerHTML="",this.context.getData().clear()}detach(){window.removeEventListener("ed_set_location",this.onSetLocation),window.removeEventListener("popstate",this.onSetLocation)}},exports.EntityDataView=$t,exports.EntityEditForm=Mt,exports.EntityEditFormBuilder=At,exports.ProgressBar=Pt,exports.RequiredValidator=Ft,exports.RootDataView=Bt,exports.TextDataFilter=E,exports.TextFilterWidget=Rt,exports.TypeValidator=Nt,exports.Validator=It;
|
|
22
|
-
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
var core = require('@easydata/core');
|
|
11
|
+
var ui = require('@easydata/ui');
|
|
12
|
+
|
|
13
|
+
class TextDataFilter {
|
|
14
|
+
constructor(loader, sourceTable, sourceId, isLookup = false) {
|
|
15
|
+
this.loader = loader;
|
|
16
|
+
this.sourceTable = sourceTable;
|
|
17
|
+
this.sourceId = sourceId;
|
|
18
|
+
this.isLookup = isLookup;
|
|
19
|
+
this.filterValue = '';
|
|
20
|
+
//turns off client-side search
|
|
21
|
+
//for test purposes
|
|
22
|
+
this.justServerSide = false;
|
|
23
|
+
}
|
|
24
|
+
getValue() {
|
|
25
|
+
return this.filterValue;
|
|
26
|
+
}
|
|
27
|
+
apply(value) {
|
|
28
|
+
this.filterValue = value;
|
|
29
|
+
if (this.filterValue) {
|
|
30
|
+
return this.applyCore();
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
return this.clear();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
clear() {
|
|
37
|
+
this.filterValue = '';
|
|
38
|
+
return Promise.resolve(this.sourceTable);
|
|
39
|
+
}
|
|
40
|
+
applyCore() {
|
|
41
|
+
if (this.sourceTable.getTotal() == this.sourceTable.getCachedCount() && !this.justServerSide) {
|
|
42
|
+
return this.applyInMemoryFilter();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
const filters = [
|
|
46
|
+
{ class: "__substring", value: this.filterValue }
|
|
47
|
+
];
|
|
48
|
+
return this.loader.loadChunk({
|
|
49
|
+
offset: 0,
|
|
50
|
+
limit: this.sourceTable.chunkSize,
|
|
51
|
+
needTotal: true,
|
|
52
|
+
filters: filters,
|
|
53
|
+
sourceId: this.sourceId,
|
|
54
|
+
lookup: this.isLookup
|
|
55
|
+
})
|
|
56
|
+
.then(data => {
|
|
57
|
+
const filteredTable = new core.EasyDataTable({
|
|
58
|
+
chunkSize: this.sourceTable.chunkSize,
|
|
59
|
+
loader: {
|
|
60
|
+
loadChunk: (params) => this.loader
|
|
61
|
+
.loadChunk(Object.assign(Object.assign({}, params), { filters: filters, sourceId: this.sourceId, lookup: this.isLookup }))
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
for (const col of this.sourceTable.columns.getItems()) {
|
|
65
|
+
filteredTable.columns.add(col);
|
|
66
|
+
}
|
|
67
|
+
filteredTable.setTotal(data.total);
|
|
68
|
+
for (const row of data.table.getCachedRows()) {
|
|
69
|
+
filteredTable.addRow(row);
|
|
70
|
+
}
|
|
71
|
+
return filteredTable;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
applyInMemoryFilter() {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
const filteredTable = new core.EasyDataTable({
|
|
78
|
+
chunkSize: this.sourceTable.chunkSize,
|
|
79
|
+
inMemory: true
|
|
80
|
+
});
|
|
81
|
+
for (const col of this.sourceTable.columns.getItems()) {
|
|
82
|
+
filteredTable.columns.add(col);
|
|
83
|
+
}
|
|
84
|
+
const words = this.filterValue.split('||').map(w => w.trim().toLowerCase());
|
|
85
|
+
const suitableColumns = this.sourceTable.columns.getItems()
|
|
86
|
+
.filter(col => core.utils.isNumericType(col.type)
|
|
87
|
+
|| core.utils.getStringDataTypes().indexOf(col.type) >= 0);
|
|
88
|
+
const hasEnterance = (row) => {
|
|
89
|
+
for (const col of suitableColumns) {
|
|
90
|
+
const value = row.getValue(col.id);
|
|
91
|
+
if (value) {
|
|
92
|
+
const normalized = value.toString().toLowerCase();
|
|
93
|
+
for (const word of words) {
|
|
94
|
+
if (normalized.indexOf(word) >= 0) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
};
|
|
102
|
+
for (const row of this.sourceTable.getCachedRows()) {
|
|
103
|
+
if (hasEnterance(row)) {
|
|
104
|
+
filteredTable.addRow(row);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
filteredTable.setTotal(filteredTable.getCachedCount());
|
|
108
|
+
resolve(filteredTable);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const internalDateFormat = 'yyyy-MM-dd';
|
|
114
|
+
const internalTimeFormat = 'HH:mm';
|
|
115
|
+
const getInternalDateTimeFormat = (dtype) => {
|
|
116
|
+
if (dtype == core.DataType.Date)
|
|
117
|
+
return internalDateFormat;
|
|
118
|
+
if (dtype == core.DataType.Time)
|
|
119
|
+
return internalTimeFormat;
|
|
120
|
+
return `${internalDateFormat}T${internalTimeFormat}`;
|
|
121
|
+
};
|
|
122
|
+
const getEditDateTimeFormat = (dtype) => {
|
|
123
|
+
const settings = core.i18n.getLocaleSettings();
|
|
124
|
+
if (dtype == core.DataType.Date)
|
|
125
|
+
return settings.editDateFormat;
|
|
126
|
+
if (dtype == core.DataType.Time)
|
|
127
|
+
return settings.editTimeFormat;
|
|
128
|
+
return `${settings.editDateFormat} ${settings.editTimeFormat}`;
|
|
129
|
+
};
|
|
130
|
+
const setLocation = (path) => {
|
|
131
|
+
const state = window.history.state;
|
|
132
|
+
history.pushState(state, document.title, path);
|
|
133
|
+
window.dispatchEvent(new Event('ed_set_location'));
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
class Validator {
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
class DateTimeValidator extends Validator {
|
|
140
|
+
constructor() {
|
|
141
|
+
super();
|
|
142
|
+
this.name = 'DateTime';
|
|
143
|
+
}
|
|
144
|
+
validate(attr, value) {
|
|
145
|
+
if (!core.utils.IsDefinedAndNotNull(value) || value == '')
|
|
146
|
+
return { successed: true };
|
|
147
|
+
if (core.utils.getDateDataTypes().indexOf(attr.dataType) >= 0) {
|
|
148
|
+
try {
|
|
149
|
+
const editFormat = getEditDateTimeFormat(attr.dataType);
|
|
150
|
+
const newDate = core.utils.strToDateTime(value, editFormat);
|
|
151
|
+
}
|
|
152
|
+
catch (_a) {
|
|
153
|
+
return {
|
|
154
|
+
successed: false,
|
|
155
|
+
messages: [core.i18n.getText('DateTimeError')]
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return { successed: true };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
class EntityEditForm {
|
|
164
|
+
constructor(context) {
|
|
165
|
+
this.context = context;
|
|
166
|
+
this.validators = [new DateTimeValidator()];
|
|
167
|
+
}
|
|
168
|
+
getHtml() {
|
|
169
|
+
return this.html;
|
|
170
|
+
}
|
|
171
|
+
setHtmlInt(html) {
|
|
172
|
+
this.html = html;
|
|
173
|
+
this.errorsDiv = this.html.querySelector('.errors-block');
|
|
174
|
+
}
|
|
175
|
+
validate() {
|
|
176
|
+
this.clearErrors();
|
|
177
|
+
const inputs = Array.from(this.html.querySelectorAll('input, select'));
|
|
178
|
+
let isValid = true;
|
|
179
|
+
for (const input of inputs) {
|
|
180
|
+
const attr = this.context.getMetaData().getAttributeById(input.name);
|
|
181
|
+
if (input.type === 'checkbox')
|
|
182
|
+
continue;
|
|
183
|
+
const result = this.validateValue(attr, input.value);
|
|
184
|
+
if (!result.successed) {
|
|
185
|
+
if (isValid) {
|
|
186
|
+
ui.domel(this.errorsDiv)
|
|
187
|
+
.addChild('ul');
|
|
188
|
+
}
|
|
189
|
+
isValid = false;
|
|
190
|
+
for (const message of result.messages) {
|
|
191
|
+
this.errorsDiv.firstElementChild.innerHTML += `<li>${attr.caption}: ${message}</li>`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
this.markInputValid(input, result.successed);
|
|
195
|
+
}
|
|
196
|
+
return isValid;
|
|
197
|
+
}
|
|
198
|
+
getData() {
|
|
199
|
+
return new Promise((resolve, reject) => {
|
|
200
|
+
const filePromises = [];
|
|
201
|
+
const inputs = Array.from(this.html
|
|
202
|
+
.querySelectorAll('input, select, textarea'));
|
|
203
|
+
let obj = {};
|
|
204
|
+
for (const input of inputs) {
|
|
205
|
+
const property = input.name.substring(input.name.lastIndexOf('.') + 1);
|
|
206
|
+
const attr = this.context.getMetaData().getAttributeById(input.name);
|
|
207
|
+
if (input.type === 'checkbox') {
|
|
208
|
+
obj[property] = input.checked;
|
|
209
|
+
}
|
|
210
|
+
else if (input.type === 'file') {
|
|
211
|
+
filePromises.push(this.fileToBase64(input.files[0])
|
|
212
|
+
.then(content => obj[property] = content));
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
obj[property] = this.mapValue(attr.dataType, input.value);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
Promise.all(filePromises)
|
|
219
|
+
.then(() => resolve(obj))
|
|
220
|
+
.catch((e) => reject(e));
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
fileToBase64(file) {
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
const reader = new FileReader();
|
|
226
|
+
reader.readAsDataURL(file);
|
|
227
|
+
reader.onload = () => {
|
|
228
|
+
const result = reader.result.toString();
|
|
229
|
+
resolve(result.substring(result.indexOf(',') + 1));
|
|
230
|
+
};
|
|
231
|
+
reader.onerror = error => reject(error);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
useValidator(...validator) {
|
|
235
|
+
this.useValidators(validator);
|
|
236
|
+
}
|
|
237
|
+
useValidators(validators) {
|
|
238
|
+
this.validators = this.validators.concat(validators);
|
|
239
|
+
}
|
|
240
|
+
mapValue(type, value) {
|
|
241
|
+
if (core.utils.getDateDataTypes().indexOf(type) >= 0) {
|
|
242
|
+
if (type !== core.DataType.Time && value && value.length) {
|
|
243
|
+
const editFormat = getEditDateTimeFormat(type);
|
|
244
|
+
const internalFormat = getInternalDateTimeFormat(type);
|
|
245
|
+
const date = core.utils.strToDateTime(value, editFormat);
|
|
246
|
+
return core.i18n.dateTimeToStr(date, internalFormat);
|
|
247
|
+
}
|
|
248
|
+
return value && value.length ? value : null;
|
|
249
|
+
}
|
|
250
|
+
if (core.utils.isIntType(type))
|
|
251
|
+
return parseInt(value);
|
|
252
|
+
if (core.utils.isNumericType(type))
|
|
253
|
+
return parseFloat(value);
|
|
254
|
+
return value;
|
|
255
|
+
}
|
|
256
|
+
clearErrors() {
|
|
257
|
+
this.errorsDiv.innerHTML = '';
|
|
258
|
+
this.html.querySelectorAll('input, select').forEach(el => {
|
|
259
|
+
el.classList.remove('is-valid');
|
|
260
|
+
el.classList.remove('is-invalid');
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
markInputValid(input, valid) {
|
|
264
|
+
input.classList.add(valid ? 'is-valid' : 'is-invalid');
|
|
265
|
+
}
|
|
266
|
+
validateValue(attr, value) {
|
|
267
|
+
const result = { successed: true, messages: [] };
|
|
268
|
+
for (const validator of this.validators) {
|
|
269
|
+
const res = validator.validate(attr, value);
|
|
270
|
+
if (!res.successed) {
|
|
271
|
+
result.successed = false;
|
|
272
|
+
result.messages = result.messages.concat(res.messages);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
class TextFilterWidget {
|
|
280
|
+
constructor(slot, grid, filter, options) {
|
|
281
|
+
this.slot = slot;
|
|
282
|
+
this.grid = grid;
|
|
283
|
+
this.filter = filter;
|
|
284
|
+
this.options = {
|
|
285
|
+
focus: false,
|
|
286
|
+
instantMode: false,
|
|
287
|
+
instantTimeout: 1000
|
|
288
|
+
};
|
|
289
|
+
this.options = core.utils.assignDeep(this.options, options || {});
|
|
290
|
+
const stringDefRenderer = this.grid.cellRendererStore
|
|
291
|
+
.getDefaultRendererByType(ui.CellRendererType.STRING);
|
|
292
|
+
this.grid.cellRendererStore
|
|
293
|
+
.setDefaultRenderer(ui.CellRendererType.STRING, (value, column, cellElement, rowElement) => this.highlightCellRenderer(stringDefRenderer, value, column, cellElement, rowElement));
|
|
294
|
+
const numDefRenderer = this.grid.cellRendererStore
|
|
295
|
+
.getDefaultRendererByType(ui.CellRendererType.NUMBER);
|
|
296
|
+
this.grid.cellRendererStore
|
|
297
|
+
.setDefaultRenderer(ui.CellRendererType.NUMBER, (value, column, cellElement, rowElement) => this.highlightCellRenderer(numDefRenderer, value, column, cellElement, rowElement));
|
|
298
|
+
this.render();
|
|
299
|
+
}
|
|
300
|
+
render() {
|
|
301
|
+
const horizClass = ui.browserUtils.IsIE()
|
|
302
|
+
? 'kfrm-fields-ie is-horizontal'
|
|
303
|
+
: 'kfrm-fields is-horizontal';
|
|
304
|
+
const isEdgeOrIE = ui.browserUtils.IsIE() || ui.browserUtils.IsEdge();
|
|
305
|
+
ui.domel(this.slot)
|
|
306
|
+
.addClass(horizClass)
|
|
307
|
+
.addChild('div', b => {
|
|
308
|
+
b
|
|
309
|
+
.addClass('control')
|
|
310
|
+
.addChild('input', b => {
|
|
311
|
+
this.filterInput = b.toDOM();
|
|
312
|
+
b
|
|
313
|
+
.attr('placeholder', core.i18n.getText('SearchInputPlaceholder'))
|
|
314
|
+
.type('text');
|
|
315
|
+
b.on('keydown', this.inputKeydownHandler.bind(this));
|
|
316
|
+
if (this.options.instantMode) {
|
|
317
|
+
b.on('keyup', this.inputKeyupHandler.bind(this));
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
if (!isEdgeOrIE) {
|
|
321
|
+
b
|
|
322
|
+
.addClass('has-icons-right')
|
|
323
|
+
.addChild('span', b => {
|
|
324
|
+
b
|
|
325
|
+
.addClass('icon')
|
|
326
|
+
.addClass('is-right')
|
|
327
|
+
.addClass('is-clickable')
|
|
328
|
+
.html('🗙')
|
|
329
|
+
.on('click', this.clearButtonClickHander.bind(this));
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
if (!this.options.instantMode) {
|
|
334
|
+
ui.domel(this.slot)
|
|
335
|
+
.addChild('button', b => b
|
|
336
|
+
.addClass('kfrm-button')
|
|
337
|
+
.addText(core.i18n.getText('SearchBtn'))
|
|
338
|
+
.on('click', this.searchButtonClickHandler.bind(this)));
|
|
339
|
+
}
|
|
340
|
+
if (this.options.focus) {
|
|
341
|
+
this.filterInput.focus();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
inputKeydownHandler(ev) {
|
|
345
|
+
if (ev.keyCode == 13) {
|
|
346
|
+
this.applyFilter(true);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
inputKeyupHandler() {
|
|
350
|
+
if (this.applyFilterTimeout) {
|
|
351
|
+
clearTimeout(this.applyFilterTimeout);
|
|
352
|
+
}
|
|
353
|
+
this.applyFilterTimeout = setTimeout(() => {
|
|
354
|
+
this.applyFilter(true);
|
|
355
|
+
}, this.options.instantTimeout);
|
|
356
|
+
}
|
|
357
|
+
clearButtonClickHander() {
|
|
358
|
+
this.filterInput.value = '';
|
|
359
|
+
this.filterInput.focus();
|
|
360
|
+
this.applyFilter(true);
|
|
361
|
+
}
|
|
362
|
+
searchButtonClickHandler() {
|
|
363
|
+
this.applyFilter(true);
|
|
364
|
+
}
|
|
365
|
+
applyFilter(checkChange) {
|
|
366
|
+
if (this.applyFilterTimeout) {
|
|
367
|
+
clearTimeout(this.applyFilterTimeout);
|
|
368
|
+
}
|
|
369
|
+
const filterValue = this.filter.getValue();
|
|
370
|
+
if (!checkChange || filterValue != this.filterInput.value) {
|
|
371
|
+
this.filter.apply(this.filterInput.value)
|
|
372
|
+
.then(data => {
|
|
373
|
+
this.grid.setData(data);
|
|
374
|
+
});
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
highlightCellRenderer(defaultRenderer, value, column, cellElement, rowElement) {
|
|
380
|
+
if (core.utils.isNumericType(column.type)
|
|
381
|
+
|| core.utils.getStringDataTypes().indexOf(column.type) >= 0) {
|
|
382
|
+
if (value) {
|
|
383
|
+
if (column.dataColumn && column.dataColumn.displayFormat
|
|
384
|
+
&& ui.DFMT_REGEX.test(column.dataColumn.displayFormat)) {
|
|
385
|
+
value = column.dataColumn.displayFormat.replace(ui.DFMT_REGEX, (_, $1) => {
|
|
386
|
+
return core.i18n.numberToStr(value, $1);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
value = value.toLocaleString();
|
|
391
|
+
}
|
|
392
|
+
const result = this.highlightText(value.toString());
|
|
393
|
+
if (result instanceof HTMLElement) {
|
|
394
|
+
cellElement.title = value;
|
|
395
|
+
cellElement.appendChild(result);
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
defaultRenderer(value, column, cellElement, rowElement);
|
|
401
|
+
}
|
|
402
|
+
highlightText(content) {
|
|
403
|
+
const normalizedContent = content.toLowerCase();
|
|
404
|
+
const filterValue = this.filter.getValue().toString();
|
|
405
|
+
if (filterValue && filterValue.length > 0 && content && content.length > 0) {
|
|
406
|
+
const indexInMas = [];
|
|
407
|
+
const words = filterValue.split('||').map(w => w.trim().toLowerCase());
|
|
408
|
+
for (let i = 0; i < words.length; i++) {
|
|
409
|
+
let pos = 0;
|
|
410
|
+
const lowerWord = words[i];
|
|
411
|
+
if (!lowerWord.length)
|
|
412
|
+
continue;
|
|
413
|
+
if (lowerWord === normalizedContent) {
|
|
414
|
+
const highlightSpan = document.createElement('span');
|
|
415
|
+
highlightSpan.style.backgroundColor = 'yellow';
|
|
416
|
+
highlightSpan.innerText = content;
|
|
417
|
+
return highlightSpan;
|
|
418
|
+
}
|
|
419
|
+
while (pos < content.length - 1) {
|
|
420
|
+
const index = normalizedContent.indexOf(lowerWord, pos);
|
|
421
|
+
if (index >= 0) {
|
|
422
|
+
indexInMas.push({ index: index, length: words[i].length });
|
|
423
|
+
pos = index + lowerWord.length;
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
pos++;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (indexInMas.length > 0) {
|
|
431
|
+
//sort array item by index
|
|
432
|
+
indexInMas.sort((item1, item2) => {
|
|
433
|
+
if (item1.index > item2.index) {
|
|
434
|
+
return 1;
|
|
435
|
+
}
|
|
436
|
+
else if (item1.index == item2.index2) {
|
|
437
|
+
return 0;
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
return -1;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
//remove intersecting gaps
|
|
444
|
+
for (let i = 0; i < indexInMas.length - 1;) {
|
|
445
|
+
const delta = indexInMas[i + 1].index - (indexInMas[i].index + indexInMas[i].length);
|
|
446
|
+
if (delta < 0) {
|
|
447
|
+
const addDelta = indexInMas[i + 1].length + delta;
|
|
448
|
+
if (addDelta > 0) {
|
|
449
|
+
indexInMas[i].length += addDelta;
|
|
450
|
+
}
|
|
451
|
+
indexInMas.splice(i + 1, 1);
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
i++;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
const div = document.createElement('div');
|
|
458
|
+
for (let i = 0; i < indexInMas.length; i++) {
|
|
459
|
+
if (i === 0) {
|
|
460
|
+
const text = document.createTextNode(content.substring(0, indexInMas[i].index));
|
|
461
|
+
div.appendChild(text);
|
|
462
|
+
}
|
|
463
|
+
const highlightSpan = document.createElement('span');
|
|
464
|
+
highlightSpan.style.backgroundColor = 'yellow';
|
|
465
|
+
highlightSpan.innerText = content.substring(indexInMas[i].index, indexInMas[i].index + indexInMas[i].length);
|
|
466
|
+
div.appendChild(highlightSpan);
|
|
467
|
+
const text = (i < indexInMas.length - 1)
|
|
468
|
+
? document.createTextNode(content.substring(indexInMas[i].index
|
|
469
|
+
+ indexInMas[i].length, indexInMas[i + 1].index))
|
|
470
|
+
: document.createTextNode(content.substring(indexInMas[i].index
|
|
471
|
+
+ indexInMas[i].length));
|
|
472
|
+
div.appendChild(text);
|
|
473
|
+
}
|
|
474
|
+
return div;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return content;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const isIE = ui.browserUtils.IsIE();
|
|
482
|
+
class EntityEditFormBuilder {
|
|
483
|
+
constructor(context, params) {
|
|
484
|
+
this.context = context;
|
|
485
|
+
this.params = params;
|
|
486
|
+
this.params = params || {};
|
|
487
|
+
this.reset();
|
|
488
|
+
}
|
|
489
|
+
reset() {
|
|
490
|
+
this.form = new EntityEditForm(this.context);
|
|
491
|
+
}
|
|
492
|
+
setupLookupField(parent, attr, readOnly, value) {
|
|
493
|
+
const lookupEntity = this.context.getMetaData().getRootEntity()
|
|
494
|
+
.subEntities.filter(ent => ent.id == attr.lookupEntity)[0];
|
|
495
|
+
const dataAttr = this.context.getMetaData().getAttributeById(attr.dataAttr);
|
|
496
|
+
if (!dataAttr)
|
|
497
|
+
return;
|
|
498
|
+
readOnly = readOnly || !dataAttr.isEditable;
|
|
499
|
+
value = this.params.values
|
|
500
|
+
? this.params.values.getValue(dataAttr.id)
|
|
501
|
+
: undefined;
|
|
502
|
+
const horizClass = isIE
|
|
503
|
+
? 'kfrm-fields-ie is-horizontal'
|
|
504
|
+
: 'kfrm-fields is-horizontal';
|
|
505
|
+
let inputEl;
|
|
506
|
+
ui.domel(parent)
|
|
507
|
+
.addChild('div', b => {
|
|
508
|
+
b
|
|
509
|
+
.addClass(horizClass)
|
|
510
|
+
.addChild('input', b => {
|
|
511
|
+
inputEl = b.toDOM();
|
|
512
|
+
b.attr('readonly', '');
|
|
513
|
+
b.name(dataAttr.id);
|
|
514
|
+
b.type(this.resolveInputType(dataAttr.dataType));
|
|
515
|
+
b.value(core.utils.IsDefinedAndNotNull(value)
|
|
516
|
+
? value.toString() : '');
|
|
517
|
+
});
|
|
518
|
+
if (!readOnly)
|
|
519
|
+
b.addChild('button', b => b
|
|
520
|
+
.addClass('kfrm-button')
|
|
521
|
+
.attr('title', core.i18n.getText('NavigationBtnTitle'))
|
|
522
|
+
.addText('...')
|
|
523
|
+
.on('click', (ev) => {
|
|
524
|
+
const lookupTable = new core.EasyDataTable({
|
|
525
|
+
loader: {
|
|
526
|
+
loadChunk: (chunkParams) => this.context.getDataLoader()
|
|
527
|
+
.loadChunk(Object.assign(Object.assign({}, chunkParams), { id: lookupEntity.id }))
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
this.context.getDataLoader()
|
|
531
|
+
.loadChunk({ offset: 0, limit: 1000, needTotal: true, sourceId: lookupEntity.id })
|
|
532
|
+
.then(data => {
|
|
533
|
+
for (const col of data.table.columns.getItems()) {
|
|
534
|
+
const attrs = lookupEntity.attributes.filter(attr => attr.id == col.id && (attr.isPrimaryKey || attr.showInLookup));
|
|
535
|
+
if (attrs.length) {
|
|
536
|
+
lookupTable.columns.add(col);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
lookupTable.setTotal(data.total);
|
|
540
|
+
for (const row of data.table.getCachedRows()) {
|
|
541
|
+
lookupTable.addRow(row);
|
|
542
|
+
}
|
|
543
|
+
const ds = new ui.DefaultDialogService();
|
|
544
|
+
let gridSlot = null;
|
|
545
|
+
let selectedSlot = null;
|
|
546
|
+
let widgetSlot;
|
|
547
|
+
const slot = ui.domel('div')
|
|
548
|
+
.addClass(`kfrm-form`)
|
|
549
|
+
.addChild('div', b => b
|
|
550
|
+
.addClass(`kfrm-field`)
|
|
551
|
+
.addChild('label', b => b
|
|
552
|
+
.addText(core.i18n.getText('LookupSelectedItem'))
|
|
553
|
+
.toDOM())
|
|
554
|
+
.addChild('div', b => selectedSlot = b
|
|
555
|
+
.addText('None')
|
|
556
|
+
.toDOM()))
|
|
557
|
+
.addChild('div', b => widgetSlot = b.toDOM())
|
|
558
|
+
.addChild('div', b => b
|
|
559
|
+
.addClass('kfrm-control')
|
|
560
|
+
.addChild('div', b => gridSlot = b.toDOM()))
|
|
561
|
+
.toDOM();
|
|
562
|
+
let selectedValue = inputEl.value;
|
|
563
|
+
const getValue = (row, colId) => {
|
|
564
|
+
if (row instanceof core.DataRow) {
|
|
565
|
+
return row.getValue(colId);
|
|
566
|
+
}
|
|
567
|
+
const property = colId.substring(colId.lastIndexOf('.') + 1);
|
|
568
|
+
return row[property];
|
|
569
|
+
};
|
|
570
|
+
const updateSelectedValue = (row) => {
|
|
571
|
+
selectedSlot.innerHTML = lookupTable.columns
|
|
572
|
+
.getItems()
|
|
573
|
+
.map(col => {
|
|
574
|
+
return `<b>${col.label}:</b> ${getValue(row, col.id)}`;
|
|
575
|
+
})
|
|
576
|
+
.join(', ');
|
|
577
|
+
};
|
|
578
|
+
if (selectedValue) {
|
|
579
|
+
const attr = lookupEntity.getFirstPrimaryAttr();
|
|
580
|
+
const key = attr.id.substring(attr.id.lastIndexOf('.') + 1);
|
|
581
|
+
this.context.fetchRecord({ [key]: selectedValue }, lookupEntity.id)
|
|
582
|
+
.then(data => {
|
|
583
|
+
if (data.entity) {
|
|
584
|
+
updateSelectedValue(data.entity);
|
|
585
|
+
}
|
|
586
|
+
})
|
|
587
|
+
.catch(error => {
|
|
588
|
+
console.error(error);
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
const lookupGrid = new ui.EasyGrid({
|
|
592
|
+
slot: gridSlot,
|
|
593
|
+
dataTable: lookupTable,
|
|
594
|
+
fixHeightOnFirstRender: true,
|
|
595
|
+
paging: {
|
|
596
|
+
pageSize: 10
|
|
597
|
+
},
|
|
598
|
+
onActiveRowChanged: (ev) => {
|
|
599
|
+
lookupGrid.getData().getRow(ev.rowIndex)
|
|
600
|
+
.then((row) => {
|
|
601
|
+
selectedValue = row.getValue(attr.lookupDataAttr);
|
|
602
|
+
updateSelectedValue(row);
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
ds.open({
|
|
607
|
+
title: core.i18n.getText('LookupDlgCaption')
|
|
608
|
+
.replace('{entity}', lookupEntity.caption),
|
|
609
|
+
body: slot,
|
|
610
|
+
arrangeParents: true,
|
|
611
|
+
beforeOpen: () => {
|
|
612
|
+
const dataFilter = this.context.createFilter(lookupEntity.id, lookupGrid.getData(), true);
|
|
613
|
+
new TextFilterWidget(widgetSlot, lookupGrid, dataFilter, { instantMode: true, focus: true });
|
|
614
|
+
},
|
|
615
|
+
onSubmit: () => {
|
|
616
|
+
inputEl.value = selectedValue;
|
|
617
|
+
return true;
|
|
618
|
+
},
|
|
619
|
+
onDestroy: () => {
|
|
620
|
+
lookupGrid.destroy();
|
|
621
|
+
// return focus on button
|
|
622
|
+
b.toDOM().focus();
|
|
623
|
+
}
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
}));
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
setupDateTimeField(parent, attr, value, readOnly, hidden) {
|
|
630
|
+
const horizClass = isIE
|
|
631
|
+
? 'kfrm-fields-ie is-horizontal'
|
|
632
|
+
: 'kfrm-fields is-horizontal';
|
|
633
|
+
const editFormat = getEditDateTimeFormat(attr.dataType);
|
|
634
|
+
let inputEl;
|
|
635
|
+
const mask = editFormat
|
|
636
|
+
.replace('yyyy', '9999')
|
|
637
|
+
.replace('MM', '99')
|
|
638
|
+
.replace('dd', '99')
|
|
639
|
+
.replace('HH', '99')
|
|
640
|
+
.replace('mm', '99')
|
|
641
|
+
.replace('ss', '99');
|
|
642
|
+
ui.domel(parent)
|
|
643
|
+
.addChild('div', b => {
|
|
644
|
+
b
|
|
645
|
+
.addClass(horizClass)
|
|
646
|
+
.addChild('input', b => {
|
|
647
|
+
inputEl = b.toDOM();
|
|
648
|
+
b.name(attr.id);
|
|
649
|
+
b.type(hidden ? 'hidden' : this.resolveInputType(attr.dataType));
|
|
650
|
+
if (readOnly) {
|
|
651
|
+
b.attr('readonly', '');
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
b.mask(mask);
|
|
655
|
+
b.on('keypress', (ev) => this.applySumbit(ev))
|
|
656
|
+
.on('input', ev => {
|
|
657
|
+
b.removeClass('is-invalid');
|
|
658
|
+
try {
|
|
659
|
+
const newDate = core.utils.strToDateTime(inputEl.value, editFormat);
|
|
660
|
+
}
|
|
661
|
+
catch (e) {
|
|
662
|
+
b.addClass('is-invalid');
|
|
663
|
+
}
|
|
664
|
+
finally {
|
|
665
|
+
}
|
|
666
|
+
})
|
|
667
|
+
.on('blur', ev => {
|
|
668
|
+
if (inputEl.value === mask.replace(/[9]/g, '_')) {
|
|
669
|
+
inputEl.value = '';
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
b.value((core.utils.IsDefinedAndNotNull(value)
|
|
674
|
+
? core.i18n.dateTimeToStr(value, editFormat)
|
|
675
|
+
: ''));
|
|
676
|
+
});
|
|
677
|
+
if (!readOnly)
|
|
678
|
+
b.addChild('button', b => b
|
|
679
|
+
.addClass('kfrm-button')
|
|
680
|
+
.attr('title', core.i18n.getText(attr.dataType !== core.DataType.Time
|
|
681
|
+
? 'CalendarBtnTitle'
|
|
682
|
+
: 'TimerBtnTitle'))
|
|
683
|
+
.addChild('i', b => b.addClass(attr.dataType !== core.DataType.Time
|
|
684
|
+
? 'ed-calendar-icon'
|
|
685
|
+
: 'ed-timer-icon'))
|
|
686
|
+
.on('click', (ev) => {
|
|
687
|
+
let value;
|
|
688
|
+
try {
|
|
689
|
+
value = inputEl.value.length
|
|
690
|
+
? attr.dataType !== core.DataType.Time
|
|
691
|
+
? core.utils.strToDateTime(inputEl.value, editFormat)
|
|
692
|
+
: core.utils.strToTime(inputEl.value)
|
|
693
|
+
: new Date(new Date().setSeconds(0));
|
|
694
|
+
}
|
|
695
|
+
catch (_a) {
|
|
696
|
+
value = new Date(new Date().setSeconds(0));
|
|
697
|
+
}
|
|
698
|
+
const pickerOptions = {
|
|
699
|
+
zIndex: 9999999999,
|
|
700
|
+
showCalendar: attr.dataType !== core.DataType.Time,
|
|
701
|
+
showTimePicker: attr.dataType !== core.DataType.Date,
|
|
702
|
+
onApply: (dateTime) => {
|
|
703
|
+
dateTime.setSeconds(0);
|
|
704
|
+
dateTime.setMilliseconds(0);
|
|
705
|
+
inputEl.value = core.i18n.dateTimeToStr(dateTime, editFormat);
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
const dtp = new ui.DefaultDateTimePicker(pickerOptions);
|
|
709
|
+
dtp.setDateTime(value);
|
|
710
|
+
dtp.show(ev.target);
|
|
711
|
+
}).toDOM());
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
setupListField(parent, attr, value, values, readOnly) {
|
|
715
|
+
ui.domel(parent)
|
|
716
|
+
.addChild('div', b => b
|
|
717
|
+
.addClass('kfrm-select full-width')
|
|
718
|
+
.addChild('select', b => {
|
|
719
|
+
if (readOnly)
|
|
720
|
+
b.attr('readonly', '');
|
|
721
|
+
b.attr('name', attr.id);
|
|
722
|
+
b.on('keypress', (ev) => this.applySumbit(ev));
|
|
723
|
+
if (values) {
|
|
724
|
+
for (let i = 0; i < values.length; i++) {
|
|
725
|
+
const val = values[i];
|
|
726
|
+
b.addOption({
|
|
727
|
+
value: val.id,
|
|
728
|
+
title: val.text,
|
|
729
|
+
selected: i === 0
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
b.value(value);
|
|
734
|
+
}));
|
|
735
|
+
}
|
|
736
|
+
setupFileField(parent, attr, readOnly, accept) {
|
|
737
|
+
ui.domel(parent)
|
|
738
|
+
.addChild('input', b => {
|
|
739
|
+
if (readOnly)
|
|
740
|
+
b.attr('readonly', '');
|
|
741
|
+
b.name(attr.id)
|
|
742
|
+
.type(this.resolveInputType(attr.dataType));
|
|
743
|
+
b.attr('accept', accept);
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
setupTextField(parent, attr, value, readOnly, hidden) {
|
|
747
|
+
ui.domel(parent)
|
|
748
|
+
.addChild('input', b => {
|
|
749
|
+
if (readOnly) {
|
|
750
|
+
b.attr('readonly', '');
|
|
751
|
+
}
|
|
752
|
+
b.type(hidden ? 'hidden' : this.resolveInputType(attr.dataType));
|
|
753
|
+
b.name(attr.id)
|
|
754
|
+
.type(this.resolveInputType(attr.dataType));
|
|
755
|
+
if (attr.dataType == core.DataType.Bool) {
|
|
756
|
+
if (value)
|
|
757
|
+
b.attr('checked', '');
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
b.on('keypress', (ev) => this.applySumbit(ev))
|
|
761
|
+
.value(core.utils.IsDefinedAndNotNull(value)
|
|
762
|
+
? value.toString()
|
|
763
|
+
: '');
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
setupTextArea(parent, attr, value, readOnly) {
|
|
768
|
+
// feature: modify size in value editor ??
|
|
769
|
+
ui.domel(parent)
|
|
770
|
+
.addChild('textarea', b => {
|
|
771
|
+
if (readOnly)
|
|
772
|
+
b.attr('readonly', '');
|
|
773
|
+
b.attr('name', attr.id);
|
|
774
|
+
b.setStyle('height', `120px`);
|
|
775
|
+
b.value(core.utils.IsDefinedAndNotNull(value)
|
|
776
|
+
? value.toString()
|
|
777
|
+
: '');
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
addFormField(parent, attr) {
|
|
781
|
+
const value = (this.params.values && attr.kind !== core.EntityAttrKind.Lookup)
|
|
782
|
+
? this.params.values.getValue(attr.id)
|
|
783
|
+
: !this.params.isEditForm
|
|
784
|
+
? attr.defaultValue
|
|
785
|
+
: undefined;
|
|
786
|
+
const editor = this.resolveEditor(attr);
|
|
787
|
+
const readOnly = this.params.isEditForm && (attr.isPrimaryKey || !attr.isEditable);
|
|
788
|
+
const required = !attr.isNullable;
|
|
789
|
+
if (isIE) {
|
|
790
|
+
parent = ui.domel('div', parent)
|
|
791
|
+
.addClass('kfrm-field-ie')
|
|
792
|
+
.toDOM();
|
|
793
|
+
}
|
|
794
|
+
ui.domel(parent)
|
|
795
|
+
.addChild('label', b => {
|
|
796
|
+
b.attr('for', attr.id);
|
|
797
|
+
b.addHtml(`${attr.caption} ${required ? '<sup style="color: red">*</sup>' : ''}: `);
|
|
798
|
+
if (attr.description) {
|
|
799
|
+
b.addChild('div', b => b
|
|
800
|
+
.attr('title', attr.description)
|
|
801
|
+
.addClass('question-mark')
|
|
802
|
+
.setStyle('vertical-align', 'middle')
|
|
803
|
+
.setStyle('display', 'inline-block'));
|
|
804
|
+
}
|
|
805
|
+
});
|
|
806
|
+
const hidden = attr.isPrimaryKey;
|
|
807
|
+
if (attr.kind === core.EntityAttrKind.Lookup) {
|
|
808
|
+
this.setupLookupField(parent, attr, readOnly, value);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
switch (editor.tag) {
|
|
812
|
+
case core.EditorTag.DateTime:
|
|
813
|
+
this.setupDateTimeField(parent, attr, value, readOnly, hidden);
|
|
814
|
+
break;
|
|
815
|
+
case core.EditorTag.List:
|
|
816
|
+
this.setupListField(parent, attr, value, editor.values, readOnly);
|
|
817
|
+
break;
|
|
818
|
+
case core.EditorTag.File:
|
|
819
|
+
this.setupFileField(parent, attr, readOnly, editor.accept);
|
|
820
|
+
break;
|
|
821
|
+
case core.EditorTag.Edit:
|
|
822
|
+
default:
|
|
823
|
+
if (editor.multiline) {
|
|
824
|
+
this.setupTextArea(parent, attr, value, readOnly);
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
this.setupTextField(parent, attr, value, readOnly, hidden);
|
|
828
|
+
}
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
resolveInputType(dataType) {
|
|
833
|
+
if (dataType === core.DataType.Bool)
|
|
834
|
+
return 'checkbox';
|
|
835
|
+
if (dataType === core.DataType.Blob)
|
|
836
|
+
return 'file';
|
|
837
|
+
return 'text';
|
|
838
|
+
}
|
|
839
|
+
resolveEditor(attr) {
|
|
840
|
+
let editor = attr.defaultEditor || new core.ValueEditor();
|
|
841
|
+
if (editor.tag == core.EditorTag.Unknown) {
|
|
842
|
+
if (core.utils.getDateDataTypes().indexOf(attr.dataType) >= 0) {
|
|
843
|
+
editor.tag = core.EditorTag.DateTime;
|
|
844
|
+
}
|
|
845
|
+
else {
|
|
846
|
+
editor.tag = core.EditorTag.Edit;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return editor;
|
|
850
|
+
}
|
|
851
|
+
applySumbit(ev) {
|
|
852
|
+
if (ev.keyCode === 13) {
|
|
853
|
+
this.sumbitCallback && this.sumbitCallback();
|
|
854
|
+
return false;
|
|
855
|
+
}
|
|
856
|
+
return false;
|
|
857
|
+
}
|
|
858
|
+
onSubmit(sumbitCallback) {
|
|
859
|
+
this.sumbitCallback = sumbitCallback;
|
|
860
|
+
return this;
|
|
861
|
+
}
|
|
862
|
+
build() {
|
|
863
|
+
let fb;
|
|
864
|
+
const formHtml = ui.domel('div')
|
|
865
|
+
.addClass('kfrm-form')
|
|
866
|
+
.addChild('div', b => b
|
|
867
|
+
.addClass(`errors-block`)
|
|
868
|
+
.toDOM())
|
|
869
|
+
.addChild('div', b => {
|
|
870
|
+
b.addClass(`${isIE
|
|
871
|
+
? 'kfrm-fields-ie col-ie-1-4 label-align-right'
|
|
872
|
+
: 'kfrm-fields col-a-1 label-align-right'}`);
|
|
873
|
+
fb = b;
|
|
874
|
+
})
|
|
875
|
+
.toDOM();
|
|
876
|
+
this.form['setHtmlInt'](formHtml);
|
|
877
|
+
for (const attr of this.context.getActiveEntity().attributes) {
|
|
878
|
+
if (!this.params.isEditForm && !attr.showOnCreate)
|
|
879
|
+
continue;
|
|
880
|
+
if (!attr.isPrimaryKey && this.params.isEditForm && !attr.showOnEdit) {
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
this.addFormField(fb.toDOM(), attr);
|
|
884
|
+
}
|
|
885
|
+
return this.form;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
class ProgressBar {
|
|
890
|
+
constructor(slot) {
|
|
891
|
+
this.slot = slot;
|
|
892
|
+
this.hide();
|
|
893
|
+
this.slot.classList.add('ed-progress-bar');
|
|
894
|
+
}
|
|
895
|
+
show() {
|
|
896
|
+
this.slot.style.removeProperty('display');
|
|
897
|
+
}
|
|
898
|
+
hide() {
|
|
899
|
+
this.slot.style.display = 'none';
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
class EasyDataServerLoader {
|
|
904
|
+
constructor(context) {
|
|
905
|
+
this.context = context;
|
|
906
|
+
}
|
|
907
|
+
loadChunk(params) {
|
|
908
|
+
const url = this.context.resolveEndpoint('FetchDataset', { sourceId: params.sourceId || this.context.getActiveEntity().id });
|
|
909
|
+
delete params.sourceId;
|
|
910
|
+
this.context.startProcess();
|
|
911
|
+
const http = this.context.getHttpClient();
|
|
912
|
+
return http.post(url, params)
|
|
913
|
+
.then((result) => {
|
|
914
|
+
const dataTable = new core.EasyDataTable({
|
|
915
|
+
chunkSize: 1000
|
|
916
|
+
});
|
|
917
|
+
const resultSet = result.resultSet;
|
|
918
|
+
for (const col of resultSet.cols) {
|
|
919
|
+
dataTable.columns.add(col);
|
|
920
|
+
}
|
|
921
|
+
for (const row of resultSet.rows) {
|
|
922
|
+
dataTable.addRow(row);
|
|
923
|
+
}
|
|
924
|
+
let totalRecords = 0;
|
|
925
|
+
if (result.meta && result.meta.totalRecords) {
|
|
926
|
+
totalRecords = result.meta.totalRecords;
|
|
927
|
+
}
|
|
928
|
+
return {
|
|
929
|
+
table: dataTable,
|
|
930
|
+
total: totalRecords,
|
|
931
|
+
hasNext: !params.needTotal
|
|
932
|
+
|| params.offset + params.limit < totalRecords
|
|
933
|
+
};
|
|
934
|
+
})
|
|
935
|
+
.finally(() => {
|
|
936
|
+
this.context.endProcess();
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
class DataContext {
|
|
942
|
+
constructor(options) {
|
|
943
|
+
this.endpoints = new Map();
|
|
944
|
+
this.endpointVarsRegex = /\{.*?\}/g;
|
|
945
|
+
this.options = options || {};
|
|
946
|
+
this.http = new core.HttpClient();
|
|
947
|
+
this.model = new core.MetaData();
|
|
948
|
+
this.model.id = options.metaDataId || '__default';
|
|
949
|
+
this.dataLoader = new EasyDataServerLoader(this);
|
|
950
|
+
const dataTableOptions = Object.assign({ loader: this.dataLoader }, options.dataTable);
|
|
951
|
+
this.data = new core.EasyDataTable(dataTableOptions);
|
|
952
|
+
this.setDefaultEndpoints(this.options.endpoint || '/api/easydata');
|
|
953
|
+
}
|
|
954
|
+
getActiveEntity() {
|
|
955
|
+
return this.activeEntity;
|
|
956
|
+
}
|
|
957
|
+
setActiveSource(entityId) {
|
|
958
|
+
this.activeEntity = this.model.getRootEntity().subEntities
|
|
959
|
+
.filter(e => e.id == entityId)[0];
|
|
960
|
+
}
|
|
961
|
+
getMetaData() {
|
|
962
|
+
return this.model;
|
|
963
|
+
}
|
|
964
|
+
getData() {
|
|
965
|
+
return this.data;
|
|
966
|
+
}
|
|
967
|
+
getDataLoader() {
|
|
968
|
+
return this.dataLoader;
|
|
969
|
+
}
|
|
970
|
+
createFilter(sourceId, data, isLookup) {
|
|
971
|
+
return new TextDataFilter(this.dataLoader, data || this.getData(), sourceId || this.activeEntity.id, isLookup);
|
|
972
|
+
}
|
|
973
|
+
loadMetaData() {
|
|
974
|
+
const url = this.resolveEndpoint('GetMetaData');
|
|
975
|
+
this.startProcess();
|
|
976
|
+
return this.http.get(url)
|
|
977
|
+
.then(result => {
|
|
978
|
+
if (result.model) {
|
|
979
|
+
this.model.loadFromData(result.model);
|
|
980
|
+
}
|
|
981
|
+
return this.model;
|
|
982
|
+
})
|
|
983
|
+
.catch(error => {
|
|
984
|
+
console.error(`Error: ${error.message}. Source: ${error.sourceError}`);
|
|
985
|
+
return null;
|
|
986
|
+
})
|
|
987
|
+
.finally(() => {
|
|
988
|
+
this.endProcess();
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
getHttpClient() {
|
|
992
|
+
return this.http;
|
|
993
|
+
}
|
|
994
|
+
fetchDataset() {
|
|
995
|
+
this.data.clear();
|
|
996
|
+
return this.dataLoader.loadChunk({ offset: 0, limit: this.data.chunkSize, needTotal: true })
|
|
997
|
+
.then(result => {
|
|
998
|
+
for (const col of result.table.columns.getItems()) {
|
|
999
|
+
this.data.columns.add(col);
|
|
1000
|
+
}
|
|
1001
|
+
this.data.setTotal(result.total);
|
|
1002
|
+
for (const row of result.table.getCachedRows()) {
|
|
1003
|
+
this.data.addRow(row);
|
|
1004
|
+
}
|
|
1005
|
+
return this.data;
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
fetchRecord(keys, sourceId) {
|
|
1009
|
+
const url = this.resolveEndpoint('FetchRecord', { sourceId: sourceId || this.activeEntity.id });
|
|
1010
|
+
this.startProcess();
|
|
1011
|
+
return this.http.get(url, { queryParams: keys })
|
|
1012
|
+
.finally(() => this.endProcess());
|
|
1013
|
+
}
|
|
1014
|
+
createRecord(obj, sourceId) {
|
|
1015
|
+
const url = this.resolveEndpoint('CreateRecord', { sourceId: sourceId || this.activeEntity.id });
|
|
1016
|
+
this.startProcess();
|
|
1017
|
+
return this.http.post(url, obj, { dataType: 'json' })
|
|
1018
|
+
.finally(() => this.endProcess());
|
|
1019
|
+
}
|
|
1020
|
+
updateRecord(obj, sourceId) {
|
|
1021
|
+
const url = this.resolveEndpoint('UpdateRecord', { sourceId: sourceId || this.activeEntity.id });
|
|
1022
|
+
this.startProcess();
|
|
1023
|
+
return this.http.post(url, obj, { dataType: 'json' })
|
|
1024
|
+
.finally(() => this.endProcess());
|
|
1025
|
+
}
|
|
1026
|
+
deleteRecord(obj, sourceId) {
|
|
1027
|
+
const url = this.resolveEndpoint('DeleteRecord', { sourceId: sourceId || this.activeEntity.id });
|
|
1028
|
+
this.startProcess();
|
|
1029
|
+
return this.http.post(url, obj, { dataType: 'json' })
|
|
1030
|
+
.finally(() => this.endProcess());
|
|
1031
|
+
}
|
|
1032
|
+
setEndpoint(key, value) {
|
|
1033
|
+
this.endpoints.set(key, value);
|
|
1034
|
+
}
|
|
1035
|
+
setEnpointIfNotExist(key, value) {
|
|
1036
|
+
if (!this.endpoints.has(key))
|
|
1037
|
+
this.endpoints.set(key, value);
|
|
1038
|
+
}
|
|
1039
|
+
resolveEndpoint(endpointKey, options) {
|
|
1040
|
+
options = options || {};
|
|
1041
|
+
let result = this.endpoints.get(endpointKey);
|
|
1042
|
+
if (!result) {
|
|
1043
|
+
throw endpointKey + ' endpoint is not defined';
|
|
1044
|
+
}
|
|
1045
|
+
let matches = result.match(this.endpointVarsRegex);
|
|
1046
|
+
if (matches) {
|
|
1047
|
+
for (let match of matches) {
|
|
1048
|
+
let opt = match.substring(1, match.length - 1);
|
|
1049
|
+
let optVal = options[opt];
|
|
1050
|
+
if (!optVal) {
|
|
1051
|
+
if (opt == 'modelId') {
|
|
1052
|
+
optVal = this.model.getId();
|
|
1053
|
+
}
|
|
1054
|
+
else if (opt == 'sourceId') {
|
|
1055
|
+
optVal = this.activeEntity.id;
|
|
1056
|
+
}
|
|
1057
|
+
else {
|
|
1058
|
+
throw `Parameter [${opt}] is not defined`;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
result = result.replace(match, optVal);
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
return result;
|
|
1065
|
+
}
|
|
1066
|
+
startProcess() {
|
|
1067
|
+
if (this.options.onProcessStart)
|
|
1068
|
+
this.options.onProcessStart();
|
|
1069
|
+
}
|
|
1070
|
+
endProcess() {
|
|
1071
|
+
if (this.options.onProcessEnd)
|
|
1072
|
+
this.options.onProcessEnd();
|
|
1073
|
+
}
|
|
1074
|
+
setDefaultEndpoints(endpointBase) {
|
|
1075
|
+
this.setEnpointIfNotExist('GetMetaData', core.combinePath(endpointBase, 'models/{modelId}'));
|
|
1076
|
+
this.setEnpointIfNotExist('FetchDataset', core.combinePath(endpointBase, 'models/{modelId}/sources/{sourceId}/fetch'));
|
|
1077
|
+
this.setEnpointIfNotExist('FetchRecord', core.combinePath(endpointBase, 'models/{modelId}/sources/{sourceId}/fetch'));
|
|
1078
|
+
this.setEnpointIfNotExist('CreateRecord', core.combinePath(endpointBase, 'models/{modelId}/sources/{sourceId}/create'));
|
|
1079
|
+
this.setEnpointIfNotExist('UpdateRecord', core.combinePath(endpointBase, 'models/{modelId}/sources/{sourceId}/update'));
|
|
1080
|
+
this.setEnpointIfNotExist('DeleteRecord', core.combinePath(endpointBase, 'models/{modelId}/sources/{sourceId}/delete'));
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
class TypeValidator extends Validator {
|
|
1085
|
+
constructor() {
|
|
1086
|
+
super();
|
|
1087
|
+
this.name = 'Type';
|
|
1088
|
+
}
|
|
1089
|
+
validate(attr, value) {
|
|
1090
|
+
if (!core.utils.IsDefinedAndNotNull(value) || value == '')
|
|
1091
|
+
return { successed: true };
|
|
1092
|
+
if (core.utils.isNumericType(attr.dataType)) {
|
|
1093
|
+
if (!core.utils.isNumeric(value))
|
|
1094
|
+
return {
|
|
1095
|
+
successed: false,
|
|
1096
|
+
messages: [core.i18n.getText('NumberError')]
|
|
1097
|
+
};
|
|
1098
|
+
if (core.utils.isIntType(attr.dataType)
|
|
1099
|
+
&& !Number.isInteger(Number.parseFloat(value))) {
|
|
1100
|
+
return {
|
|
1101
|
+
successed: false,
|
|
1102
|
+
messages: [core.i18n.getText('IntNumberError')]
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
return { successed: true };
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
class RequiredValidator extends Validator {
|
|
1111
|
+
constructor() {
|
|
1112
|
+
super();
|
|
1113
|
+
this.name = 'Required';
|
|
1114
|
+
}
|
|
1115
|
+
validate(attr, value) {
|
|
1116
|
+
if (!attr.isNullable && (!core.utils.IsDefinedAndNotNull(value)
|
|
1117
|
+
|| value === ''))
|
|
1118
|
+
return {
|
|
1119
|
+
successed: false,
|
|
1120
|
+
messages: [core.i18n.getText('RequiredError')]
|
|
1121
|
+
};
|
|
1122
|
+
return { successed: true };
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
class EntityDataView {
|
|
1127
|
+
constructor(slot, context, basePath, options) {
|
|
1128
|
+
this.slot = slot;
|
|
1129
|
+
this.context = context;
|
|
1130
|
+
this.basePath = basePath;
|
|
1131
|
+
this.options = {
|
|
1132
|
+
showFilterBox: true,
|
|
1133
|
+
showBackToEntities: true
|
|
1134
|
+
};
|
|
1135
|
+
this.defaultValidators = [new RequiredValidator(), new TypeValidator()];
|
|
1136
|
+
this.options = core.utils.assignDeep(this.options, options || {});
|
|
1137
|
+
this.dlg = new ui.DefaultDialogService();
|
|
1138
|
+
const ent = this.context.getActiveEntity();
|
|
1139
|
+
if (!ent) {
|
|
1140
|
+
throw "Can't find active entity for " + window.location.pathname;
|
|
1141
|
+
}
|
|
1142
|
+
this.slot.innerHTML += `<h1>${ent.captionPlural || ent.caption}</h1>`;
|
|
1143
|
+
if (this.options.showBackToEntities) {
|
|
1144
|
+
ui.domel(this.slot)
|
|
1145
|
+
.addChild('a', b => b
|
|
1146
|
+
.attr('href', 'javascript:void(0)')
|
|
1147
|
+
.text(`← ${core.i18n.getText('BackToEntities')}`)
|
|
1148
|
+
.on('click', (e) => {
|
|
1149
|
+
e.preventDefault();
|
|
1150
|
+
setLocation(this.basePath);
|
|
1151
|
+
}));
|
|
1152
|
+
}
|
|
1153
|
+
this.renderGrid();
|
|
1154
|
+
}
|
|
1155
|
+
syncGridColumnHandler(column) {
|
|
1156
|
+
if (column.dataColumn) {
|
|
1157
|
+
const attr = this.context.getMetaData().getAttributeById(column.dataColumn.id);
|
|
1158
|
+
if (attr) {
|
|
1159
|
+
column.isVisible = attr.showOnView;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
renderGrid() {
|
|
1164
|
+
this.context.fetchDataset()
|
|
1165
|
+
.then(result => {
|
|
1166
|
+
const gridSlot = document.createElement('div');
|
|
1167
|
+
this.slot.appendChild(gridSlot);
|
|
1168
|
+
gridSlot.id = 'Grid';
|
|
1169
|
+
this.grid = new ui.EasyGrid(core.utils.assignDeep({
|
|
1170
|
+
slot: gridSlot,
|
|
1171
|
+
dataTable: result,
|
|
1172
|
+
paging: {
|
|
1173
|
+
pageSize: 15,
|
|
1174
|
+
allowPageSizeChange: true,
|
|
1175
|
+
pageSizeItems: [15, 30, 50, 100, 200]
|
|
1176
|
+
},
|
|
1177
|
+
showPlusButton: this.context.getActiveEntity().isEditable,
|
|
1178
|
+
plusButtonTitle: core.i18n.getText('AddRecordBtnTitle'),
|
|
1179
|
+
showActiveRow: false,
|
|
1180
|
+
onPlusButtonClick: this.addClickHandler.bind(this),
|
|
1181
|
+
onGetCellRenderer: this.manageCellRenderer.bind(this),
|
|
1182
|
+
onRowDbClick: this.rowDbClickHandler.bind(this),
|
|
1183
|
+
onSyncGridColumn: this.syncGridColumnHandler.bind(this)
|
|
1184
|
+
}, this.options.grid || {}));
|
|
1185
|
+
if (this.options.showFilterBox) {
|
|
1186
|
+
let filterWidgetSlot;
|
|
1187
|
+
const filterBarDiv = ui.domel('div')
|
|
1188
|
+
.addClass(`kfrm-form`)
|
|
1189
|
+
.setStyle('margin', '10px 0px')
|
|
1190
|
+
.addChild('div', b => filterWidgetSlot = b.toDOM()).toDOM();
|
|
1191
|
+
this.slot.insertBefore(filterBarDiv, gridSlot);
|
|
1192
|
+
const dataFilter = this.context.createFilter();
|
|
1193
|
+
this.filterWidget = new TextFilterWidget(filterWidgetSlot, this.grid, dataFilter);
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
manageCellRenderer(column, defaultRenderer) {
|
|
1198
|
+
if (column.isRowNum) {
|
|
1199
|
+
column.width = 110;
|
|
1200
|
+
return (value, column, cell, rowEl) => {
|
|
1201
|
+
const b = ui.domel('div', cell)
|
|
1202
|
+
.addClass(`keg-cell-value`);
|
|
1203
|
+
if (this.context.getActiveEntity().isEditable) {
|
|
1204
|
+
b.addChild('a', b => b
|
|
1205
|
+
.attr('href', 'javascript:void(0)')
|
|
1206
|
+
.text(core.i18n.getText('EditBtn'))
|
|
1207
|
+
.on('click', (ev) => this.editClickHandler(ev, parseInt(rowEl.getAttribute('data-row-idx')))))
|
|
1208
|
+
.addChild('span', b => b.text(' | '))
|
|
1209
|
+
.addChild('a', b => b
|
|
1210
|
+
.attr('href', 'javascript:void(0)')
|
|
1211
|
+
.text(core.i18n.getText('DeleteBtn'))
|
|
1212
|
+
.on('click', (ev) => this.deleteClickHandler(ev, parseInt(rowEl.getAttribute('data-row-idx')))));
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
addClickHandler() {
|
|
1218
|
+
const activeEntity = this.context.getActiveEntity();
|
|
1219
|
+
const form = new EntityEditFormBuilder(this.context)
|
|
1220
|
+
.onSubmit(() => dlg.submit())
|
|
1221
|
+
.build();
|
|
1222
|
+
form.useValidators(this.defaultValidators);
|
|
1223
|
+
const dlg = this.dlg.open({
|
|
1224
|
+
title: core.i18n.getText('AddDlgCaption')
|
|
1225
|
+
.replace('{entity}', activeEntity.caption),
|
|
1226
|
+
body: form.getHtml(),
|
|
1227
|
+
onSubmit: () => {
|
|
1228
|
+
if (!form.validate())
|
|
1229
|
+
return false;
|
|
1230
|
+
form.getData()
|
|
1231
|
+
.then(obj => this.context.createRecord(obj))
|
|
1232
|
+
.then(() => {
|
|
1233
|
+
return this.refreshData();
|
|
1234
|
+
})
|
|
1235
|
+
.catch((error) => {
|
|
1236
|
+
this.processError(error);
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
editClickHandler(ev, rowIndex) {
|
|
1242
|
+
this.grid.getData().getRow(rowIndex)
|
|
1243
|
+
.then(row => {
|
|
1244
|
+
if (row) {
|
|
1245
|
+
this.showEditForm(row);
|
|
1246
|
+
}
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
showEditForm(row) {
|
|
1250
|
+
const activeEntity = this.context.getActiveEntity();
|
|
1251
|
+
const form = new EntityEditFormBuilder(this.context, { isEditForm: true, values: row })
|
|
1252
|
+
.onSubmit(() => dlg.submit())
|
|
1253
|
+
.build();
|
|
1254
|
+
form.useValidators(this.defaultValidators);
|
|
1255
|
+
const dlg = this.dlg.open({
|
|
1256
|
+
title: core.i18n.getText('EditDlgCaption')
|
|
1257
|
+
.replace('{entity}', activeEntity.caption),
|
|
1258
|
+
body: form.getHtml(),
|
|
1259
|
+
onSubmit: () => {
|
|
1260
|
+
if (!form.validate())
|
|
1261
|
+
return false;
|
|
1262
|
+
form.getData()
|
|
1263
|
+
.then(obj => this.context.updateRecord(obj))
|
|
1264
|
+
.then(() => {
|
|
1265
|
+
return this.refreshData();
|
|
1266
|
+
})
|
|
1267
|
+
.catch((error) => {
|
|
1268
|
+
this.processError(error);
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
rowDbClickHandler(ev) {
|
|
1274
|
+
if (this.context.getActiveEntity().isEditable) {
|
|
1275
|
+
this.showEditForm(ev.row);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
deleteClickHandler(ev, rowIndex) {
|
|
1279
|
+
this.grid.getData().getRow(rowIndex)
|
|
1280
|
+
.then(row => {
|
|
1281
|
+
if (row) {
|
|
1282
|
+
const activeEntity = this.context.getActiveEntity();
|
|
1283
|
+
const keyAttrs = activeEntity.getPrimaryAttrs();
|
|
1284
|
+
const keyVals = keyAttrs.map(attr => row.getValue(attr.id));
|
|
1285
|
+
const keys = keyAttrs.reduce((val, attr, index) => {
|
|
1286
|
+
const property = attr.id.substring(attr.id.lastIndexOf('.') + 1);
|
|
1287
|
+
val[property] = keyVals[index];
|
|
1288
|
+
return val;
|
|
1289
|
+
}, {});
|
|
1290
|
+
this.dlg.openConfirm(core.i18n.getText('DeleteDlgCaption')
|
|
1291
|
+
.replace('{entity}', activeEntity.caption), core.i18n.getText('DeleteDlgMessage')
|
|
1292
|
+
.replace('{recordId}', Object.keys(keys)
|
|
1293
|
+
.map(key => `${key}:${keys[key]}`).join(';')))
|
|
1294
|
+
.then((result) => {
|
|
1295
|
+
if (result) {
|
|
1296
|
+
this.context.deleteRecord(keys)
|
|
1297
|
+
.then(() => {
|
|
1298
|
+
return this.refreshData();
|
|
1299
|
+
})
|
|
1300
|
+
.catch((error) => {
|
|
1301
|
+
this.processError(error);
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1308
|
+
processError(error) {
|
|
1309
|
+
this.dlg.open({
|
|
1310
|
+
title: 'Ooops, something went wrong',
|
|
1311
|
+
body: error.message,
|
|
1312
|
+
closable: true,
|
|
1313
|
+
cancelable: false
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
refreshData() {
|
|
1317
|
+
return this.context.fetchDataset()
|
|
1318
|
+
.then(() => {
|
|
1319
|
+
let processed = false;
|
|
1320
|
+
if (this.filterWidget) {
|
|
1321
|
+
processed = this.filterWidget.applyFilter(false);
|
|
1322
|
+
}
|
|
1323
|
+
if (!processed) {
|
|
1324
|
+
this.grid.refresh();
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
class RootDataView {
|
|
1331
|
+
constructor(slot, context, basePath) {
|
|
1332
|
+
this.slot = slot;
|
|
1333
|
+
this.context = context;
|
|
1334
|
+
this.basePath = basePath;
|
|
1335
|
+
this.metaData = this.context.getMetaData();
|
|
1336
|
+
this.slot.innerHTML += `<h1>${core.i18n.getText('RootViewTitle')}</h1>`;
|
|
1337
|
+
this.renderEntitySelector();
|
|
1338
|
+
}
|
|
1339
|
+
renderEntitySelector() {
|
|
1340
|
+
const entities = this.metaData.getRootEntity().subEntities;
|
|
1341
|
+
if (this.slot) {
|
|
1342
|
+
ui.domel(this.slot)
|
|
1343
|
+
.addChild('div', b => b
|
|
1344
|
+
.addClass('ed-root')
|
|
1345
|
+
.addChild('div', b => b
|
|
1346
|
+
.addClass('ed-menu-description')
|
|
1347
|
+
.addText(core.i18n.getText(!this.metaData.isEmpty() ? 'EntityMenuDesc' : 'ModelIsEmpty')))
|
|
1348
|
+
.addChild('ul', b => {
|
|
1349
|
+
b.addClass('ed-entity-menu');
|
|
1350
|
+
entities.forEach(ent => {
|
|
1351
|
+
b.addChild('li', b => {
|
|
1352
|
+
b.addClass('ed-entity-item')
|
|
1353
|
+
.on('click', () => {
|
|
1354
|
+
setLocation(`${this.basePath}/${decodeURIComponent(ent.id)}`);
|
|
1355
|
+
})
|
|
1356
|
+
.addChild('div', b => {
|
|
1357
|
+
b.addClass('ed-entity-item-caption')
|
|
1358
|
+
.addText(ent.captionPlural || ent.caption);
|
|
1359
|
+
});
|
|
1360
|
+
if (ent.description) {
|
|
1361
|
+
b.addChild('div', b => {
|
|
1362
|
+
b.addClass('ed-entity-item-descr')
|
|
1363
|
+
.addText(`${ent.description}`);
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
});
|
|
1367
|
+
});
|
|
1368
|
+
}));
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
class EasyDataViewDispatcher {
|
|
1374
|
+
constructor(options) {
|
|
1375
|
+
this.options = {
|
|
1376
|
+
container: '#EasyDataContainer',
|
|
1377
|
+
basePath: 'easydata'
|
|
1378
|
+
};
|
|
1379
|
+
this.onSetLocation = () => {
|
|
1380
|
+
this.setActiveView();
|
|
1381
|
+
};
|
|
1382
|
+
this.attach = () => {
|
|
1383
|
+
window.addEventListener('ed_set_location', this.onSetLocation);
|
|
1384
|
+
window.addEventListener('popstate', this.onSetLocation);
|
|
1385
|
+
};
|
|
1386
|
+
this.options = core.utils.assign(this.options, options || {});
|
|
1387
|
+
if (this.options.rootEntity) {
|
|
1388
|
+
this.options.showBackToEntities = false;
|
|
1389
|
+
this.basePath = '/';
|
|
1390
|
+
}
|
|
1391
|
+
else {
|
|
1392
|
+
this.basePath = this.normalizeBasePath(this.options.basePath);
|
|
1393
|
+
}
|
|
1394
|
+
this.setContainer(this.options.container);
|
|
1395
|
+
const progressBarSlot = document.createElement('div');
|
|
1396
|
+
const bar = new ProgressBar(progressBarSlot);
|
|
1397
|
+
const parent = this.container.parentElement;
|
|
1398
|
+
parent.insertBefore(progressBarSlot, parent.firstElementChild);
|
|
1399
|
+
this.context = new DataContext({
|
|
1400
|
+
endpoint: this.options.endpoint,
|
|
1401
|
+
dataTable: this.options.dataTable,
|
|
1402
|
+
onProcessStart: () => bar.show(),
|
|
1403
|
+
onProcessEnd: () => bar.hide()
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
normalizeBasePath(basePath) {
|
|
1407
|
+
basePath = this.trimSlashes(basePath);
|
|
1408
|
+
const fullPath = decodeURIComponent(window.location.pathname);
|
|
1409
|
+
const idx = fullPath.toLocaleLowerCase().indexOf(basePath);
|
|
1410
|
+
return idx >= 0 ? fullPath.substring(0, idx + basePath.length) : '/';
|
|
1411
|
+
}
|
|
1412
|
+
trimSlashes(path) {
|
|
1413
|
+
return path.replace(/^\/|\/$/g, '');
|
|
1414
|
+
}
|
|
1415
|
+
setContainer(container) {
|
|
1416
|
+
if (!container) {
|
|
1417
|
+
throw 'Container is undefined';
|
|
1418
|
+
}
|
|
1419
|
+
if (typeof container === 'string') {
|
|
1420
|
+
if (container.length) {
|
|
1421
|
+
if (container[0] === '.') {
|
|
1422
|
+
const result = document.getElementsByClassName(container.substring(1));
|
|
1423
|
+
if (result.length)
|
|
1424
|
+
this.container = result[0];
|
|
1425
|
+
}
|
|
1426
|
+
else {
|
|
1427
|
+
if (container[0] === '#') {
|
|
1428
|
+
container = container.substring(1);
|
|
1429
|
+
}
|
|
1430
|
+
this.container = document.getElementById(container);
|
|
1431
|
+
}
|
|
1432
|
+
if (!this.container) {
|
|
1433
|
+
throw Error('Unrecognized `container` parameter: ' + container + '\n'
|
|
1434
|
+
+ 'It must be an element ID, a class name (starting with .) or an HTMLElement object itself.');
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
else {
|
|
1439
|
+
this.container = container;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
getActiveSourceId() {
|
|
1443
|
+
if (this.options.rootEntity)
|
|
1444
|
+
return this.options.rootEntity;
|
|
1445
|
+
const path = decodeURIComponent(window.location.pathname);
|
|
1446
|
+
const idIndex = this.basePath.length + 1;
|
|
1447
|
+
return idIndex < path.length ? path.substring(idIndex) : null;
|
|
1448
|
+
}
|
|
1449
|
+
run() {
|
|
1450
|
+
this.attach();
|
|
1451
|
+
return this.context.loadMetaData()
|
|
1452
|
+
.then(() => {
|
|
1453
|
+
this.setActiveView();
|
|
1454
|
+
})
|
|
1455
|
+
.catch(error => console.error(error));
|
|
1456
|
+
}
|
|
1457
|
+
setActiveView() {
|
|
1458
|
+
this.clear();
|
|
1459
|
+
const sourceId = this.getActiveSourceId();
|
|
1460
|
+
if (sourceId) {
|
|
1461
|
+
this.context.setActiveSource(sourceId);
|
|
1462
|
+
window['EDView'] = new EntityDataView(this.container, this.context, this.basePath, this.options);
|
|
1463
|
+
}
|
|
1464
|
+
else {
|
|
1465
|
+
window['EDView'] = new RootDataView(this.container, this.context, this.basePath);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
clear() {
|
|
1469
|
+
this.container.innerHTML = '';
|
|
1470
|
+
this.context.getData().clear();
|
|
1471
|
+
}
|
|
1472
|
+
detach() {
|
|
1473
|
+
window.removeEventListener('ed_set_location', this.onSetLocation);
|
|
1474
|
+
window.removeEventListener('popstate', this.onSetLocation);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
function addEasyDataCRUDTexts() {
|
|
1479
|
+
core.i18n.updateDefaultTexts({
|
|
1480
|
+
RequiredError: 'Value is required.',
|
|
1481
|
+
NumberError: 'Value should be a number',
|
|
1482
|
+
IntNumberError: 'Value should be an integer number',
|
|
1483
|
+
DateTimeError: 'Invalid date or time value',
|
|
1484
|
+
LookupSelectedItem: 'Selected item: ',
|
|
1485
|
+
LookupDlgCaption: 'Select {entity}',
|
|
1486
|
+
None: 'None',
|
|
1487
|
+
NavigationBtnTitle: 'Navigation values',
|
|
1488
|
+
CalendarBtnTitle: 'Open calendar',
|
|
1489
|
+
TimerBtnTitle: 'Open timer',
|
|
1490
|
+
AddBtnTitle: 'Add',
|
|
1491
|
+
AddRecordBtnTitle: 'Add record',
|
|
1492
|
+
EditBtn: 'Edit',
|
|
1493
|
+
DeleteBtn: 'Delete',
|
|
1494
|
+
SelectLink: '[ select ]',
|
|
1495
|
+
AddDlgCaption: 'Create {entity}',
|
|
1496
|
+
EditDlgCaption: 'Edit {entity}',
|
|
1497
|
+
DeleteDlgCaption: 'Delete {entity}',
|
|
1498
|
+
DeleteDlgMessage: 'Are you sure you want to remove this record: {{recordId}}?',
|
|
1499
|
+
EntityMenuDesc: 'Click on an entity to view/edit its content',
|
|
1500
|
+
BackToEntities: 'Back to entities',
|
|
1501
|
+
SearchBtn: 'Search',
|
|
1502
|
+
SearchInputPlaceholder: 'Search...',
|
|
1503
|
+
RootViewTitle: 'Entities',
|
|
1504
|
+
ModelIsEmpty: 'No entity was found.'
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
addEasyDataCRUDTexts();
|
|
1508
|
+
|
|
1509
|
+
exports.DataContext = DataContext;
|
|
1510
|
+
exports.EasyDataServerLoader = EasyDataServerLoader;
|
|
1511
|
+
exports.EasyDataViewDispatcher = EasyDataViewDispatcher;
|
|
1512
|
+
exports.EntityDataView = EntityDataView;
|
|
1513
|
+
exports.EntityEditForm = EntityEditForm;
|
|
1514
|
+
exports.EntityEditFormBuilder = EntityEditFormBuilder;
|
|
1515
|
+
exports.ProgressBar = ProgressBar;
|
|
1516
|
+
exports.RequiredValidator = RequiredValidator;
|
|
1517
|
+
exports.RootDataView = RootDataView;
|
|
1518
|
+
exports.TextDataFilter = TextDataFilter;
|
|
1519
|
+
exports.TextFilterWidget = TextFilterWidget;
|
|
1520
|
+
exports.TypeValidator = TypeValidator;
|
|
1521
|
+
exports.Validator = Validator;
|