UNPKG

pragma-views2

Version:

1 lines 14.5 kB
const helpers={parseDuration:null,parseDurationToDate:null,parseDurationToOnkeyFormat:null},valueFns={string:e=>new Function("sandbox",`with (sandbox) return sandbox.${e} == null ? "" : sandbox.${e}`),date:e=>new Function("sandbox",`with (sandbox) {const formattedDate = formattedDateToDate(sandbox.${e}); return formattedDate == null ? "" : formattedDate}`),datetime:e=>new Function("sandbox",`with (sandbox) {const formattedDate = formattedDateToDate(sandbox.${e}); return formattedDate == null ? "" : formattedDate}`),duration:e=>new Function("sandbox",`with (sandbox) {const durationDate = helpers.parseDurationToDate(sandbox.${e}); return durationDate == null ? new Date(1970, 0, 1) : durationDate}`),number:e=>new Function("sandbox",`with (sandbox) return sandbox.${e} == null ? -9999999 : sandbox.${e}`),time:e=>new Function("sandbox",`with (sandbox) {const formattedTime = formattedTimeToDate(sandbox.${e}); return formattedTime == null ? "" : formattedTime}`)};function _createConditionFn(e){const t=`with (sandbox) {return sandbox.${e.condition}}`;e.conditionFn=new Function("sandbox","args",t)}function _createValueFn(e,t){return(null!=valueFns[t]?valueFns[t]:valueFns.string)(_parsePath(e))}function _parsePath(e){if(null==e)return e;let t=e;return e.includes(".")&&!1===e.includes("?.")&&(t=e.replace(".","?.")),t}function padStart(e,t=2,n="0"){return null!=e?e.toString().padStart(t,n):null}function _splitWord(e){const t=(e=`${e.charAt(0).toUpperCase()}${e.slice(1)}`).match(/(^[a-z]|[A-Z0-9])[a-z]*/g),n=[];for(const e of t)e.length>1?n.push(` ${e}`):n.push(e);return n.join("").trim()}const dateOrderEnum=Object.freeze({Y:"year",M:"month",D:"day"}),dateFormatEnum=Object.freeze({YYYYMMDD:"YYYYMMDD"}),timeFormatEnum=Object.freeze({Clock12h:"Clock12h",Clock24h:"Clock24h"}),meridiemEnum=Object.freeze({AnteMeridiem:"AM",PostMeridiem:"PM"}),toTwentyFourHour=Object.freeze({12:0,1:13,2:14,3:15,4:16,5:17,6:18,7:19,8:20,9:21,10:22,11:23}),dataConstants=Object.freeze({TranslationPrefix:"translation_"});function convert_to_24(e,t,n){return n===timeFormatEnum.Clock24h?t:e===meridiemEnum.AnteMeridiem&&12===t?toTwentyFourHour[12]:e===meridiemEnum.PostMeridiem&&12===t?12:e===meridiemEnum.AnteMeridiem?t:toTwentyFourHour[t]}const validateDate=e=>{let t=!1;if(null!=e&&(e.month>0||e.month<=12)){const n=[31,28,31,30,31,30,31,31,30,31,30,31];(e.year%400==0||e.year%100!=0&&e.year%4==0)&&(n[1]=29),e.day>0&&e.day<=n[e.month-1]&&(t=!0)}return t};function formattedDateToDate(e,t=!1,n){let i=null;const r=n||globalThis.regionalSettings?.dateFormat||dateFormatEnum.YYYYMMDD;if(null==r||r.length<8)return i;if(null!=e&&""!==e&&e.length>=10){const n=[];let s=r;n.push(dateOrderEnum[s[0]]),s=s.slice("Y"===s[0]?4:2,s.length),n.push(dateOrderEnum[s[0]]),s=s.slice("Y"===s[0]?4:2,s.length),n.push(dateOrderEnum[s[0]]);const o=e.trim(),l={hours:"00",minutes:"00",seconds:"00",milliSeconds:"000"};if(o.length>=10){let e=o,t="year"===n[0]?4:2;l[n[0]]=e.slice(0,t),e=e.slice(t+1,e.length),t="year"===n[1]?4:2,l[n[1]]=e.slice(0,t),e=e.slice(t+1,e.length),t="year"===n[2]?4:2,l[n[2]]=e.slice(0,t)}if(!0===validateDate(l)){if(o.length>=16){const t=e.includes(meridiemEnum.AnteMeridiem)||e.includes(meridiemEnum.PostMeridiem);if(l.hours=o.substr(11,2),!0===t){const t=e.includes(meridiemEnum.AnteMeridiem)?meridiemEnum.AnteMeridiem:meridiemEnum.PostMeridiem;l.hours=padStart(convert_to_24(t,parseInt(l.hours),timeFormatEnum.Clock12h),2)}l.minutes=o.substr(14,2),l.seconds="00",l.milliSeconds="000",o.length>=19&&(l.seconds=o.substr(17,2)),o.length>=21&&(l.milliSeconds=o.substr(20,3))}let n=`${l.year}-${l.month}-${l.day}`;!1===t&&(n+=`T${l.hours}:${l.minutes}:${l.seconds}.${padStart(l.milliSeconds,3)}`),i=new Date(n)}}return i}function formattedTimeToDate(e){if(null==e)return null;const t=e.split(" "),n=t[0].split(":"),i=n[0],r=n[1],s=n[2],o=padStart(n[3]||"",3),l=t[1]||"",a=new Date;return formattedDateToDate(`${a.getFullYear()}/${padStart(a.getMonth(),2)}/${padStart(a.getDate(),2)}T${i}:${r}:${s}.${o} ${l}`,!1,dateFormatEnum.YYYYMMDD)}function parseArrayForCondition(e,t=[]){let n=[],i=t.reduce(((t,i)=>(!0===e(i)?n.push(i):t.push(i),t)),[]);return{matches:n,leftovers:i}}class PerspectiveWorker{constructor(){this.sortHelper=new SortHelper,this.aggregateHelper=new AggregateHelper,this.groupHelper=new GroupHelper(this.sortHelper,this.aggregateHelper),this.cache=new Map}dispose(){this.groupHelper.dispose(),this.groupHelper=null,this.sortHelper=null,this.aggregateHelper=null,this.cache.clear(),this.cache=null,this.translations=null,this.fields=null}_saveCache(e,t){let n=this.cache.get(e.datasourceKey);null==n&&(n={},this.cache.set(e.datasourceKey,n));const i=null!=e.perspective.groupings&&0===e.perspective.groupings.length?null:e.perspective.groupings;n[e.perspective.id]={items:t,groupingDefinition:i,aggregate:{}}}clear(e){this.cache.delete(e.options.datasourceKey)}async load(e){this.groupHelper.fields=e.options.fields;let t,n=e.options.items;null!=e.options.perspective.aggregate&&(t=await this.aggregateHelper.convertDefinition(e.options.perspective.aggregate),e.options.perspective.aggregate=this.aggregateHelper.process(n,t)),null!=e.options.perspective.sorting&&!0===Array.isArray(e.options.perspective.sorting)&&(n=this.sortHelper.applySorting(e.options.items,e.options.perspective.sorting,e.options.fields)),n=e.options.perspective.groupings&&e.options.perspective.groupings.length>0?await this.groupHelper.group(n,e.options.perspective.groupings):e.options.items,this._saveCache(e.options,n),postMessage({key:e.key,result:{items:n,aggregate:e.options.perspective.aggregate}})}async setup(e){this.translations=e.args.translations,globalThis.regionalSettings=e.args.regionalSettings,await this.setupFunctions(e.args.functions)}async setupFunctions(e){helpers.parseDuration=new Function("value",`${e.parseDuration};return parseDuration(value)`),helpers.parseDurationToDate=new Function("value",`${e.parseDurationToDate};return parseDurationToDate(value)`),helpers.parseDurationToOnkeyFormat=new Function("value","parseDuration",`${e.parseDurationToOnkeyFormat};return parseDurationToOnkeyFormat(value)`)}add(e){const t=this.cache.get(e.options.datasourceKey)[e.options.perspectiveId];let n=[];for(const i of e.options.items){let e;null!=t.groupingDefinition&&(e=this.groupHelper._addItemRecursively(t.groupingDefinition,t.items,i)),null==e&&(t.items.push(i),e=i),n.push(e)}null!=t.sorting?t.items=this.sortHelper.applySorting(t.items):this.sortHelper.applySortIndex(t.items),postMessage({key:e.key,result:{items:n}})}update(e){const t=this.cache.get(e.options.datasourceKey)[e.options.perspectiveId];let n,i,r=e.options.idField,s=[],o=[],l=[];null!=t.groupingDefinition&&(i=this._getGroupingFields(t.groupingDefinition));for(const a of e.options.oldItems){let u,p,g;const d=e.options.newItems.find((e=>e[r]===a[r]));null!=t.groupingDefinition&&(!1===this._groupingDataChanged(this._getUpdatedProperties(a,d),Array.from(i))?g=this.groupHelper._updateItemRecursively(t.groupingDefinition,t.items,d):(u=this.groupHelper._deleteItemRecursively(t.groupingDefinition,t.items,a),p=this.groupHelper._addItemRecursively(t.groupingDefinition,t.items,d))),null==g&&null==p&&(n=t.items.findIndex((e=>e[r]===a[r])),g=Object.assign(t.items[n],d)),u&&s.push(u),p&&o.push(p),g&&l.push(g)}null!=t.sorting?t.items=this.sortHelper.applySorting(t.items):this.sortHelper.applySortIndex(t.items),postMessage({key:e.key,result:{newItems:o,oldItems:s,updatedItems:l}})}_getGroupingFields(e){let t=new Set;for(const n of e)null!=n.field&&t.add(n.field),null!=n.groupings&&t.add(...this._getGroupingFields(n.groupings));return t}_getUpdatedProperties(e,t){const n=[],i=Object.keys(e);for(const r of i)e[r]!==t[r]&&n.push(r);return n}_groupingDataChanged(e,t){return t.some((t=>e.includes(t)))}delete(e){const t=this.cache.get(e.options.datasourceKey)[e.options.perspectiveId];let n=e.options.idField,i=[];for(const r of e.options.items){let e;null!=t.groupingDefinition&&(e=this.groupHelper._deleteItemRecursively(t.groupingDefinition,t.items,r)),null==e&&(e=t.items.splice(t.items.findIndex((e=>e[n]===r[n])),1)[0]),i.push(e)}postMessage({key:e.key,result:{items:i}})}onMessage(e){null!=this[e.data.type]&&this[e.data.type](e.data)}}class GroupHelper{constructor(e,t){this.sortHelper=e,this.aggregateHelper=t}dispose(){delete this.sortHelper,delete this.aggregateHelper}groupTitle(e,t,n){if(null==e||""===e)return perspectiveWorker.translations.nullValue;if("_*no-rights*_"===e)return`${_splitWord(t.name)} - ${perspectiveWorker.translations.limitedPermission}`;if(null!=t){if("duration"===t.type)return helpers.parseDurationToOnkeyFormat(e,helpers.parseDuration);if(null!=n&&Object.keys(n).includes(`${dataConstants.TranslationPrefix}${t.name}`))return n[`${dataConstants.TranslationPrefix}${t.name}`]}return e}_createFieldGroup(e,t,n,i){return{title:this.groupTitle(e,n,i),items:[],id:e,groupings:null!=t.groupings?this._cloneObject(t.groupings):null,aggregateDefinition:t.aggregateDefinition,aggregate:{},sorting:t.sorting,field:t.field,isGroup:!0}}async _setupGroupDefinition(e){null!=e.aggregate&&null==e.aggregateDefinition&&(e.aggregateDefinition=await this.aggregateHelper.convertDefinition(e.aggregate),e.aggregate={}),null!=e.condition&&null==e.conditionFn&&_createConditionFn(e)}_addItemRecursively(e,t,n){for(const i of e){let e;if(null!=i.condition&&!0===i.conditionFn(n)&&(e=t.find((e=>e.condition===i.condition)),null==e&&(e=this._cloneObject(i),e.id=i.condition,e.isGroup=!0,delete e.conditionFn,delete e.groupings,e.items=[],t.push(e))),null!=i.field&&(e=t.find((e=>e.id===n[i.field])),null==e&&(e=this._createFieldGroup(n[i.field],i,null,n),delete e.groupings,e.items=[],t.push(e))),null!=e){let t;null!=i.groupings&&(t=this._addItemRecursively(i.groupings,e.items,n)),null==t&&(e.items.push(n),t=n),null!=i.sorting?e.items=this.sortHelper.applySorting(e.items,i.sorting):this.sortHelper.applySortIndex(e.items),null!=e.aggregateDefinition&&(e.aggregate=this.aggregateHelper.recalculate(e.aggregateDefinition,e.items));let r=this._cloneObject(e);return r.items=[t],r}}}_updateItemRecursively(e,t,n){let i={};for(const r of e){let e;if(null!=r.condition&&!0===r.conditionFn(n)&&(e=t.find((e=>e.condition===r.condition))),null!=r.field&&(e=t.find((e=>e.id===n[r.field]))),null!=e){let t,s=e.items.findIndex((e=>e.id==n.id));-1!==s&&(t=[Object.assign(e.items[s],n)]),null==t&&null!=r.groupings&&(t=[this._updateItemRecursively(r.groupings,e.items,n)]),e.items=this.sortHelper.applySorting(e.items,r.sorting),null!=e.aggregateDefinition&&(e.aggregate=this.aggregateHelper.recalculate(e.aggregateDefinition,e.items)),i=this._cloneObject(e),delete i.conditionFn,delete i.groupings,i.items=t;break}}return i}_deleteItemRecursively(e,t,n){let i={};for(const r of e){let e;if(null!=r.condition&&!0===r.conditionFn(n)&&(e=t.find((e=>e.condition===r.condition))),null!=r.field&&(e=t.find((e=>e.id===n[r.field]))),null!=e){let t,s=e.items.findIndex((e=>e.id==n.id));-1!==s&&(t=e.items.splice(s,1)),null==t&&null!=r.groupings&&(t=[this._deleteItemRecursively(r.groupings,e.items,n)]),e.items=this.sortHelper.applySorting(e.items,r.sorting),null!=e.aggregateDefinition&&(e.aggregate=this.aggregateHelper.recalculate(e.aggregateDefinition,e.items)),i=this._cloneObject(e),delete i.conditionFn,delete i.groupings,i.items=t;break}}return i}async _createFieldGroups(e,t,n){const i=_parsePath(e.field);let r=new Function("item","args",`return item.${i}`),s=t.reduce(((t,i)=>{const s=r(i),o=""===s?null:s;return null==t[o]&&(t[o]=this._createFieldGroup(o,e,n,i)),t[o].items.push(i),t}),{});return Object.values(s)}async _processGroups(e,t){let n,i,r=[],s=!1;if(e.length>0&&null!=e[0].field){s=!0,i=e[0],await this._setupGroupDefinition(i);const r=this.fields?.find((e=>e.name===i.field));n=await this._createFieldGroups(i,t,r),t=[]}else n=this._cloneObject(e);for(let s=0;s<n.length;s++){let o=n[s];if(!0!==o.disabled){if(o.isGroup=!0,delete o.conditionFn,null!=o.condition){o.id=o.condition,i=e[s],await this._setupGroupDefinition(i),o.aggregateDefinition=i.aggregateDefinition;let n=parseArrayForCondition(i.conditionFn,t);o.items=n.matches,t=n.leftovers}if(this._calculateAggregates(o),null!=o.groupings){const e=i.groupings.filter((e=>!0!==e.disabled));o.items=await this._processGroups(e,o.items),delete o.groupings}o.items&&o.items.length>0&&r.push(o)}}return!0===s&&(null==i.sorting&&(i.sorting=[{fields:[{name:"title",value:"ascending"}]}]),r=this.sortHelper.applySorting(r,i.sorting)),[...r,...t]}_cloneObject(e){return JSON.parse(JSON.stringify(e))}_calculateAggregates(e){null!=e.aggregateDefinition&&(e.aggregate=this.aggregateHelper.process(e.items,e.aggregateDefinition))}async group(e,t){return await this._processGroups(t,e)}}class SortHelper{applySorting(e,t,n){if(null==t||0===t.length)return e;let i=e,r=[];for(const e of t){if(null==e.types&&(e.types={}),null!=n)for(const t of e.fields){const i=`${dataConstants.TranslationPrefix}${t.name}`;n.some((e=>e.name===i))&&(t.name=i);const r=n.find((e=>e.name===t.name));r&&(e.types[t.name]=r.type)}if(e.fieldFnMap=new Map(e.fields.map((t=>[t.name,_createValueFn(t.name,e.types[t.name])]))),null!=e.condition){_createConditionFn(e);let t=parseArrayForCondition(e.conditionFn,i);i=t.leftovers,r.push(...t.matches.sort(this.sortMultiple(e)))}else{const t=i.sort(this.sortMultiple(e));for(const e of t)r.push(e);i=[]}delete e.fieldFnMap}return r=[...r,...i],this.applySortIndex(r),r}applySortIndex(e){for(let t=0;t<e.length;t++)e[t].__sortIndex=t}sort(e,t,n){const i="descending"===t?-1:1;return(e,t)=>{const r=n(e),s=n(t);return(r<s?-1:r>s?1:0)*i}}sortMultiple(e){const t=e.fields.length;return(n,i)=>{let r=0,s=0;for(;0===r&&s<t;){const t=e.fields[s];r=this.sort(t.name,t.value,e.fieldFnMap.get(t.name))(n,i),s++}return r}}}class AggregateHelper{async convertDefinition(e){let t={};for(const n of e){const e=n.split(":");t[e[0]]=e[1]}return t}_recursiveGetAggregateValue(e,t,n){let i=null;for(const r of e)i=null!=r.items?t(this._recursiveGetAggregateValue(r.items,t,n),i):t(r[n],i);return i}recalculate(e,t){let n={};for(const i of Object.keys(e))n[i]=this._recursiveGetAggregateValue(t,this[i],e[i]);return n}count(e=1,t=0){return t+e}max(e,t){return null==t||e>t?e:t}min(e,t){return null==t||e<t?e:t}sum(e=0,t=0){return e+t}process(e,t){let n={};for(const i of Object.keys(t))for(const r of e)n[i]=this[i](r[t[i]],n[i]);return n}}const perspectiveWorker=new PerspectiveWorker;onmessage=function(e){perspectiveWorker.onMessage(e)};