UNPKG

136 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.gridjs = {}));
5}(this, (function (exports) { 'use strict';
6
7 /*! *****************************************************************************
8 Copyright (c) Microsoft Corporation.
9
10 Permission to use, copy, modify, and/or distribute this software for any
11 purpose with or without fee is hereby granted.
12
13 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 PERFORMANCE OF THIS SOFTWARE.
20 ***************************************************************************** */
21 /* global Reflect, Promise */
22
23 var extendStatics = function(d, b) {
24 extendStatics = Object.setPrototypeOf ||
25 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
26 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
27 return extendStatics(d, b);
28 };
29
30 function __extends(d, b) {
31 extendStatics(d, b);
32 function __() { this.constructor = d; }
33 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34 }
35
36 var __assign = function() {
37 __assign = Object.assign || function __assign(t) {
38 for (var s, i = 1, n = arguments.length; i < n; i++) {
39 s = arguments[i];
40 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
41 }
42 return t;
43 };
44 return __assign.apply(this, arguments);
45 };
46
47 function __awaiter(thisArg, _arguments, P, generator) {
48 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
49 return new (P || (P = Promise))(function (resolve, reject) {
50 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
51 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
52 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
53 step((generator = generator.apply(thisArg, _arguments || [])).next());
54 });
55 }
56
57 function __generator(thisArg, body) {
58 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
59 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
60 function verb(n) { return function (v) { return step([n, v]); }; }
61 function step(op) {
62 if (f) throw new TypeError("Generator is already executing.");
63 while (_) try {
64 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
65 if (y = 0, t) op = [op[0] & 2, t.value];
66 switch (op[0]) {
67 case 0: case 1: t = op; break;
68 case 4: _.label++; return { value: op[1], done: false };
69 case 5: _.label++; y = op[1]; op = [0]; continue;
70 case 7: op = _.ops.pop(); _.trys.pop(); continue;
71 default:
72 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
73 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
74 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
75 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
76 if (t[2]) _.ops.pop();
77 _.trys.pop(); continue;
78 }
79 op = body.call(thisArg, _);
80 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
81 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
82 }
83 }
84
85 function __spreadArrays() {
86 for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
87 for (var r = Array(s), k = 0, i = 0; i < il; i++)
88 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
89 r[k] = a[j];
90 return r;
91 }
92
93 var n,l,u,i,t,o,r,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n);}function v(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return h(n,f,i,t,null)}function h(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function y(){return {current:null}}function p(n){return n.children}function d(n,l){this.props=n,this.context=l;}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?_(n):null}function w(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return w(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!g.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i)(g);}function g(){for(var n;g.__r=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=s({},t)).__v=t.__v+1,$(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?_(t):o,t.__h),j(u,t),t.__e!=o&&w(t)));});}function m(n,l,u,i,t,o,r,c,s,v){var y,d,w,k,g,m,x,P=i&&i.__k||e,C=P.length;for(s==f&&(s=null!=r?r[0]:C?_(i,0):null),u.__k=[],y=0;y<l.length;y++)if(null!=(k=u.__k[y]=null==(k=l[y])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k?h(null,k,null,null,k):Array.isArray(k)?h(p,{children:k},null,null,null):k.__b>0?h(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(w=P[y])||w&&k.key==w.key&&k.type===w.type)P[y]=void 0;else for(d=0;d<C;d++){if((w=P[d])&&k.key==w.key&&k.type===w.type){P[d]=void 0;break}w=null;}$(n,k,w=w||f,t,o,r,c,s,v),g=k.__e,(d=k.ref)&&w.ref!=d&&(x||(x=[]),w.ref&&x.push(w.ref,null,k),x.push(d,k.__c||g,k)),null!=g?(null==m&&(m=g),"function"==typeof k.type&&k.__k===w.__k?k.__d=s=b(k,s,n):s=A(n,k,w,P,r,g,s),v||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&w.__e==s&&s.parentNode!=n&&(s=_(w));}if(u.__e=m,null!=r&&"function"!=typeof u.type)for(y=r.length;y--;)null!=r[y]&&a(r[y]);for(y=C;y--;)null!=P[y]&&("function"==typeof u.type&&null!=P[y].__e&&P[y].__e==u.__d&&(u.__d=_(i,y+1)),L(P[y],P[y]));if(x)for(y=0;y<x.length;y++)I(x[y],x[++y],x[++y]);}function b(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,"function"==typeof t.type?b(t,l,u):l=A(u,t,t,n.__k,null,t.__e,l));return l}function A(n,l,u,i,t,o,r){var f,e,c;if(void 0!==l.__d)f=l.__d,l.__d=void 0;else if(t==u||o!=r||null==o.parentNode)n:if(null==r||r.parentNode!==n)n.appendChild(o),f=null;else {for(e=r,c=0;(e=e.nextSibling)&&c<i.length;c+=2)if(e==o)break n;n.insertBefore(o,r),f=r;}return void 0!==f?f:o.nextSibling}function P(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||z(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||z(n,o,l[o],u[o],i);}function C(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||c.test(l)?u:u+"px";}function z(n,l,u,i,t){var o,r,f;if(t&&"className"==l&&(l="class"),"style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||C(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||C(n.style,l,u[l]);}else "o"===l[0]&&"n"===l[1]?(o=l!==(l=l.replace(/Capture$/,"")),(r=l.toLowerCase())in n&&(l=r),l=l.slice(2),n.l||(n.l={}),n.l[l+o]=u,f=o?T:N,u?i||n.addEventListener(l,f,o):n.removeEventListener(l,f,o)):"list"!==l&&"tagName"!==l&&"form"!==l&&"type"!==l&&"size"!==l&&"download"!==l&&"href"!==l&&!t&&l in n?n[l]=null==u?"":u:"function"!=typeof u&&"dangerouslySetInnerHTML"!==l&&(l!==(l=l.replace(/xlink:?/,""))?null==u||!1===u?n.removeAttributeNS("http://www.w3.org/1999/xlink",l.toLowerCase()):n.setAttributeNS("http://www.w3.org/1999/xlink",l.toLowerCase(),u):null==u||!1===u&&!/^ar/.test(l)?n.removeAttribute(l):n.setAttribute(l,u));}function N(l){this.l[l.type+!1](n.event?n.event(l):l);}function T(l){this.l[l.type+!0](n.event?n.event(l):l);}function $(l,u,i,t,o,r,f,e,c){var a,v,h,y,_,w,k,g,b,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,b=(a=P.contextType)&&t[a.__c],x=a?b?b.props.value:a.__:t,i.__c?k=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new d(g,x),v.constructor=P,v.render=M),b&&b.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=s({},v.__s)),s(v.__s,P.getDerivedStateFromProps(g,v.__s))),y=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==y&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(y,_,w);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=s(s({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(w=v.getSnapshotBeforeUpdate(y,_)),A=null!=a&&a.type===p&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,c),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),k&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=H(i.__e,u,i,t,o,r,f,c);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),n.__e(l,u,i);}}function j(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function H(n,l,u,i,t,o,r,c){var s,a,v,h,y,p=u.props,d=l.props;if(t="svg"===l.type||t,null!=o)for(s=0;s<o.length;s++)if(null!=(a=o[s])&&((null===l.type?3===a.nodeType:a.localName===l.type)||n==a)){n=a,o[s]=null;break}if(null==n){if(null===l.type)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",l.type):document.createElement(l.type,d.is&&{is:d.is}),o=null,c=!1;}if(null===l.type)p===d||c&&n.data===d||(n.data=d);else {if(null!=o&&(o=e.slice.call(n.childNodes)),v=(p=u.props||f).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}P(n,d,p,t,c),h?l.__k=[]:(s=l.props.children,m(n,Array.isArray(s)?s:[s],l,u,i,"foreignObject"!==l.type&&t,o,r,f,c)),c||("value"in d&&void 0!==(s=d.value)&&(s!==n.value||"progress"===l.type&&!s)&&z(n,"value",s,p.value,!1),"checked"in d&&void 0!==(s=d.checked)&&s!==n.checked&&z(n,"checked",s,p.checked,!1));}return n}function I(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||I(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L(t[r],u,i);null!=o&&a(o);}function M(n,l,u){return this.constructor(n,u)}function O(l,u,i){var t,r,c;n.__&&n.__(l,u),r=(t=i===o)?null:i&&i.__k||u.__k,l=v(p,null,[l]),c=[],$(u,(t?u:i||u).__k=l,r||f,f,void 0!==u.ownerSVGElement,i&&!t?[i]:r?null:u.childNodes.length?e.slice.call(u.childNodes):null,c,i||f,t),j(c,l);}function B(n,l){var u={__c:l="__cC"+r++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t,o=l.__h;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return l.__h=o,u.__E=u}catch(l){n=l;}throw n},__v:0},l=function(n){return null!=n&&void 0===n.constructor},d.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s({},this.state),"function"==typeof n&&(n=n(s({},u),this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},d.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},d.prototype.render=p,u=[],i="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,g.__r=0,o=f,r=0;
94
95 function generateUUID() {
96 return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
97 var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
98 return v.toString(16);
99 });
100 }
101
102 var Base = /** @class */ (function () {
103 function Base(id) {
104 this._id = id || generateUUID();
105 }
106 Object.defineProperty(Base.prototype, "id", {
107 get: function () {
108 return this._id;
109 },
110 enumerable: false,
111 configurable: true
112 });
113 return Base;
114 }());
115
116 /**
117 * This is a hack to get the current global config from Preact context.
118 * My assumption is that we only need one global context which is the ConfigContext
119 *
120 * @param context
121 */
122 function getConfig(context) {
123 if (!context)
124 return null;
125 var keys = Object.keys(context);
126 if (keys.length) {
127 // TODO: can we use a better way to capture and return the Config context?
128 var ctx = context[keys[0]];
129 return ctx.props.value;
130 }
131 return null;
132 }
133
134 var enUS = {
135 search: {
136 placeholder: 'Type a keyword...',
137 },
138 sort: {
139 sortAsc: 'Sort column ascending',
140 sortDesc: 'Sort column descending',
141 },
142 pagination: {
143 previous: 'Previous',
144 next: 'Next',
145 navigate: function (page, pages) { return "Page " + page + " of " + pages; },
146 page: function (page) { return "Page " + page; },
147 showing: 'Showing',
148 of: 'of',
149 to: 'to',
150 results: 'results',
151 },
152 loading: 'Loading...',
153 noRecordsFound: 'No matching records found',
154 error: 'An error happened while fetching the data',
155 };
156
157 var Translator = /** @class */ (function () {
158 function Translator(language) {
159 this._language = language;
160 this._defaultLanguage = enUS;
161 }
162 /**
163 * Tries to split the message with "." and find
164 * the key in the given language
165 *
166 * @param message
167 * @param lang
168 */
169 Translator.prototype.getString = function (message, lang) {
170 if (!lang || !message)
171 return null;
172 var splitted = message.split('.');
173 var key = splitted[0];
174 if (lang[key]) {
175 var val_1 = lang[key];
176 if (typeof val_1 === 'string') {
177 return function () { return val_1; };
178 }
179 else if (typeof val_1 === 'function') {
180 return val_1;
181 }
182 else {
183 return this.getString(splitted.slice(1).join('.'), val_1);
184 }
185 }
186 return null;
187 };
188 Translator.prototype.translate = function (message) {
189 var args = [];
190 for (var _i = 1; _i < arguments.length; _i++) {
191 args[_i - 1] = arguments[_i];
192 }
193 var translated = this.getString(message, this._language);
194 var messageFormat;
195 if (translated) {
196 messageFormat = translated;
197 }
198 else {
199 messageFormat = this.getString(message, this._defaultLanguage);
200 }
201 if (messageFormat) {
202 return messageFormat.apply(void 0, args);
203 }
204 return message;
205 };
206 return Translator;
207 }());
208 function useTranslator(translator) {
209 return function (message) {
210 var args = [];
211 for (var _i = 1; _i < arguments.length; _i++) {
212 args[_i - 1] = arguments[_i];
213 }
214 return translator.translate.apply(translator, __spreadArrays([message], args));
215 };
216 }
217
218 var BaseComponent = /** @class */ (function (_super) {
219 __extends(BaseComponent, _super);
220 function BaseComponent(props, context) {
221 var _this = _super.call(this, props, context) || this;
222 _this.config = getConfig(context);
223 if (_this.config) {
224 _this._ = useTranslator(_this.config.translator);
225 }
226 return _this;
227 }
228 return BaseComponent;
229 }(d));
230
231 var HTMLElement$1 = /** @class */ (function (_super) {
232 __extends(HTMLElement, _super);
233 function HTMLElement() {
234 return _super !== null && _super.apply(this, arguments) || this;
235 }
236 HTMLElement.prototype.render = function () {
237 return v(this.props.parentElement, {
238 dangerouslySetInnerHTML: { __html: this.props.content },
239 });
240 };
241 HTMLElement.defaultProps = {
242 parentElement: 'span',
243 };
244 return HTMLElement;
245 }(BaseComponent));
246
247 function decode(content) {
248 var value = new DOMParser().parseFromString(content, 'text/html');
249 return value.documentElement.textContent;
250 }
251 function html(content, parentElement) {
252 return v(HTMLElement$1, { content: content, parentElement: parentElement });
253 }
254
255 var Cell = /** @class */ (function (_super) {
256 __extends(Cell, _super);
257 function Cell(data) {
258 var _this = _super.call(this) || this;
259 _this.update(data);
260 return _this;
261 }
262 Cell.prototype.cast = function (data) {
263 if (data instanceof HTMLElement) {
264 return html(data.outerHTML);
265 }
266 return data;
267 };
268 /**
269 * Updates the Cell's data
270 *
271 * @param data
272 */
273 Cell.prototype.update = function (data) {
274 this.data = this.cast(data);
275 return this;
276 };
277 return Cell;
278 }(Base));
279
280 var Row = /** @class */ (function (_super) {
281 __extends(Row, _super);
282 function Row(cells) {
283 var _this = _super.call(this) || this;
284 _this.cells = cells || [];
285 return _this;
286 }
287 Row.prototype.cell = function (index) {
288 return this._cells[index];
289 };
290 Object.defineProperty(Row.prototype, "cells", {
291 get: function () {
292 return this._cells;
293 },
294 set: function (cells) {
295 this._cells = cells;
296 },
297 enumerable: false,
298 configurable: true
299 });
300 Row.prototype.toArray = function () {
301 return this.cells.map(function (cell) { return cell.data; });
302 };
303 /**
304 * Creates a new Row from an array of Cell(s)
305 * This method generates a new ID for the Row and all nested elements
306 *
307 * @param cells
308 * @returns Row
309 */
310 Row.fromCells = function (cells) {
311 return new Row(cells.map(function (cell) { return new Cell(cell.data); }));
312 };
313 Object.defineProperty(Row.prototype, "length", {
314 get: function () {
315 return this.cells.length;
316 },
317 enumerable: false,
318 configurable: true
319 });
320 return Row;
321 }(Base));
322
323 function oneDtoTwoD(data) {
324 if (data[0] && !(data[0] instanceof Array)) {
325 return [data];
326 }
327 return data;
328 }
329 function flatten(arrays) {
330 return arrays.reduce(function (prev, x) { return prev.concat(x); }, []);
331 }
332
333 var Tabular = /** @class */ (function (_super) {
334 __extends(Tabular, _super);
335 function Tabular(rows) {
336 var _this = _super.call(this) || this;
337 if (rows instanceof Array) {
338 _this.rows = rows;
339 }
340 else if (rows instanceof Row) {
341 _this.rows = [rows];
342 }
343 else {
344 _this.rows = [];
345 }
346 return _this;
347 }
348 Object.defineProperty(Tabular.prototype, "rows", {
349 get: function () {
350 return this._rows;
351 },
352 set: function (rows) {
353 this._rows = rows;
354 },
355 enumerable: false,
356 configurable: true
357 });
358 Object.defineProperty(Tabular.prototype, "length", {
359 get: function () {
360 return this._length || this.rows.length;
361 },
362 // we want to sent the length when storage is ServerStorage
363 set: function (len) {
364 this._length = len;
365 },
366 enumerable: false,
367 configurable: true
368 });
369 Tabular.prototype.toArray = function () {
370 return this.rows.map(function (row) { return row.toArray(); });
371 };
372 /**
373 * Creates a new Tabular from an array of Row(s)
374 * This method generates a new ID for the Tabular and all nested elements
375 *
376 * @param rows
377 * @returns Tabular
378 */
379 Tabular.fromRows = function (rows) {
380 return new Tabular(rows.map(function (row) { return Row.fromCells(row.cells); }));
381 };
382 /**
383 * Creates a new Tabular from a 2D array
384 * This method generates a new ID for the Tabular and all nested elements
385 *
386 * @param data
387 * @returns Tabular
388 */
389 Tabular.fromArray = function (data) {
390 data = oneDtoTwoD(data);
391 return new Tabular(data.map(function (row) { return new Row(row.map(function (cell) { return new Cell(cell); })); }));
392 };
393 return Tabular;
394 }(Base));
395
396 function search (keyword, tabular, selector) {
397 // escape special regex chars
398 keyword = keyword.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
399 return new Tabular(tabular.rows.filter(function (row, rowIndex) {
400 return row.cells.some(function (cell, cellIndex) {
401 if (!cell) {
402 return false;
403 }
404 var data = '';
405 if (typeof selector === 'function') {
406 data = selector(cell.data, rowIndex, cellIndex);
407 }
408 else if (typeof cell.data === 'object') {
409 // HTMLContent element
410 var element = cell.data;
411 if (element && element.props && element.props.content) {
412 // TODO: we should only search in the content of the element. props.content is the entire HTML element
413 data = element.props.content;
414 }
415 }
416 else {
417 // primitive types
418 data = String(cell.data);
419 }
420 return new RegExp(keyword, 'gi').test(data);
421 });
422 }));
423 }
424
425 var EventEmitter = /** @class */ (function () {
426 function EventEmitter() {
427 }
428 // because we are using EventEmitter as a mixin and the
429 // constructor won't be called by the applyMixins function
430 // see src/base.ts and src/util/applyMixin.ts
431 EventEmitter.prototype.init = function (event) {
432 if (!this.callbacks) {
433 this.callbacks = {};
434 }
435 if (event && !this.callbacks[event]) {
436 this.callbacks[event] = [];
437 }
438 };
439 EventEmitter.prototype.on = function (event, listener) {
440 this.init(event);
441 this.callbacks[event].push(listener);
442 return this;
443 };
444 EventEmitter.prototype.off = function (event, listener) {
445 var eventName = event;
446 this.init();
447 if (!this.callbacks[eventName] || this.callbacks[eventName].length === 0) {
448 // there is no callbacks with this key
449 return this;
450 }
451 this.callbacks[eventName] = this.callbacks[eventName].filter(function (value) { return value != listener; });
452 return this;
453 };
454 EventEmitter.prototype.emit = function (event) {
455 var args = [];
456 for (var _i = 1; _i < arguments.length; _i++) {
457 args[_i - 1] = arguments[_i];
458 }
459 var eventName = event;
460 this.init(eventName);
461 if (this.callbacks[eventName].length > 0) {
462 this.callbacks[eventName].forEach(function (value) { return value.apply(void 0, args); });
463 return true;
464 }
465 return false;
466 };
467 return EventEmitter;
468 }());
469
470 var ProcessorType;
471 (function (ProcessorType) {
472 ProcessorType[ProcessorType["Initiator"] = 0] = "Initiator";
473 ProcessorType[ProcessorType["ServerFilter"] = 1] = "ServerFilter";
474 ProcessorType[ProcessorType["ServerSort"] = 2] = "ServerSort";
475 ProcessorType[ProcessorType["ServerLimit"] = 3] = "ServerLimit";
476 ProcessorType[ProcessorType["Extractor"] = 4] = "Extractor";
477 ProcessorType[ProcessorType["Transformer"] = 5] = "Transformer";
478 ProcessorType[ProcessorType["Filter"] = 6] = "Filter";
479 ProcessorType[ProcessorType["Sort"] = 7] = "Sort";
480 ProcessorType[ProcessorType["Limit"] = 8] = "Limit";
481 })(ProcessorType || (ProcessorType = {}));
482 var PipelineProcessor = /** @class */ (function (_super) {
483 __extends(PipelineProcessor, _super);
484 function PipelineProcessor(props) {
485 var _this = _super.call(this) || this;
486 _this._props = {};
487 _this.id = generateUUID();
488 if (props)
489 _this.setProps(props);
490 return _this;
491 }
492 /**
493 * process is used to call beforeProcess and afterProcess callbacks
494 * This function is just a wrapper that calls _process()
495 *
496 * @param args
497 */
498 PipelineProcessor.prototype.process = function () {
499 var args = [];
500 for (var _i = 0; _i < arguments.length; _i++) {
501 args[_i] = arguments[_i];
502 }
503 if (this.validateProps instanceof Function) {
504 this.validateProps.apply(this, args);
505 }
506 this.emit.apply(this, __spreadArrays(['beforeProcess'], args));
507 var result = this._process.apply(this, args);
508 this.emit.apply(this, __spreadArrays(['afterProcess'], args));
509 return result;
510 };
511 PipelineProcessor.prototype.setProps = function (props) {
512 Object.assign(this._props, props);
513 this.emit('propsUpdated', this);
514 return this;
515 };
516 Object.defineProperty(PipelineProcessor.prototype, "props", {
517 get: function () {
518 return this._props;
519 },
520 enumerable: false,
521 configurable: true
522 });
523 return PipelineProcessor;
524 }(EventEmitter));
525
526 var GlobalSearchFilter = /** @class */ (function (_super) {
527 __extends(GlobalSearchFilter, _super);
528 function GlobalSearchFilter() {
529 return _super !== null && _super.apply(this, arguments) || this;
530 }
531 Object.defineProperty(GlobalSearchFilter.prototype, "type", {
532 get: function () {
533 return ProcessorType.Filter;
534 },
535 enumerable: false,
536 configurable: true
537 });
538 GlobalSearchFilter.prototype._process = function (data) {
539 if (this.props.keyword) {
540 return search(String(this.props.keyword).trim(), data, this.props.selector);
541 }
542 return data;
543 };
544 return GlobalSearchFilter;
545 }(PipelineProcessor));
546
547 function className() {
548 var args = [];
549 for (var _i = 0; _i < arguments.length; _i++) {
550 args[_i] = arguments[_i];
551 }
552 var prefix = 'gridjs';
553 return "" + prefix + args.reduce(function (prev, cur) { return prev + "-" + cur; }, '');
554 }
555 function classJoin() {
556 var classNames = [];
557 for (var _i = 0; _i < arguments.length; _i++) {
558 classNames[_i] = arguments[_i];
559 }
560 return (classNames
561 .filter(function (x) { return x; })
562 .reduce(function (className, prev) { return (className || '') + " " + prev; }, '')
563 .trim() || null);
564 }
565
566 var BaseStore = /** @class */ (function (_super) {
567 __extends(BaseStore, _super);
568 function BaseStore(dispatcher) {
569 var _this = _super.call(this) || this;
570 _this.dispatcher = dispatcher;
571 _this._state = _this.getInitialState();
572 dispatcher.register(_this._handle.bind(_this));
573 return _this;
574 }
575 BaseStore.prototype._handle = function (action) {
576 this.handle(action.type, action.payload);
577 };
578 BaseStore.prototype.setState = function (newState) {
579 var prevState = this._state;
580 this._state = newState;
581 this.emit('updated', newState, prevState);
582 };
583 Object.defineProperty(BaseStore.prototype, "state", {
584 get: function () {
585 return this._state;
586 },
587 enumerable: false,
588 configurable: true
589 });
590 return BaseStore;
591 }(EventEmitter));
592
593 var SearchStore = /** @class */ (function (_super) {
594 __extends(SearchStore, _super);
595 function SearchStore() {
596 return _super !== null && _super.apply(this, arguments) || this;
597 }
598 SearchStore.prototype.getInitialState = function () {
599 return { keyword: null };
600 };
601 SearchStore.prototype.handle = function (type, payload) {
602 if (type === 'SEARCH_KEYWORD') {
603 var keyword = payload.keyword;
604 this.search(keyword);
605 }
606 };
607 SearchStore.prototype.search = function (keyword) {
608 this.setState({ keyword: keyword });
609 };
610 return SearchStore;
611 }(BaseStore));
612
613 var BaseActions = /** @class */ (function () {
614 function BaseActions(dispatcher) {
615 this.dispatcher = dispatcher;
616 }
617 BaseActions.prototype.dispatch = function (type, payload) {
618 this.dispatcher.dispatch({
619 type: type,
620 payload: payload,
621 });
622 };
623 return BaseActions;
624 }());
625
626 var SearchActions = /** @class */ (function (_super) {
627 __extends(SearchActions, _super);
628 function SearchActions() {
629 return _super !== null && _super.apply(this, arguments) || this;
630 }
631 SearchActions.prototype.search = function (keyword) {
632 this.dispatch('SEARCH_KEYWORD', {
633 keyword: keyword,
634 });
635 };
636 return SearchActions;
637 }(BaseActions));
638
639 var ServerGlobalSearchFilter = /** @class */ (function (_super) {
640 __extends(ServerGlobalSearchFilter, _super);
641 function ServerGlobalSearchFilter() {
642 return _super !== null && _super.apply(this, arguments) || this;
643 }
644 Object.defineProperty(ServerGlobalSearchFilter.prototype, "type", {
645 get: function () {
646 return ProcessorType.ServerFilter;
647 },
648 enumerable: false,
649 configurable: true
650 });
651 ServerGlobalSearchFilter.prototype._process = function (options) {
652 if (!this.props.keyword)
653 return options;
654 var updates = {};
655 if (this.props.url) {
656 updates['url'] = this.props.url(options.url, this.props.keyword);
657 }
658 if (this.props.body) {
659 updates['body'] = this.props.body(options.body, this.props.keyword);
660 }
661 return __assign(__assign({}, options), updates);
662 };
663 return ServerGlobalSearchFilter;
664 }(PipelineProcessor));
665
666 var debounce = function (func, waitFor) {
667 var timeout;
668 return function () {
669 var args = [];
670 for (var _i = 0; _i < arguments.length; _i++) {
671 args[_i] = arguments[_i];
672 }
673 return new Promise(function (resolve) {
674 if (timeout) {
675 clearTimeout(timeout);
676 }
677 timeout = setTimeout(function () { return resolve(func.apply(void 0, args)); }, waitFor);
678 });
679 };
680 };
681
682 /**
683 * Centralized logging lib
684 *
685 * This class needs some improvements but so far it has been used to have a coherent way to log
686 */
687 var Logger = /** @class */ (function () {
688 function Logger() {
689 }
690 Logger.prototype.format = function (message, type) {
691 return "[Grid.js] [" + type.toUpperCase() + "]: " + message;
692 };
693 Logger.prototype.error = function (message, throwException) {
694 if (throwException === void 0) { throwException = false; }
695 var msg = this.format(message, 'error');
696 if (throwException) {
697 throw Error(msg);
698 }
699 else {
700 console.error(msg);
701 }
702 };
703 Logger.prototype.warn = function (message) {
704 console.warn(this.format(message, 'warn'));
705 };
706 Logger.prototype.info = function (message) {
707 console.info(this.format(message, 'info'));
708 };
709 return Logger;
710 }());
711 var log = new Logger();
712
713 /**
714 * BaseComponent for all plugins
715 */
716 var PluginBaseComponent = /** @class */ (function (_super) {
717 __extends(PluginBaseComponent, _super);
718 function PluginBaseComponent() {
719 return _super !== null && _super.apply(this, arguments) || this;
720 }
721 return PluginBaseComponent;
722 }(BaseComponent));
723 (function (PluginPosition) {
724 PluginPosition[PluginPosition["Header"] = 0] = "Header";
725 PluginPosition[PluginPosition["Footer"] = 1] = "Footer";
726 PluginPosition[PluginPosition["Cell"] = 2] = "Cell";
727 })(exports.PluginPosition || (exports.PluginPosition = {}));
728 var PluginManager = /** @class */ (function () {
729 function PluginManager() {
730 this.plugins = [];
731 }
732 PluginManager.prototype.get = function (id) {
733 var plugins = this.plugins.filter(function (p) { return p.id === id; });
734 if (plugins.length > 0) {
735 return plugins[0];
736 }
737 return null;
738 };
739 PluginManager.prototype.add = function (plugin) {
740 if (!plugin.id) {
741 log.error('Plugin ID cannot be empty');
742 return this;
743 }
744 if (this.get(plugin.id) !== null) {
745 log.error("Duplicate plugin ID: " + plugin.id);
746 return this;
747 }
748 this.plugins.push(plugin);
749 return this;
750 };
751 PluginManager.prototype.remove = function (id) {
752 this.plugins.splice(this.plugins.indexOf(this.get(id)), 1);
753 return this;
754 };
755 PluginManager.prototype.list = function (position) {
756 var plugins;
757 if (position != null || position != undefined) {
758 plugins = this.plugins.filter(function (p) { return p.position === position; });
759 }
760 else {
761 plugins = this.plugins;
762 }
763 return plugins.sort(function (a, b) { return a.order - b.order; });
764 };
765 return PluginManager;
766 }());
767 var PluginRenderer = /** @class */ (function (_super) {
768 __extends(PluginRenderer, _super);
769 function PluginRenderer() {
770 return _super !== null && _super.apply(this, arguments) || this;
771 }
772 PluginRenderer.prototype.render = function () {
773 var _this = this;
774 if (this.props.pluginId) {
775 // render a single plugin
776 var plugin = this.config.plugin.get(this.props.pluginId);
777 if (!plugin)
778 return null;
779 return v(p, {}, v(plugin.component, __assign(__assign({ plugin: plugin }, plugin.props), this.props.props)));
780 }
781 else if (this.props.position !== undefined) {
782 // render using a specific plugin position
783 return v(p, {}, this.config.plugin
784 .list(this.props.position)
785 .map(function (p) {
786 return v(p.component, __assign(__assign({ plugin: p }, p.props), _this.props.props));
787 }));
788 }
789 return null;
790 };
791 return PluginRenderer;
792 }(BaseComponent));
793
794 var Search = /** @class */ (function (_super) {
795 __extends(Search, _super);
796 function Search(props, context) {
797 var _this = _super.call(this, props, context) || this;
798 _this.actions = new SearchActions(_this.config.dispatcher);
799 _this.store = new SearchStore(_this.config.dispatcher);
800 var enabled = props.enabled, keyword = props.keyword;
801 if (enabled) {
802 // initial search
803 if (keyword)
804 _this.actions.search(keyword);
805 _this.storeUpdatedFn = _this.storeUpdated.bind(_this);
806 _this.store.on('updated', _this.storeUpdatedFn);
807 var searchProcessor = void 0;
808 if (props.server) {
809 searchProcessor = new ServerGlobalSearchFilter({
810 keyword: props.keyword,
811 url: props.server.url,
812 body: props.server.body,
813 });
814 }
815 else {
816 searchProcessor = new GlobalSearchFilter({
817 keyword: props.keyword,
818 selector: props.selector,
819 });
820 }
821 _this.searchProcessor = searchProcessor;
822 // adds a new processor to the pipeline
823 _this.config.pipeline.register(searchProcessor);
824 }
825 return _this;
826 }
827 Search.prototype.componentWillUnmount = function () {
828 this.config.pipeline.unregister(this.searchProcessor);
829 this.store.off('updated', this.storeUpdatedFn);
830 };
831 Search.prototype.storeUpdated = function (state) {
832 // updates the processor state
833 this.searchProcessor.setProps({
834 keyword: state.keyword,
835 });
836 };
837 Search.prototype.onChange = function (event) {
838 var keyword = event.target.value;
839 this.actions.search(keyword);
840 };
841 Search.prototype.render = function () {
842 if (!this.props.enabled)
843 return null;
844 var onInput = this.onChange.bind(this);
845 // add debounce to input only if it's a server-side search
846 if (this.searchProcessor instanceof ServerGlobalSearchFilter) {
847 onInput = debounce(onInput, this.props.debounceTimeout);
848 }
849 return (v("div", { className: className(classJoin('search', this.config.className.search)) },
850 v("input", { type: "search", placeholder: this._('search.placeholder'), "aria-label": this._('search.placeholder'), onInput: onInput, className: classJoin(className('input'), className('search', 'input')), value: this.store.state.keyword })));
851 };
852 Search.defaultProps = {
853 debounceTimeout: 250,
854 };
855 return Search;
856 }(PluginBaseComponent));
857
858 var PaginationLimit = /** @class */ (function (_super) {
859 __extends(PaginationLimit, _super);
860 function PaginationLimit() {
861 return _super !== null && _super.apply(this, arguments) || this;
862 }
863 PaginationLimit.prototype.validateProps = function () {
864 if (isNaN(Number(this.props.limit)) || isNaN(Number(this.props.page))) {
865 throw Error('Invalid parameters passed');
866 }
867 };
868 Object.defineProperty(PaginationLimit.prototype, "type", {
869 get: function () {
870 return ProcessorType.Limit;
871 },
872 enumerable: false,
873 configurable: true
874 });
875 PaginationLimit.prototype._process = function (data) {
876 var page = this.props.page;
877 var start = page * this.props.limit;
878 var end = (page + 1) * this.props.limit;
879 return new Tabular(data.rows.slice(start, end));
880 };
881 return PaginationLimit;
882 }(PipelineProcessor));
883
884 var ServerPaginationLimit = /** @class */ (function (_super) {
885 __extends(ServerPaginationLimit, _super);
886 function ServerPaginationLimit() {
887 return _super !== null && _super.apply(this, arguments) || this;
888 }
889 Object.defineProperty(ServerPaginationLimit.prototype, "type", {
890 get: function () {
891 return ProcessorType.ServerLimit;
892 },
893 enumerable: false,
894 configurable: true
895 });
896 ServerPaginationLimit.prototype._process = function (options) {
897 var updates = {};
898 if (this.props.url) {
899 updates['url'] = this.props.url(options.url, this.props.page, this.props.limit);
900 }
901 if (this.props.body) {
902 updates['body'] = this.props.body(options.body, this.props.page, this.props.limit);
903 }
904 return __assign(__assign({}, options), updates);
905 };
906 return ServerPaginationLimit;
907 }(PipelineProcessor));
908
909 var Pagination = /** @class */ (function (_super) {
910 __extends(Pagination, _super);
911 function Pagination(props, context) {
912 var _this = _super.call(this, props, context) || this;
913 _this.state = {
914 limit: props.limit,
915 page: props.page || 0,
916 total: 0,
917 };
918 return _this;
919 }
920 Pagination.prototype.componentWillMount = function () {
921 var _this = this;
922 if (this.props.enabled) {
923 var processor = void 0;
924 this.setTotalFromTabularFn = this.setTotalFromTabular.bind(this);
925 if (this.props.server) {
926 processor = new ServerPaginationLimit({
927 limit: this.state.limit,
928 page: this.state.page,
929 url: this.props.server.url,
930 body: this.props.server.body,
931 });
932 this.config.pipeline.on('afterProcess', this.setTotalFromTabularFn);
933 }
934 else {
935 processor = new PaginationLimit({
936 limit: this.state.limit,
937 page: this.state.page,
938 });
939 // Pagination (all Limit processors) is the last step in the pipeline
940 // and we assume that at this stage, we have the rows that we care about.
941 // Let's grab the rows before processing Pagination and set total number of rows
942 processor.on('beforeProcess', this.setTotalFromTabularFn);
943 }
944 this.processor = processor;
945 this.config.pipeline.register(processor);
946 // we need to make sure that the state is set
947 // to the default props when an error happens
948 this.config.pipeline.on('error', function () {
949 _this.setState({
950 total: 0,
951 page: 0,
952 });
953 });
954 }
955 };
956 Pagination.prototype.setTotalFromTabular = function (tabular) {
957 this.setTotal(tabular.length);
958 };
959 Pagination.prototype.onUpdate = function (processor) {
960 // this is to ensure that the current page is set to 0
961 // when a processor is updated for some reason
962 if (this.props.resetPageOnUpdate && processor !== this.processor) {
963 this.setPage(0);
964 }
965 };
966 Pagination.prototype.componentDidMount = function () {
967 this.onUpdateFn = this.onUpdate.bind(this);
968 this.config.pipeline.on('updated', this.onUpdateFn);
969 };
970 Pagination.prototype.componentWillUnmount = function () {
971 this.config.pipeline.unregister(this.processor);
972 this.config.pipeline.off('updated', this.onUpdateFn);
973 };
974 Object.defineProperty(Pagination.prototype, "pages", {
975 get: function () {
976 return Math.ceil(this.state.total / this.state.limit);
977 },
978 enumerable: false,
979 configurable: true
980 });
981 Pagination.prototype.setPage = function (page) {
982 if (page >= this.pages || page < 0 || page === this.state.page) {
983 return null;
984 }
985 this.setState({
986 page: page,
987 });
988 this.processor.setProps({
989 page: page,
990 });
991 };
992 Pagination.prototype.setTotal = function (totalRows) {
993 // to set the correct total number of rows
994 // when running in-memory operations
995 this.setState({
996 total: totalRows,
997 });
998 };
999 Pagination.prototype.renderPages = function () {
1000 var _this = this;
1001 if (this.props.buttonsCount <= 0) {
1002 return null;
1003 }
1004 // how many pagination buttons to render?
1005 var maxCount = Math.min(this.pages, this.props.buttonsCount);
1006 var pagePivot = Math.min(this.state.page, Math.floor(maxCount / 2));
1007 if (this.state.page + Math.floor(maxCount / 2) >= this.pages) {
1008 pagePivot = maxCount - (this.pages - this.state.page);
1009 }
1010 return (v(p, null,
1011 this.pages > maxCount && this.state.page - pagePivot > 0 && (v(p, null,
1012 v("button", { tabIndex: 0, role: "button", onClick: this.setPage.bind(this, 0), title: this._('pagination.firstPage'), "aria-label": this._('pagination.firstPage'), className: this.config.className.paginationButton }, this._('1')),
1013 v("button", { tabIndex: -1, className: classJoin(className('spread'), this.config.className.paginationButton) }, "..."))),
1014 Array.from(Array(maxCount).keys())
1015 .map(function (i) { return _this.state.page + (i - pagePivot); })
1016 .map(function (i) { return (v("button", { tabIndex: 0, role: "button", onClick: _this.setPage.bind(_this, i), className: classJoin(_this.state.page === i
1017 ? classJoin(className('currentPage'), _this.config.className.paginationButtonCurrent)
1018 : null, _this.config.className.paginationButton), title: _this._('pagination.page', i + 1), "aria-label": _this._('pagination.page', i + 1) }, _this._("" + (i + 1)))); }),
1019 this.pages > maxCount && this.pages > this.state.page + pagePivot + 1 && (v(p, null,
1020 v("button", { tabIndex: -1, className: classJoin(className('spread'), this.config.className.paginationButton) }, "..."),
1021 v("button", { tabIndex: 0, role: "button", onClick: this.setPage.bind(this, this.pages - 1), title: this._('pagination.page', this.pages), "aria-label": this._('pagination.page', this.pages), className: this.config.className.paginationButton }, this._("" + this.pages))))));
1022 };
1023 Pagination.prototype.renderSummary = function () {
1024 return (v(p, null, this.props.summary && this.state.total > 0 && (v("div", { role: "status", "aria-live": "polite", className: classJoin(className('summary'), this.config.className.paginationSummary), title: this._('pagination.navigate', this.state.page + 1, this.pages) },
1025 this._('pagination.showing'),
1026 ' ',
1027 v("b", null, this._("" + (this.state.page * this.state.limit + 1))),
1028 ' ',
1029 this._('pagination.to'),
1030 ' ',
1031 v("b", null, this._("" + Math.min((this.state.page + 1) * this.state.limit, this.state.total))),
1032 ' ',
1033 this._('pagination.of'),
1034 " ",
1035 v("b", null, this._("" + this.state.total)),
1036 ' ',
1037 this._('pagination.results')))));
1038 };
1039 Pagination.prototype.render = function () {
1040 if (!this.props.enabled)
1041 return null;
1042 return (v("div", { className: classJoin(className('pagination'), this.config.className.pagination) },
1043 this.renderSummary(),
1044 v("div", { className: className('pages') },
1045 this.props.prevButton && (v("button", { tabIndex: 0, role: "button", disabled: this.state.page === 0, onClick: this.setPage.bind(this, this.state.page - 1), title: this._('pagination.previous'), "aria-label": this._('pagination.previous'), className: classJoin(this.config.className.paginationButton, this.config.className.paginationButtonPrev) }, this._('pagination.previous'))),
1046 this.renderPages(),
1047 this.props.nextButton && (v("button", { tabIndex: 0, role: "button", disabled: this.pages === this.state.page + 1 || this.pages === 0, onClick: this.setPage.bind(this, this.state.page + 1), title: this._('pagination.next'), "aria-label": this._('pagination.next'), className: classJoin(this.config.className.paginationButton, this.config.className.paginationButtonNext) }, this._('pagination.next'))))));
1048 };
1049 Pagination.defaultProps = {
1050 summary: true,
1051 nextButton: true,
1052 prevButton: true,
1053 buttonsCount: 3,
1054 limit: 10,
1055 resetPageOnUpdate: true,
1056 };
1057 return Pagination;
1058 }(PluginBaseComponent));
1059
1060 function width(width, containerWidth) {
1061 if (typeof width == 'string') {
1062 if (width.indexOf('%') > -1) {
1063 return (containerWidth / 100) * parseInt(width, 10);
1064 }
1065 else {
1066 return parseInt(width, 10);
1067 }
1068 }
1069 return width;
1070 }
1071 function px(width) {
1072 if (!width)
1073 return '';
1074 return Math.floor(width) + "px";
1075 }
1076 /**
1077 * Accepts a ShadowTable and tries to find the clientWidth
1078 * that is already rendered on the web browser
1079 *
1080 * @param shadowTable
1081 * @param columnId
1082 */
1083 function getWidth(shadowTable, columnId) {
1084 if (!shadowTable) {
1085 return null;
1086 }
1087 var td = shadowTable.querySelector("thead th[data-column-id=\"" + columnId + "\"]");
1088 if (td) {
1089 return td.clientWidth;
1090 }
1091 return null;
1092 }
1093
1094 /**
1095 * ShadowTable renders a hidden table and is used to calculate the column's width
1096 * when autoWidth option is enabled
1097 */
1098 var ShadowTable = /** @class */ (function (_super) {
1099 __extends(ShadowTable, _super);
1100 function ShadowTable() {
1101 return _super !== null && _super.apply(this, arguments) || this;
1102 }
1103 ShadowTable.prototype.render = function () {
1104 if (this.props.tableRef.current) {
1105 var tableRef = this.props.tableRef;
1106 var tableElement_1 = tableRef.current.base.cloneNode(true);
1107 tableElement_1.className += " " + className('shadowTable');
1108 tableElement_1.style.position = 'absolute';
1109 tableElement_1.style.zIndex = '-2147483640';
1110 tableElement_1.style.visibility = 'hidden';
1111 tableElement_1.style.tableLayout = 'auto';
1112 tableElement_1.style.width = 'auto';
1113 tableElement_1.style.padding = '0';
1114 tableElement_1.style.margin = '0';
1115 tableElement_1.style.border = 'none';
1116 tableElement_1.style.outline = 'none';
1117 return (v("div", { ref: function (nodeElement) {
1118 nodeElement && nodeElement.appendChild(tableElement_1);
1119 } }));
1120 }
1121 return null;
1122 };
1123 return ShadowTable;
1124 }(BaseComponent));
1125
1126 function camelCase(str) {
1127 if (!str)
1128 return '';
1129 var words = str.split(' ');
1130 // do not convert strings that are already in camelCase format
1131 if (words.length === 1 && /([a-z][A-Z])+/g.test(str)) {
1132 return str;
1133 }
1134 return words
1135 .map(function (word, index) {
1136 // if it is the first word, lowercase all the chars
1137 if (index == 0) {
1138 return word.toLowerCase();
1139 }
1140 // if it is not the first word only upper case the first char and lowercase the rest
1141 return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
1142 })
1143 .join('');
1144 }
1145
1146 var Header = /** @class */ (function (_super) {
1147 __extends(Header, _super);
1148 function Header() {
1149 var _this = _super.call(this) || this;
1150 _this._columns = [];
1151 return _this;
1152 }
1153 Object.defineProperty(Header.prototype, "columns", {
1154 get: function () {
1155 return this._columns;
1156 },
1157 set: function (columns) {
1158 this._columns = columns;
1159 },
1160 enumerable: false,
1161 configurable: true
1162 });
1163 /**
1164 * Tries to automatically adjust the width of columns based on:
1165 * - Header cell content
1166 * - Cell content of the first row
1167 * - Cell content of the last row
1168 *
1169 * @param container
1170 * @param tableRef
1171 * @param tempRef
1172 * @param autoWidth
1173 */
1174 Header.prototype.adjustWidth = function (container, tableRef, tempRef, autoWidth) {
1175 if (autoWidth === void 0) { autoWidth = true; }
1176 if (!container) {
1177 // we can't calculate the width because the container
1178 // is unknown at this stage
1179 return this;
1180 }
1181 // pixels
1182 var containerWidth = container.clientWidth;
1183 // let's create a shadow table with the first 10 rows of the data
1184 // and let the browser to render the table with table-layout: auto
1185 // no padding, margin or border to get the minimum space required
1186 // to render columns. One the table is rendered and widths are known,
1187 // we unmount the shadow table from the DOM and set the correct width
1188 var shadowTable = y();
1189 if (tableRef.current && autoWidth) {
1190 // render a ShadowTable with the first 10 rows
1191 var el = v(ShadowTable, {
1192 tableRef: tableRef,
1193 });
1194 el.ref = shadowTable;
1195 O(el, tempRef.current);
1196 }
1197 for (var _i = 0, _a = flatten(Header.tabularFormat(this.columns)); _i < _a.length; _i++) {
1198 var column = _a[_i];
1199 // because we don't want to set the width of parent THs
1200 if (column.columns && column.columns.length > 0) {
1201 continue;
1202 }
1203 if (!column.width && autoWidth) {
1204 // tries to find the corresponding cell
1205 // from the ShadowTable and set the correct width
1206 column.width = px(getWidth(shadowTable.current.base, column.id));
1207 }
1208 else {
1209 // column with is already defined
1210 // sets the column with based on the width of its container
1211 column.width = px(width(column.width, containerWidth));
1212 }
1213 }
1214 if (tableRef.current && autoWidth) {
1215 // unmount the shadow table from temp
1216 O(null, tempRef.current);
1217 }
1218 return this;
1219 };
1220 Header.prototype.setSort = function (userConfig, columns) {
1221 var cols = columns || this.columns || [];
1222 for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) {
1223 var column = cols_1[_i];
1224 // sorting can only be enabled for columns without any children
1225 if (column.columns && column.columns.length > 0) {
1226 column.sort = {
1227 enabled: false,
1228 };
1229 }
1230 // implicit userConfig.sort flag
1231 if (column.sort === undefined && userConfig.sort) {
1232 column.sort = {
1233 enabled: true,
1234 };
1235 }
1236 // false, null, etc.
1237 if (!column.sort) {
1238 column.sort = {
1239 enabled: false,
1240 };
1241 }
1242 else if (typeof column.sort === 'object') {
1243 column.sort = __assign({ enabled: true }, column.sort);
1244 }
1245 if (column.columns) {
1246 this.setSort(userConfig, column.columns);
1247 }
1248 }
1249 };
1250 Header.prototype.setFixedHeader = function (userConfig, columns) {
1251 var cols = columns || this.columns || [];
1252 for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) {
1253 var column = cols_2[_i];
1254 if (column.fixedHeader === undefined) {
1255 column.fixedHeader = userConfig.fixedHeader;
1256 }
1257 if (column.columns) {
1258 this.setFixedHeader(userConfig, column.columns);
1259 }
1260 }
1261 };
1262 Header.prototype.setID = function (columns) {
1263 var cols = columns || this.columns || [];
1264 for (var _i = 0, cols_3 = cols; _i < cols_3.length; _i++) {
1265 var column = cols_3[_i];
1266 if (!column.id && typeof column.name === 'string') {
1267 // let's guess the column ID if it's undefined
1268 column.id = camelCase(column.name);
1269 }
1270 if (!column.id) {
1271 log.error("Could not find a valid ID for one of the columns. Make sure a valid \"id\" is set for all columns.");
1272 }
1273 // nested columns
1274 if (column.columns) {
1275 this.setID(column.columns);
1276 }
1277 }
1278 };
1279 Header.prototype.populatePlugins = function (userConfig, columns) {
1280 // populate the cell columns
1281 for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {
1282 var column = columns_1[_i];
1283 if (column.plugin !== undefined) {
1284 userConfig.plugin.add(__assign(__assign({ id: column.id, props: {} }, column.plugin), { position: exports.PluginPosition.Cell }));
1285 }
1286 }
1287 };
1288 Header.fromColumns = function (columns) {
1289 var header = new Header();
1290 for (var _i = 0, columns_2 = columns; _i < columns_2.length; _i++) {
1291 var column = columns_2[_i];
1292 if (typeof column === 'string' || l(column)) {
1293 header.columns.push({
1294 name: column,
1295 });
1296 }
1297 else if (typeof column === 'object') {
1298 var typedColumn = column;
1299 if (typedColumn.columns) {
1300 typedColumn.columns = Header.fromColumns(typedColumn.columns).columns;
1301 }
1302 // because the data for that cell is null
1303 // if we are trying to render a plugin
1304 if (typeof typedColumn.plugin === 'object') {
1305 if (typedColumn.data === undefined) {
1306 typedColumn.data = null;
1307 }
1308 }
1309 // TColumn type
1310 header.columns.push(column);
1311 }
1312 }
1313 return header;
1314 };
1315 Header.fromUserConfig = function (userConfig) {
1316 var header = new Header();
1317 // TODO: this part needs some refactoring
1318 if (userConfig.from) {
1319 header.columns = Header.fromHTMLTable(userConfig.from).columns;
1320 }
1321 else if (userConfig.columns) {
1322 header.columns = Header.fromColumns(userConfig.columns).columns;
1323 }
1324 else if (userConfig.data &&
1325 typeof userConfig.data[0] === 'object' &&
1326 !(userConfig.data[0] instanceof Array)) {
1327 // if data[0] is an object but not an Array
1328 // used for when a JSON payload is provided
1329 header.columns = Object.keys(userConfig.data[0]).map(function (name) {
1330 return { name: name };
1331 });
1332 }
1333 if (header.columns.length) {
1334 header.setID();
1335 header.setSort(userConfig);
1336 header.setFixedHeader(userConfig);
1337 header.populatePlugins(userConfig, header.columns);
1338 return header;
1339 }
1340 return null;
1341 };
1342 Header.fromHTMLTable = function (element) {
1343 var header = new Header();
1344 var thead = element.querySelector('thead');
1345 var ths = thead.querySelectorAll('th');
1346 for (var _i = 0, _a = ths; _i < _a.length; _i++) {
1347 var th = _a[_i];
1348 header.columns.push({
1349 name: th.innerHTML,
1350 width: th.width,
1351 });
1352 }
1353 return header;
1354 };
1355 /**
1356 * Converts the tree-like format of Header to a tabular format
1357 *
1358 * Example:
1359 *
1360 * H1
1361 * H1-H1
1362 * H1-H2
1363 * H2
1364 * H2-H1
1365 *
1366 * becomes:
1367 * [
1368 * [H1, H2],
1369 * [H1-H1, H1-H2, H2-H1]
1370 * ]
1371 *
1372 * @param columns
1373 */
1374 Header.tabularFormat = function (columns) {
1375 var result = [];
1376 var cols = columns || [];
1377 var nextRow = [];
1378 if (cols && cols.length) {
1379 result.push(cols);
1380 for (var _i = 0, cols_4 = cols; _i < cols_4.length; _i++) {
1381 var col = cols_4[_i];
1382 if (col.columns && col.columns.length) {
1383 nextRow = nextRow.concat(col.columns);
1384 }
1385 }
1386 if (nextRow.length) {
1387 result = result.concat(this.tabularFormat(nextRow));
1388 }
1389 }
1390 return result;
1391 };
1392 /**
1393 * Returns an array of leaf columns (last columns in the tree)
1394 *
1395 * @param columns
1396 */
1397 Header.leafColumns = function (columns) {
1398 var result = [];
1399 var cols = columns || [];
1400 if (cols && cols.length) {
1401 for (var _i = 0, cols_5 = cols; _i < cols_5.length; _i++) {
1402 var col = cols_5[_i];
1403 if (!col.columns || col.columns.length === 0) {
1404 result.push(col);
1405 }
1406 if (col.columns) {
1407 result = result.concat(this.leafColumns(col.columns));
1408 }
1409 }
1410 }
1411 return result;
1412 };
1413 /**
1414 * Returns the maximum depth of a column tree
1415 * @param column
1416 */
1417 Header.maximumDepth = function (column) {
1418 return this.tabularFormat([column]).length - 1;
1419 };
1420 return Header;
1421 }(Base));
1422
1423 var _prefix = 'ID_';
1424 /**
1425 * This class is mostly based on Flux's Dispatcher by Facebook
1426 * https://github.com/facebook/flux/blob/master/src/Dispatcher.js
1427 */
1428 var Dispatcher = /** @class */ (function () {
1429 function Dispatcher() {
1430 this._callbacks = {};
1431 this._isDispatching = false;
1432 this._isHandled = {};
1433 this._isPending = {};
1434 this._lastID = 1;
1435 }
1436 /**
1437 * Registers a callback to be invoked with every dispatched payload. Returns
1438 * a token that can be used with `waitFor()`.
1439 */
1440 Dispatcher.prototype.register = function (callback) {
1441 var id = _prefix + this._lastID++;
1442 this._callbacks[id] = callback;
1443 return id;
1444 };
1445 /**
1446 * Removes a callback based on its token.
1447 */
1448 Dispatcher.prototype.unregister = function (id) {
1449 if (!this._callbacks[id]) {
1450 throw Error("Dispatcher.unregister(...): " + id + " does not map to a registered callback.");
1451 }
1452 delete this._callbacks[id];
1453 };
1454 /**
1455 * Waits for the callbacks specified to be invoked before continuing execution
1456 * of the current callback. This method should only be used by a callback in
1457 * response to a dispatched payload.
1458 */
1459 Dispatcher.prototype.waitFor = function (ids) {
1460 if (!this._isDispatching) {
1461 throw Error('Dispatcher.waitFor(...): Must be invoked while dispatching.');
1462 }
1463 for (var ii = 0; ii < ids.length; ii++) {
1464 var id = ids[ii];
1465 if (this._isPending[id]) {
1466 if (!this._isHandled[id]) {
1467 throw Error("Dispatcher.waitFor(...): Circular dependency detected while ' +\n 'waiting for " + id + ".");
1468 }
1469 continue;
1470 }
1471 if (!this._callbacks[id]) {
1472 throw Error("Dispatcher.waitFor(...): " + id + " does not map to a registered callback.");
1473 }
1474 this._invokeCallback(id);
1475 }
1476 };
1477 /**
1478 * Dispatches a payload to all registered callbacks.
1479 */
1480 Dispatcher.prototype.dispatch = function (payload) {
1481 if (this._isDispatching) {
1482 throw Error('Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.');
1483 }
1484 this._startDispatching(payload);
1485 try {
1486 for (var id in this._callbacks) {
1487 if (this._isPending[id]) {
1488 continue;
1489 }
1490 this._invokeCallback(id);
1491 }
1492 }
1493 finally {
1494 this._stopDispatching();
1495 }
1496 };
1497 /**
1498 * Is this Dispatcher currently dispatching.
1499 */
1500 Dispatcher.prototype.isDispatching = function () {
1501 return this._isDispatching;
1502 };
1503 /**
1504 * Call the callback stored with the given id. Also do some internal
1505 * bookkeeping.
1506 *
1507 * @internal
1508 */
1509 Dispatcher.prototype._invokeCallback = function (id) {
1510 this._isPending[id] = true;
1511 this._callbacks[id](this._pendingPayload);
1512 this._isHandled[id] = true;
1513 };
1514 /**
1515 * Set up bookkeeping needed when dispatching.
1516 *
1517 * @internal
1518 */
1519 Dispatcher.prototype._startDispatching = function (payload) {
1520 for (var id in this._callbacks) {
1521 this._isPending[id] = false;
1522 this._isHandled[id] = false;
1523 }
1524 this._pendingPayload = payload;
1525 this._isDispatching = true;
1526 };
1527 /**
1528 * Clear bookkeeping used for dispatching.
1529 *
1530 * @internal
1531 */
1532 Dispatcher.prototype._stopDispatching = function () {
1533 delete this._pendingPayload;
1534 this._isDispatching = false;
1535 };
1536 return Dispatcher;
1537 }());
1538
1539 var Storage = /** @class */ (function () {
1540 function Storage() {
1541 }
1542 return Storage;
1543 }());
1544
1545 var MemoryStorage = /** @class */ (function (_super) {
1546 __extends(MemoryStorage, _super);
1547 function MemoryStorage(data) {
1548 var _this = _super.call(this) || this;
1549 _this.set(data);
1550 return _this;
1551 }
1552 MemoryStorage.prototype.get = function () {
1553 return __awaiter(this, void 0, void 0, function () {
1554 var data;
1555 return __generator(this, function (_a) {
1556 switch (_a.label) {
1557 case 0: return [4 /*yield*/, this.data()];
1558 case 1:
1559 data = _a.sent();
1560 return [2 /*return*/, {
1561 data: data,
1562 total: data.length,
1563 }];
1564 }
1565 });
1566 });
1567 };
1568 MemoryStorage.prototype.set = function (data) {
1569 if (data instanceof Array) {
1570 this.data = function () { return data; };
1571 }
1572 else if (data instanceof Function) {
1573 this.data = data;
1574 }
1575 return this;
1576 };
1577 return MemoryStorage;
1578 }(Storage));
1579
1580 var ServerStorage = /** @class */ (function (_super) {
1581 __extends(ServerStorage, _super);
1582 function ServerStorage(options) {
1583 var _this = _super.call(this) || this;
1584 _this.options = options;
1585 return _this;
1586 }
1587 ServerStorage.prototype.handler = function (response) {
1588 if (typeof this.options.handle === 'function') {
1589 return this.options.handle(response);
1590 }
1591 if (response.ok) {
1592 return response.json();
1593 }
1594 else {
1595 log.error("Could not fetch data: " + response.status + " - " + response.statusText, true);
1596 return null;
1597 }
1598 };
1599 ServerStorage.prototype.get = function (options) {
1600 // this.options is the initial config object
1601 // options is the runtime config passed by the pipeline (e.g. search component)
1602 var opts = __assign(__assign({}, this.options), options);
1603 // if `options.data` is provided, the current ServerStorage
1604 // implementation will be ignored and we let options.data to
1605 // handle the request. Useful when HTTP client needs to be
1606 // replaced with something else
1607 if (typeof opts.data === 'function') {
1608 return opts.data(opts);
1609 }
1610 return fetch(opts.url, opts)
1611 .then(this.handler.bind(this))
1612 .then(function (res) {
1613 return {
1614 data: opts.then(res),
1615 total: typeof opts.total === 'function' ? opts.total(res) : undefined,
1616 };
1617 });
1618 };
1619 return ServerStorage;
1620 }(Storage));
1621
1622 var StorageUtils = /** @class */ (function () {
1623 function StorageUtils() {
1624 }
1625 /**
1626 * Accepts the userConfig dict and tries to guess and return a Storage type
1627 *
1628 * @param userConfig
1629 */
1630 StorageUtils.createFromUserConfig = function (userConfig) {
1631 var storage = null;
1632 // `data` array is provided
1633 if (userConfig.data) {
1634 storage = new MemoryStorage(userConfig.data);
1635 }
1636 if (userConfig.from) {
1637 storage = new MemoryStorage(this.tableElementToArray(userConfig.from));
1638 // remove the source table element from the DOM
1639 userConfig.from.style.display = 'none';
1640 }
1641 if (userConfig.server) {
1642 storage = new ServerStorage(userConfig.server);
1643 }
1644 if (!storage) {
1645 log.error('Could not determine the storage type', true);
1646 }
1647 return storage;
1648 };
1649 /**
1650 * Accepts a HTML table element and converts it into a 2D array of data
1651 *
1652 * TODO: This function can be a step in the pipeline: Convert Table -> Load into a memory storage -> ...
1653 *
1654 * @param element
1655 */
1656 StorageUtils.tableElementToArray = function (element) {
1657 var arr = [];
1658 var tbody = element.querySelector('tbody');
1659 var rows = tbody.querySelectorAll('tr');
1660 for (var _i = 0, _a = rows; _i < _a.length; _i++) {
1661 var row = _a[_i];
1662 var cells = row.querySelectorAll('td');
1663 var parsedRow = [];
1664 for (var _b = 0, cells_1 = cells; _b < cells_1.length; _b++) {
1665 var cell = cells_1[_b];
1666 // try to capture a TD with single text element first
1667 if (cell.childNodes.length === 1 &&
1668 cell.childNodes[0].nodeType === Node.TEXT_NODE) {
1669 parsedRow.push(decode(cell.innerHTML));
1670 }
1671 else {
1672 parsedRow.push(html(cell.innerHTML));
1673 }
1674 }
1675 arr.push(parsedRow);
1676 }
1677 return arr;
1678 };
1679 return StorageUtils;
1680 }());
1681
1682 var Pipeline = /** @class */ (function (_super) {
1683 __extends(Pipeline, _super);
1684 function Pipeline(steps) {
1685 var _this = _super.call(this) || this;
1686 // available steps for this pipeline
1687 _this._steps = new Map();
1688 // used to cache the results of processors using their id field
1689 _this.cache = new Map();
1690 // keeps the index of the last updated processor in the registered
1691 // processors list and will be used to invalidate the cache
1692 // -1 means all new processors should be processed
1693 _this.lastProcessorIndexUpdated = -1;
1694 if (steps) {
1695 steps.forEach(function (step) { return _this.register(step); });
1696 }
1697 return _this;
1698 }
1699 /**
1700 * Clears the `cache` array
1701 */
1702 Pipeline.prototype.clearCache = function () {
1703 this.cache = new Map();
1704 this.lastProcessorIndexUpdated = -1;
1705 };
1706 /**
1707 * Registers a new processor
1708 *
1709 * @param processor
1710 * @param priority
1711 */
1712 Pipeline.prototype.register = function (processor, priority) {
1713 if (priority === void 0) { priority = null; }
1714 if (processor.type === null) {
1715 throw Error('Processor type is not defined');
1716 }
1717 // binding the propsUpdated callback to the Pipeline
1718 processor.on('propsUpdated', this.processorPropsUpdated.bind(this));
1719 this.addProcessorByPriority(processor, priority);
1720 this.afterRegistered(processor);
1721 };
1722 /**
1723 * Removes a processor from the list
1724 *
1725 * @param processor
1726 */
1727 Pipeline.prototype.unregister = function (processor) {
1728 if (!processor)
1729 return;
1730 var subSteps = this._steps.get(processor.type);
1731 if (subSteps && subSteps.length) {
1732 this._steps.set(processor.type, subSteps.filter(function (proc) { return proc != processor; }));
1733 this.emit('updated', processor);
1734 }
1735 };
1736 /**
1737 * Registers a new processor
1738 *
1739 * @param processor
1740 * @param priority
1741 */
1742 Pipeline.prototype.addProcessorByPriority = function (processor, priority) {
1743 var subSteps = this._steps.get(processor.type);
1744 if (!subSteps) {
1745 var newSubStep = [];
1746 this._steps.set(processor.type, newSubStep);
1747 subSteps = newSubStep;
1748 }
1749 if (priority === null || priority < 0) {
1750 subSteps.push(processor);
1751 }
1752 else {
1753 if (!subSteps[priority]) {
1754 // slot is empty
1755 subSteps[priority] = processor;
1756 }
1757 else {
1758 // slot is NOT empty
1759 var first = subSteps.slice(0, priority - 1);
1760 var second = subSteps.slice(priority + 1);
1761 this._steps.set(processor.type, first.concat(processor).concat(second));
1762 }
1763 }
1764 };
1765 Object.defineProperty(Pipeline.prototype, "steps", {
1766 /**
1767 * Flattens the _steps Map and returns a list of steps with their correct priorities
1768 */
1769 get: function () {
1770 var steps = [];
1771 for (var _i = 0, _a = this.getSortedProcessorTypes(); _i < _a.length; _i++) {
1772 var type = _a[_i];
1773 var subSteps = this._steps.get(type);
1774 if (subSteps && subSteps.length) {
1775 steps = steps.concat(subSteps);
1776 }
1777 }
1778 // to remove any undefined elements
1779 return steps.filter(function (s) { return s; });
1780 },
1781 enumerable: false,
1782 configurable: true
1783 });
1784 /**
1785 * Accepts ProcessType and returns an array of the registered processes
1786 * with the give type
1787 *
1788 * @param type
1789 */
1790 Pipeline.prototype.getStepsByType = function (type) {
1791 return this.steps.filter(function (process) { return process.type === type; });
1792 };
1793 /**
1794 * Returns a list of ProcessorType according to their priority
1795 */
1796 Pipeline.prototype.getSortedProcessorTypes = function () {
1797 return Object.keys(ProcessorType)
1798 .filter(function (key) { return !isNaN(Number(key)); })
1799 .map(function (key) { return Number(key); });
1800 };
1801 /**
1802 * Runs all registered processors based on their correct priority
1803 * and returns the final output after running all steps
1804 *
1805 * @param data
1806 */
1807 Pipeline.prototype.process = function (data) {
1808 return __awaiter(this, void 0, void 0, function () {
1809 var lastProcessorIndexUpdated, steps, prev, _i, steps_1, processor, processorIndex, e_1;
1810 return __generator(this, function (_a) {
1811 switch (_a.label) {
1812 case 0:
1813 lastProcessorIndexUpdated = this.lastProcessorIndexUpdated;
1814 steps = this.steps;
1815 prev = data;
1816 _a.label = 1;
1817 case 1:
1818 _a.trys.push([1, 7, , 8]);
1819 _i = 0, steps_1 = steps;
1820 _a.label = 2;
1821 case 2:
1822 if (!(_i < steps_1.length)) return [3 /*break*/, 6];
1823 processor = steps_1[_i];
1824 processorIndex = this.findProcessorIndexByID(processor.id);
1825 if (!(processorIndex >= lastProcessorIndexUpdated)) return [3 /*break*/, 4];
1826 return [4 /*yield*/, processor.process(prev)];
1827 case 3:
1828 // we should execute process() here since the last
1829 // updated processor was before "processor".
1830 // This is to ensure that we always have correct and up to date
1831 // data from processors and also to skip them when necessary
1832 prev = _a.sent();
1833 this.cache.set(processor.id, prev);
1834 return [3 /*break*/, 5];
1835 case 4:
1836 // cached results already exist
1837 prev = this.cache.get(processor.id);
1838 _a.label = 5;
1839 case 5:
1840 _i++;
1841 return [3 /*break*/, 2];
1842 case 6: return [3 /*break*/, 8];
1843 case 7:
1844 e_1 = _a.sent();
1845 log.error(e_1);
1846 // trigger the onError callback
1847 this.emit('error', prev);
1848 // rethrow
1849 throw e_1;
1850 case 8:
1851 // means the pipeline is up to date
1852 this.lastProcessorIndexUpdated = steps.length;
1853 // triggers the afterProcess callbacks with the results
1854 this.emit('afterProcess', prev);
1855 return [2 /*return*/, prev];
1856 }
1857 });
1858 });
1859 };
1860 /**
1861 * Returns the registered processor's index in _steps array
1862 *
1863 * @param processorID
1864 */
1865 Pipeline.prototype.findProcessorIndexByID = function (processorID) {
1866 return this.steps.findIndex(function (p) { return p.id == processorID; });
1867 };
1868 /**
1869 * Sets the last updates processors index locally
1870 * This is used to invalid or skip a processor in
1871 * the process() method
1872 */
1873 Pipeline.prototype.setLastProcessorIndex = function (processor) {
1874 var processorIndex = this.findProcessorIndexByID(processor.id);
1875 if (this.lastProcessorIndexUpdated > processorIndex) {
1876 this.lastProcessorIndexUpdated = processorIndex;
1877 }
1878 };
1879 Pipeline.prototype.processorPropsUpdated = function (processor) {
1880 this.setLastProcessorIndex(processor);
1881 this.emit('propsUpdated');
1882 this.emit('updated', processor);
1883 };
1884 Pipeline.prototype.afterRegistered = function (processor) {
1885 this.setLastProcessorIndex(processor);
1886 this.emit('afterRegister');
1887 this.emit('updated', processor);
1888 };
1889 return Pipeline;
1890 }(EventEmitter));
1891
1892 var StorageExtractor = /** @class */ (function (_super) {
1893 __extends(StorageExtractor, _super);
1894 function StorageExtractor() {
1895 return _super !== null && _super.apply(this, arguments) || this;
1896 }
1897 Object.defineProperty(StorageExtractor.prototype, "type", {
1898 get: function () {
1899 return ProcessorType.Extractor;
1900 },
1901 enumerable: false,
1902 configurable: true
1903 });
1904 StorageExtractor.prototype._process = function (opts) {
1905 return __awaiter(this, void 0, void 0, function () {
1906 return __generator(this, function (_a) {
1907 switch (_a.label) {
1908 case 0: return [4 /*yield*/, this.props.storage.get(opts)];
1909 case 1: return [2 /*return*/, _a.sent()];
1910 }
1911 });
1912 });
1913 };
1914 return StorageExtractor;
1915 }(PipelineProcessor));
1916
1917 var ArrayToTabularTransformer = /** @class */ (function (_super) {
1918 __extends(ArrayToTabularTransformer, _super);
1919 function ArrayToTabularTransformer() {
1920 return _super !== null && _super.apply(this, arguments) || this;
1921 }
1922 Object.defineProperty(ArrayToTabularTransformer.prototype, "type", {
1923 get: function () {
1924 return ProcessorType.Transformer;
1925 },
1926 enumerable: false,
1927 configurable: true
1928 });
1929 ArrayToTabularTransformer.prototype._process = function (arrayResponse) {
1930 var tabular = Tabular.fromArray(arrayResponse.data);
1931 // for server-side storage
1932 tabular.length = arrayResponse.total;
1933 return tabular;
1934 };
1935 return ArrayToTabularTransformer;
1936 }(PipelineProcessor));
1937
1938 var ServerInitiator = /** @class */ (function (_super) {
1939 __extends(ServerInitiator, _super);
1940 function ServerInitiator() {
1941 return _super !== null && _super.apply(this, arguments) || this;
1942 }
1943 Object.defineProperty(ServerInitiator.prototype, "type", {
1944 get: function () {
1945 return ProcessorType.Initiator;
1946 },
1947 enumerable: false,
1948 configurable: true
1949 });
1950 ServerInitiator.prototype._process = function () {
1951 return Object.entries(this.props.serverStorageOptions)
1952 .filter(function (_a) {
1953 var _ = _a[0], val = _a[1];
1954 return typeof val !== 'function';
1955 })
1956 .reduce(function (acc, _a) {
1957 var _b;
1958 var k = _a[0], v = _a[1];
1959 return (__assign(__assign({}, acc), (_b = {}, _b[k] = v, _b)));
1960 }, {});
1961 };
1962 return ServerInitiator;
1963 }(PipelineProcessor));
1964
1965 var StorageResponseToArrayTransformer = /** @class */ (function (_super) {
1966 __extends(StorageResponseToArrayTransformer, _super);
1967 function StorageResponseToArrayTransformer() {
1968 return _super !== null && _super.apply(this, arguments) || this;
1969 }
1970 Object.defineProperty(StorageResponseToArrayTransformer.prototype, "type", {
1971 get: function () {
1972 return ProcessorType.Transformer;
1973 },
1974 enumerable: false,
1975 configurable: true
1976 });
1977 StorageResponseToArrayTransformer.prototype.castData = function (data) {
1978 if (!data || !data.length) {
1979 return [];
1980 }
1981 if (!this.props.header || !this.props.header.columns) {
1982 return data;
1983 }
1984 var columns = Header.leafColumns(this.props.header.columns);
1985 // if it's a 2d array already
1986 if (data[0] instanceof Array) {
1987 return data.map(function (row) {
1988 var pad = 0;
1989 return columns.map(function (column, i) {
1990 // default `data` is provided for this column
1991 if (column.data !== undefined) {
1992 pad++;
1993 if (typeof column.data === 'function') {
1994 return column.data(row);
1995 }
1996 else {
1997 return column.data;
1998 }
1999 }
2000 return row[i - pad];
2001 });
2002 });
2003 }
2004 // if it's an array of objects (but not array of arrays, i.e JSON payload)
2005 if (typeof data[0] === 'object' && !(data[0] instanceof Array)) {
2006 return data.map(function (row) {
2007 return columns.map(function (column, i) {
2008 if (column.data !== undefined) {
2009 if (typeof column.data === 'function') {
2010 return column.data(row);
2011 }
2012 else {
2013 return column.data;
2014 }
2015 }
2016 else if (column.id) {
2017 return row[column.id];
2018 }
2019 else {
2020 log.error("Could not find the correct cell for column at position " + i + ".\n Make sure either 'id' or 'selector' is defined for all columns.");
2021 return null;
2022 }
2023 });
2024 });
2025 }
2026 return [];
2027 };
2028 StorageResponseToArrayTransformer.prototype._process = function (storageResponse) {
2029 return {
2030 data: this.castData(storageResponse.data),
2031 total: storageResponse.total,
2032 };
2033 };
2034 return StorageResponseToArrayTransformer;
2035 }(PipelineProcessor));
2036
2037 var PipelineUtils = /** @class */ (function () {
2038 function PipelineUtils() {
2039 }
2040 PipelineUtils.createFromConfig = function (config) {
2041 var pipeline = new Pipeline();
2042 if (config.storage instanceof ServerStorage) {
2043 pipeline.register(new ServerInitiator({
2044 serverStorageOptions: config.server,
2045 }));
2046 }
2047 pipeline.register(new StorageExtractor({ storage: config.storage }));
2048 pipeline.register(new StorageResponseToArrayTransformer({ header: config.header }));
2049 pipeline.register(new ArrayToTabularTransformer());
2050 return pipeline;
2051 };
2052 return PipelineUtils;
2053 }());
2054
2055 var Config = /** @class */ (function () {
2056 function Config(config) {
2057 Object.assign(this, __assign(__assign({}, Config.defaultConfig()), config));
2058 this._userConfig = {};
2059 }
2060 /**
2061 * Assigns `updatedConfig` keys to the current config file
2062 *
2063 * @param updatedConfig
2064 */
2065 Config.prototype.assign = function (updatedConfig) {
2066 for (var _i = 0, _a = Object.keys(updatedConfig); _i < _a.length; _i++) {
2067 var key = _a[_i];
2068 // because we don't want to update the _userConfig cache
2069 if (key === '_userConfig')
2070 continue;
2071 this[key] = updatedConfig[key];
2072 }
2073 return this;
2074 };
2075 /**
2076 * Updates the config from a UserConfig
2077 *
2078 * @param userConfig
2079 */
2080 Config.prototype.update = function (userConfig) {
2081 if (!userConfig)
2082 return this;
2083 this._userConfig = __assign(__assign({}, this._userConfig), userConfig);
2084 this.assign(Config.fromUserConfig(this._userConfig));
2085 return this;
2086 };
2087 Config.defaultConfig = function () {
2088 return {
2089 plugin: new PluginManager(),
2090 dispatcher: new Dispatcher(),
2091 tableRef: y(),
2092 tempRef: y(),
2093 width: '100%',
2094 height: 'auto',
2095 autoWidth: true,
2096 style: {},
2097 className: {},
2098 };
2099 };
2100 Config.fromUserConfig = function (userConfig) {
2101 var config = new Config(userConfig);
2102 // to set the initial _userConfig object
2103 config._userConfig = userConfig;
2104 // Sort
2105 if (typeof userConfig.sort === 'boolean' && userConfig.sort) {
2106 config.assign({
2107 sort: {
2108 multiColumn: true,
2109 },
2110 });
2111 }
2112 // Header
2113 config.assign({
2114 header: Header.fromUserConfig(config),
2115 });
2116 config.assign({
2117 storage: StorageUtils.createFromUserConfig(userConfig),
2118 });
2119 config.assign({
2120 pipeline: PipelineUtils.createFromConfig(config),
2121 });
2122 // Translator
2123 config.assign({
2124 translator: new Translator(userConfig.language),
2125 });
2126 // Search
2127 config.plugin.add({
2128 id: 'search',
2129 position: exports.PluginPosition.Header,
2130 component: Search,
2131 props: __assign({ enabled: userConfig.search === true || userConfig.search instanceof Object }, userConfig.search),
2132 });
2133 // Pagination
2134 config.plugin.add({
2135 id: 'pagination',
2136 position: exports.PluginPosition.Footer,
2137 component: Pagination,
2138 props: __assign({ enabled: userConfig.pagination === true ||
2139 userConfig.pagination instanceof Object }, userConfig.pagination),
2140 });
2141 // Additional plugins
2142 if (userConfig.plugins) {
2143 userConfig.plugins.forEach(function (p) { return config.plugin.add(p); });
2144 }
2145 return config;
2146 };
2147 return Config;
2148 }());
2149
2150 // container status
2151 var Status;
2152 (function (Status) {
2153 Status[Status["Init"] = 0] = "Init";
2154 Status[Status["Loading"] = 1] = "Loading";
2155 Status[Status["Loaded"] = 2] = "Loaded";
2156 Status[Status["Rendered"] = 3] = "Rendered";
2157 Status[Status["Error"] = 4] = "Error";
2158 })(Status || (Status = {}));
2159
2160 var TD = /** @class */ (function (_super) {
2161 __extends(TD, _super);
2162 function TD() {
2163 return _super !== null && _super.apply(this, arguments) || this;
2164 }
2165 TD.prototype.content = function () {
2166 if (this.props.column &&
2167 typeof this.props.column.formatter === 'function') {
2168 return this.props.column.formatter(this.props.cell.data, this.props.row, this.props.column);
2169 }
2170 if (this.props.column && this.props.column.plugin) {
2171 return (v(PluginRenderer, { pluginId: this.props.column.id, props: {
2172 column: this.props.column,
2173 cell: this.props.cell,
2174 row: this.props.row,
2175 } }));
2176 }
2177 return this.props.cell.data;
2178 };
2179 TD.prototype.handleClick = function (e) {
2180 if (this.props.messageCell)
2181 return;
2182 this.config.eventEmitter.emit('cellClick', e, this.props.cell, this.props.column, this.props.row);
2183 };
2184 TD.prototype.getCustomAttributes = function (column) {
2185 if (column) {
2186 if (typeof column.attributes === 'function') {
2187 return column.attributes(this.props.cell.data, this.props.row, this.props.column);
2188 }
2189 else {
2190 return column.attributes;
2191 }
2192 }
2193 return {};
2194 };
2195 TD.prototype.render = function () {
2196 return (v("td", __assign({ role: this.props.role, colSpan: this.props.colSpan, "data-column-id": this.props.column && this.props.column.id, className: classJoin(className('td'), this.props.className, this.config.className.td), style: __assign(__assign({}, this.props.style), this.config.style.td), onClick: this.handleClick.bind(this) }, this.getCustomAttributes(this.props.column)), this.content()));
2197 };
2198 return TD;
2199 }(BaseComponent));
2200
2201 var TR = /** @class */ (function (_super) {
2202 __extends(TR, _super);
2203 function TR() {
2204 return _super !== null && _super.apply(this, arguments) || this;
2205 }
2206 TR.prototype.getColumn = function (cellIndex) {
2207 if (this.props.header) {
2208 var cols = Header.leafColumns(this.props.header.columns);
2209 if (cols) {
2210 return cols[cellIndex];
2211 }
2212 }
2213 return null;
2214 };
2215 TR.prototype.handleClick = function (e) {
2216 if (this.props.messageRow)
2217 return;
2218 this.config.eventEmitter.emit('rowClick', e, this.props.row);
2219 };
2220 TR.prototype.getChildren = function () {
2221 var _this = this;
2222 if (this.props.children) {
2223 return this.props.children;
2224 }
2225 else {
2226 return (v(p, null, this.props.row.cells.map(function (cell, i) {
2227 var column = _this.getColumn(i);
2228 if (column && column.hidden)
2229 return null;
2230 return (v(TD, { key: cell.id, cell: cell, row: _this.props.row, column: column }));
2231 })));
2232 }
2233 };
2234 TR.prototype.render = function () {
2235 return (v("tr", { className: className('tr'), onClick: this.handleClick.bind(this) }, this.getChildren()));
2236 };
2237 return TR;
2238 }(BaseComponent));
2239
2240 var MessageRow = /** @class */ (function (_super) {
2241 __extends(MessageRow, _super);
2242 function MessageRow() {
2243 return _super !== null && _super.apply(this, arguments) || this;
2244 }
2245 MessageRow.prototype.render = function () {
2246 return (v(TR, { messageRow: true },
2247 v(TD, { role: "alert", colSpan: this.props.colSpan, messageCell: true, cell: new Cell(this.props.message), className: classJoin(className('message'), this.props.className ? this.props.className : null) })));
2248 };
2249 return MessageRow;
2250 }(BaseComponent));
2251
2252 var TBody = /** @class */ (function (_super) {
2253 __extends(TBody, _super);
2254 function TBody() {
2255 return _super !== null && _super.apply(this, arguments) || this;
2256 }
2257 TBody.prototype.headerLength = function () {
2258 if (this.props.header) {
2259 return this.props.header.columns.length;
2260 }
2261 return 0;
2262 };
2263 TBody.prototype.render = function () {
2264 var _this = this;
2265 return (v("tbody", { className: classJoin(className('tbody'), this.config.className.tbody) },
2266 this.props.data &&
2267 this.props.data.rows.map(function (row) {
2268 return v(TR, { key: row.id, row: row, header: _this.props.header });
2269 }),
2270 this.props.status === Status.Loading &&
2271 (!this.props.data || this.props.data.length === 0) && (v(MessageRow, { message: this._('loading'), colSpan: this.headerLength(), className: classJoin(className('loading'), this.config.className.loading) })),
2272 this.props.status === Status.Rendered &&
2273 this.props.data &&
2274 this.props.data.length === 0 && (v(MessageRow, { message: this._('noRecordsFound'), colSpan: this.headerLength(), className: classJoin(className('notfound'), this.config.className.notfound) })),
2275 this.props.status === Status.Error && (v(MessageRow, { message: this._('error'), colSpan: this.headerLength(), className: classJoin(className('error'), this.config.className.error) }))));
2276 };
2277 return TBody;
2278 }(BaseComponent));
2279
2280 var NativeSort = /** @class */ (function (_super) {
2281 __extends(NativeSort, _super);
2282 function NativeSort() {
2283 return _super !== null && _super.apply(this, arguments) || this;
2284 }
2285 NativeSort.prototype.validateProps = function () {
2286 for (var _i = 0, _a = this.props.columns; _i < _a.length; _i++) {
2287 var condition = _a[_i];
2288 if (condition.direction === undefined) {
2289 condition.direction = 1;
2290 }
2291 if (condition.direction !== 1 && condition.direction !== -1) {
2292 log.error("Invalid sort direction " + condition.direction);
2293 }
2294 }
2295 };
2296 Object.defineProperty(NativeSort.prototype, "type", {
2297 get: function () {
2298 return ProcessorType.Sort;
2299 },
2300 enumerable: false,
2301 configurable: true
2302 });
2303 NativeSort.prototype.compare = function (cellA, cellB) {
2304 if (cellA > cellB) {
2305 return 1;
2306 }
2307 else if (cellA < cellB) {
2308 return -1;
2309 }
2310 return 0;
2311 };
2312 NativeSort.prototype.compareWrapper = function (a, b) {
2313 var cmp = 0;
2314 for (var _i = 0, _a = this.props.columns; _i < _a.length; _i++) {
2315 var column = _a[_i];
2316 if (cmp === 0) {
2317 var cellA = a.cells[column.index].data;
2318 var cellB = b.cells[column.index].data;
2319 if (typeof column.compare === 'function') {
2320 cmp |= column.compare(cellA, cellB) * column.direction;
2321 }
2322 else {
2323 cmp |= this.compare(cellA, cellB) * column.direction;
2324 }
2325 }
2326 else {
2327 break;
2328 }
2329 }
2330 return cmp;
2331 };
2332 NativeSort.prototype._process = function (data) {
2333 var sortedRows = __spreadArrays(data.rows);
2334 sortedRows.sort(this.compareWrapper.bind(this));
2335 var sorted = new Tabular(sortedRows);
2336 // we have to set the tabular length manually
2337 // because of the server-side storage
2338 sorted.length = data.length;
2339 return sorted;
2340 };
2341 return NativeSort;
2342 }(PipelineProcessor));
2343
2344 var SortStore = /** @class */ (function (_super) {
2345 __extends(SortStore, _super);
2346 function SortStore() {
2347 return _super !== null && _super.apply(this, arguments) || this;
2348 }
2349 SortStore.prototype.getInitialState = function () {
2350 return [];
2351 };
2352 SortStore.prototype.handle = function (type, payload) {
2353 if (type === 'SORT_COLUMN') {
2354 var index = payload.index, direction = payload.direction, multi = payload.multi, compare = payload.compare;
2355 this.sortColumn(index, direction, multi, compare);
2356 }
2357 else if (type === 'SORT_COLUMN_TOGGLE') {
2358 var index = payload.index, multi = payload.multi, compare = payload.compare;
2359 this.sortToggle(index, multi, compare);
2360 }
2361 };
2362 SortStore.prototype.sortToggle = function (index, multi, compare) {
2363 var columns = __spreadArrays(this.state);
2364 var column = columns.find(function (x) { return x.index === index; });
2365 if (!column) {
2366 this.sortColumn(index, 1, multi, compare);
2367 }
2368 else {
2369 this.sortColumn(index, column.direction === 1 ? -1 : 1, multi, compare);
2370 }
2371 };
2372 SortStore.prototype.sortColumn = function (index, direction, multi, compare) {
2373 var columns = __spreadArrays(this.state);
2374 var count = columns.length;
2375 var column = columns.find(function (x) { return x.index === index; });
2376 var exists = column !== undefined;
2377 var add = false;
2378 var reset = false;
2379 var remove = false;
2380 var update = false;
2381 if (!exists) {
2382 // the column has not been sorted
2383 if (count === 0) {
2384 // the first column to be sorted
2385 add = true;
2386 }
2387 else if (count > 0 && !multi) {
2388 // remove the previously sorted column
2389 // and sort the current column
2390 add = true;
2391 reset = true;
2392 }
2393 else if (count > 0 && multi) {
2394 // multi-sorting
2395 // sort this column as well
2396 add = true;
2397 }
2398 }
2399 else {
2400 // the column has been sorted before
2401 if (!multi) {
2402 // single column sorting
2403 if (count === 1) {
2404 update = true;
2405 }
2406 else if (count > 1) {
2407 // this situation happens when we have already entered
2408 // multi-sorting mode but then user tries to sort a single column
2409 reset = true;
2410 add = true;
2411 }
2412 }
2413 else {
2414 // multi sorting
2415 if (column.direction === -1) {
2416 // remove the current column from the
2417 // sorted columns array
2418 remove = true;
2419 }
2420 else {
2421 update = true;
2422 }
2423 }
2424 }
2425 if (reset) {
2426 // resetting the sorted columns
2427 columns = [];
2428 }
2429 if (add) {
2430 columns.push({
2431 index: index,
2432 direction: direction,
2433 compare: compare,
2434 });
2435 }
2436 else if (update) {
2437 var index_1 = columns.indexOf(column);
2438 columns[index_1].direction = direction;
2439 }
2440 else if (remove) {
2441 var index_2 = columns.indexOf(column);
2442 columns.splice(index_2, 1);
2443 }
2444 this.setState(columns);
2445 };
2446 return SortStore;
2447 }(BaseStore));
2448
2449 var SortActions = /** @class */ (function (_super) {
2450 __extends(SortActions, _super);
2451 function SortActions() {
2452 return _super !== null && _super.apply(this, arguments) || this;
2453 }
2454 SortActions.prototype.sortColumn = function (index, direction, multi, compare) {
2455 this.dispatch('SORT_COLUMN', {
2456 index: index,
2457 direction: direction,
2458 multi: multi,
2459 compare: compare,
2460 });
2461 };
2462 SortActions.prototype.sortToggle = function (index, multi, compare) {
2463 this.dispatch('SORT_COLUMN_TOGGLE', {
2464 index: index,
2465 multi: multi,
2466 compare: compare,
2467 });
2468 };
2469 return SortActions;
2470 }(BaseActions));
2471
2472 var ServerSort = /** @class */ (function (_super) {
2473 __extends(ServerSort, _super);
2474 function ServerSort() {
2475 return _super !== null && _super.apply(this, arguments) || this;
2476 }
2477 Object.defineProperty(ServerSort.prototype, "type", {
2478 get: function () {
2479 return ProcessorType.ServerSort;
2480 },
2481 enumerable: false,
2482 configurable: true
2483 });
2484 ServerSort.prototype._process = function (options) {
2485 var updates = {};
2486 if (this.props.url) {
2487 updates['url'] = this.props.url(options.url, this.props.columns);
2488 }
2489 if (this.props.body) {
2490 updates['body'] = this.props.body(options.body, this.props.columns);
2491 }
2492 return __assign(__assign({}, options), updates);
2493 };
2494 return ServerSort;
2495 }(PipelineProcessor));
2496
2497 var Sort = /** @class */ (function (_super) {
2498 __extends(Sort, _super);
2499 function Sort(props, context) {
2500 var _this = _super.call(this, props, context) || this;
2501 _this.actions = new SortActions(_this.config.dispatcher);
2502 _this.store = new SortStore(_this.config.dispatcher);
2503 if (props.enabled) {
2504 _this.sortProcessor = _this.getOrCreateSortProcessor();
2505 _this.updateStateFn = _this.updateState.bind(_this);
2506 _this.store.on('updated', _this.updateStateFn);
2507 _this.state = { direction: 0 };
2508 }
2509 return _this;
2510 }
2511 Sort.prototype.componentWillUnmount = function () {
2512 this.config.pipeline.unregister(this.sortProcessor);
2513 this.store.off('updated', this.updateStateFn);
2514 if (this.updateSortProcessorFn)
2515 this.store.off('updated', this.updateSortProcessorFn);
2516 };
2517 /**
2518 * Sets the internal state of component
2519 */
2520 Sort.prototype.updateState = function () {
2521 var _this = this;
2522 var currentColumn = this.store.state.find(function (x) { return x.index === _this.props.index; });
2523 if (!currentColumn) {
2524 this.setState({
2525 direction: 0,
2526 });
2527 }
2528 else {
2529 this.setState({
2530 direction: currentColumn.direction,
2531 });
2532 }
2533 };
2534 Sort.prototype.updateSortProcessor = function (sortedColumns) {
2535 // updates the Sorting processor
2536 this.sortProcessor.setProps({
2537 columns: sortedColumns,
2538 });
2539 };
2540 Sort.prototype.getOrCreateSortProcessor = function () {
2541 var processorType = ProcessorType.Sort;
2542 if (this.config.sort && typeof this.config.sort.server === 'object') {
2543 processorType = ProcessorType.ServerSort;
2544 }
2545 var processors = this.config.pipeline.getStepsByType(processorType);
2546 // my assumption is that we only have ONE sorting processor in the
2547 // entire pipeline and that's why I'm displaying a warning here
2548 var processor;
2549 // A sort process is already registered
2550 if (processors.length > 0) {
2551 processor = processors[0];
2552 }
2553 else {
2554 // let's create a new sort processor
2555 // this event listener is here because
2556 // we want to subscribe to the sort store only once
2557 this.updateSortProcessorFn = this.updateSortProcessor.bind(this);
2558 this.store.on('updated', this.updateSortProcessorFn);
2559 if (processorType === ProcessorType.ServerSort) {
2560 processor = new ServerSort(__assign({ columns: this.store.state }, this.config.sort.server));
2561 }
2562 else {
2563 processor = new NativeSort({
2564 columns: this.store.state,
2565 });
2566 }
2567 this.config.pipeline.register(processor);
2568 }
2569 return processor;
2570 };
2571 Sort.prototype.changeDirection = function (e) {
2572 e.preventDefault();
2573 e.stopPropagation();
2574 // to sort two or more columns at the same time
2575 this.actions.sortToggle(this.props.index, e.shiftKey === true && this.config.sort.multiColumn, this.props.compare);
2576 };
2577 Sort.prototype.render = function () {
2578 if (!this.props.enabled) {
2579 return null;
2580 }
2581 var direction = this.state.direction;
2582 var sortClassName = 'neutral';
2583 if (direction === 1) {
2584 sortClassName = 'asc';
2585 }
2586 else if (direction === -1) {
2587 sortClassName = 'desc';
2588 }
2589 return (v("button", {
2590 // because the corresponding <th> has tabIndex=0
2591 tabIndex: -1, "aria-label": this._("sort.sort" + (direction === 1 ? 'Desc' : 'Asc')), title: this._("sort.sort" + (direction === 1 ? 'Desc' : 'Asc')), className: classJoin(className('sort'), className('sort', sortClassName), this.config.className.sort), onClick: this.changeDirection.bind(this) }));
2592 };
2593 return Sort;
2594 }(BaseComponent));
2595
2596 var TH = /** @class */ (function (_super) {
2597 __extends(TH, _super);
2598 function TH(props, context) {
2599 var _this = _super.call(this, props, context) || this;
2600 _this.sortRef = y();
2601 _this.thRef = y();
2602 _this.state = {
2603 style: {},
2604 };
2605 return _this;
2606 }
2607 TH.prototype.isSortable = function () {
2608 return this.props.column.sort.enabled;
2609 };
2610 TH.prototype.onClick = function (e) {
2611 e.stopPropagation();
2612 if (this.isSortable()) {
2613 this.sortRef.current.changeDirection(e);
2614 }
2615 };
2616 TH.prototype.keyDown = function (e) {
2617 if (this.isSortable() && e.which === 13) {
2618 this.onClick(e);
2619 }
2620 };
2621 TH.prototype.componentDidMount = function () {
2622 var _this = this;
2623 setTimeout(function () {
2624 // sets the `top` style if the current TH is fixed
2625 if (_this.props.column.fixedHeader && _this.thRef.current) {
2626 var offsetTop = _this.thRef.current.offsetTop;
2627 if (typeof offsetTop === 'number') {
2628 _this.setState({
2629 style: {
2630 top: offsetTop,
2631 },
2632 });
2633 }
2634 }
2635 }, 0);
2636 };
2637 TH.prototype.content = function () {
2638 if (this.props.column.name !== undefined) {
2639 return this.props.column.name;
2640 }
2641 if (this.props.column.plugin !== undefined) {
2642 return (v(PluginRenderer, { pluginId: this.props.column.plugin.id, props: {
2643 column: this.props.column,
2644 } }));
2645 }
2646 return null;
2647 };
2648 TH.prototype.render = function () {
2649 var props = {};
2650 if (this.isSortable()) {
2651 props['tabIndex'] = 0;
2652 }
2653 return (v("th", __assign({ ref: this.thRef, "data-column-id": this.props.column && this.props.column.id, className: classJoin(className('th'), this.isSortable() ? className('th', 'sort') : null, this.props.column.fixedHeader ? className('th', 'fixed') : null, this.config.className.th), onClick: this.onClick.bind(this), style: __assign(__assign(__assign(__assign({}, this.config.style.th), { width: this.props.column.width }), this.state.style), this.props.style), onKeyDown: this.keyDown.bind(this), rowSpan: this.props.rowSpan > 1 ? this.props.rowSpan : undefined, colSpan: this.props.colSpan > 1 ? this.props.colSpan : undefined }, props),
2654 this.content(),
2655 this.isSortable() && (v(Sort, __assign({ ref: this.sortRef, index: this.props.index }, this.props.column.sort)))));
2656 };
2657 return TH;
2658 }(BaseComponent));
2659
2660 function calculateRowColSpans(column, rowIndex, totalRows) {
2661 var depth = Header.maximumDepth(column);
2662 var remainingRows = totalRows - rowIndex;
2663 var rowSpan = Math.floor(remainingRows - depth - depth / remainingRows);
2664 var colSpan = (column.columns && column.columns.length) || 1;
2665 return {
2666 rowSpan: rowSpan,
2667 colSpan: colSpan,
2668 };
2669 }
2670
2671 var THead = /** @class */ (function (_super) {
2672 __extends(THead, _super);
2673 function THead() {
2674 return _super !== null && _super.apply(this, arguments) || this;
2675 }
2676 THead.prototype.renderColumn = function (column, rowIndex, columnIndex, totalRows) {
2677 var _a = calculateRowColSpans(column, rowIndex, totalRows), rowSpan = _a.rowSpan, colSpan = _a.colSpan;
2678 return (v(TH, { column: column, index: columnIndex, colSpan: colSpan, rowSpan: rowSpan }));
2679 };
2680 THead.prototype.renderRow = function (row, rowIndex, totalRows) {
2681 var _this = this;
2682 // because the only sortable columns are leaf columns (not parents)
2683 var leafColumns = Header.leafColumns(this.props.header.columns);
2684 return (v(TR, null, row.map(function (col) {
2685 if (col.hidden)
2686 return null;
2687 return _this.renderColumn(col, rowIndex, leafColumns.indexOf(col), totalRows);
2688 })));
2689 };
2690 THead.prototype.renderRows = function () {
2691 var _this = this;
2692 var rows = Header.tabularFormat(this.props.header.columns);
2693 return rows.map(function (row, rowIndex) {
2694 return _this.renderRow(row, rowIndex, rows.length);
2695 });
2696 };
2697 THead.prototype.render = function () {
2698 if (this.props.header) {
2699 return (v("thead", { key: this.props.header.id, className: classJoin(className('thead'), this.config.className.thead) }, this.renderRows()));
2700 }
2701 return null;
2702 };
2703 return THead;
2704 }(BaseComponent));
2705
2706 var Table = /** @class */ (function (_super) {
2707 __extends(Table, _super);
2708 function Table() {
2709 return _super !== null && _super.apply(this, arguments) || this;
2710 }
2711 Table.prototype.render = function () {
2712 return (v("table", { role: "grid", className: classJoin(className('table'), this.config.className.table), style: __assign(__assign({}, this.config.style.table), {
2713 width: this.props.width,
2714 height: this.props.height,
2715 }) },
2716 v(THead, { header: this.props.header }),
2717 v(TBody, { data: this.props.data, status: this.props.status, header: this.props.header })));
2718 };
2719 return Table;
2720 }(BaseComponent));
2721
2722 var HeaderContainer = /** @class */ (function (_super) {
2723 __extends(HeaderContainer, _super);
2724 function HeaderContainer(props, context) {
2725 var _this = _super.call(this, props, context) || this;
2726 _this.headerRef = y();
2727 _this.state = {
2728 isActive: true,
2729 };
2730 return _this;
2731 }
2732 HeaderContainer.prototype.componentDidMount = function () {
2733 if (this.headerRef.current.children.length === 0) {
2734 this.setState({
2735 isActive: false,
2736 });
2737 }
2738 };
2739 HeaderContainer.prototype.render = function () {
2740 if (this.state.isActive) {
2741 return (v("div", { ref: this.headerRef, className: classJoin(className('head'), this.config.className.header), style: __assign({}, this.config.style.header) },
2742 v(PluginRenderer, { position: exports.PluginPosition.Header })));
2743 }
2744 return null;
2745 };
2746 return HeaderContainer;
2747 }(BaseComponent));
2748
2749 var FooterContainer = /** @class */ (function (_super) {
2750 __extends(FooterContainer, _super);
2751 function FooterContainer(props, context) {
2752 var _this = _super.call(this, props, context) || this;
2753 _this.footerRef = y();
2754 _this.state = {
2755 isActive: true,
2756 };
2757 return _this;
2758 }
2759 FooterContainer.prototype.componentDidMount = function () {
2760 if (this.footerRef.current.children.length === 0) {
2761 this.setState({
2762 isActive: false,
2763 });
2764 }
2765 };
2766 FooterContainer.prototype.render = function () {
2767 if (this.state.isActive) {
2768 return (v("div", { ref: this.footerRef, className: classJoin(className('footer'), this.config.className.footer), style: __assign({}, this.config.style.footer) },
2769 v(PluginRenderer, { position: exports.PluginPosition.Footer })));
2770 }
2771 return null;
2772 };
2773 return FooterContainer;
2774 }(BaseComponent));
2775
2776 var Container = /** @class */ (function (_super) {
2777 __extends(Container, _super);
2778 function Container(props, context) {
2779 var _this = _super.call(this, props, context) || this;
2780 // global Config context which is passed to all components
2781 _this.configContext = B(null);
2782 _this.state = {
2783 status: Status.Loading,
2784 header: props.header,
2785 data: null,
2786 };
2787 return _this;
2788 }
2789 Container.prototype.processPipeline = function () {
2790 return __awaiter(this, void 0, void 0, function () {
2791 var data, e_1;
2792 return __generator(this, function (_a) {
2793 switch (_a.label) {
2794 case 0:
2795 this.props.config.eventEmitter.emit('beforeLoad');
2796 this.setState({
2797 status: Status.Loading,
2798 });
2799 _a.label = 1;
2800 case 1:
2801 _a.trys.push([1, 3, , 4]);
2802 return [4 /*yield*/, this.props.pipeline.process()];
2803 case 2:
2804 data = _a.sent();
2805 this.setState({
2806 data: data,
2807 status: Status.Loaded,
2808 });
2809 this.props.config.eventEmitter.emit('load', data);
2810 return [3 /*break*/, 4];
2811 case 3:
2812 e_1 = _a.sent();
2813 log.error(e_1);
2814 this.setState({
2815 status: Status.Error,
2816 data: null,
2817 });
2818 return [3 /*break*/, 4];
2819 case 4: return [2 /*return*/];
2820 }
2821 });
2822 });
2823 };
2824 Container.prototype.componentDidMount = function () {
2825 return __awaiter(this, void 0, void 0, function () {
2826 var config;
2827 return __generator(this, function (_a) {
2828 switch (_a.label) {
2829 case 0:
2830 config = this.props.config;
2831 // for the initial load
2832 return [4 /*yield*/, this.processPipeline()];
2833 case 1:
2834 // for the initial load
2835 _a.sent();
2836 if (config.header && this.state.data && this.state.data.length) {
2837 // now that we have the data, let's adjust columns width
2838 // NOTE: that we only calculate the columns width once
2839 this.setState({
2840 header: config.header.adjustWidth(config.container, config.tableRef, config.tempRef, config.autoWidth),
2841 });
2842 }
2843 this.processPipelineFn = this.processPipeline.bind(this);
2844 this.props.pipeline.on('updated', this.processPipelineFn);
2845 return [2 /*return*/];
2846 }
2847 });
2848 });
2849 };
2850 Container.prototype.componentWillUnmount = function () {
2851 this.props.pipeline.off('updated', this.processPipelineFn);
2852 };
2853 Container.prototype.componentDidUpdate = function (_, previousState) {
2854 // we can't jump to the Status.Rendered if previous status is not Status.Loaded
2855 if (previousState.status != Status.Rendered &&
2856 this.state.status == Status.Loaded) {
2857 this.setState({
2858 status: Status.Rendered,
2859 });
2860 this.props.config.eventEmitter.emit('ready');
2861 }
2862 };
2863 Container.prototype.render = function () {
2864 var configContext = this.configContext;
2865 return (v(configContext.Provider, { value: this.props.config },
2866 v("div", { role: "complementary", className: classJoin('gridjs', className('container'), this.state.status === Status.Loading ? className('loading') : null, this.props.config.className.container), style: __assign(__assign({}, this.props.config.style.container), {
2867 width: this.props.width,
2868 }) },
2869 this.state.status === Status.Loading && (v("div", { className: className('loading-bar') })),
2870 v(HeaderContainer, null),
2871 v("div", { className: className('wrapper'), style: { width: this.props.width, height: this.props.height } },
2872 v(Table, { ref: this.props.config.tableRef, data: this.state.data, header: this.state.header, width: this.props.width, height: this.props.height, status: this.state.status })),
2873 v(FooterContainer, null)),
2874 v("div", { ref: this.props.config.tempRef, id: "gridjs-temp", className: className('temp') })));
2875 };
2876 return Container;
2877 }(BaseComponent));
2878
2879 var Grid = /** @class */ (function (_super) {
2880 __extends(Grid, _super);
2881 function Grid(userConfig) {
2882 var _this = _super.call(this) || this;
2883 _this.config = new Config({ instance: _this, eventEmitter: _this }).update(userConfig);
2884 _this.plugin = _this.config.plugin;
2885 return _this;
2886 }
2887 Grid.prototype.updateConfig = function (userConfig) {
2888 this.config.update(userConfig);
2889 return this;
2890 };
2891 Grid.prototype.createElement = function () {
2892 return v(Container, {
2893 config: this.config,
2894 pipeline: this.config.pipeline,
2895 header: this.config.header,
2896 width: this.config.width,
2897 height: this.config.height,
2898 });
2899 };
2900 /**
2901 * Uses the existing container and tries to clear the cache
2902 * and re-render the existing Grid.js instance again. This is
2903 * useful when a new config is set/updated.
2904 *
2905 */
2906 Grid.prototype.forceRender = function () {
2907 if (!this.config || !this.config.container) {
2908 log.error('Container is empty. Make sure you call render() before forceRender()', true);
2909 }
2910 // clear the pipeline cache
2911 this.config.pipeline.clearCache();
2912 // TODO: not sure if it's a good idea to render a null element but I couldn't find a better way
2913 O(null, this.config.container);
2914 O(this.createElement(), this.config.container);
2915 return this;
2916 };
2917 /**
2918 * Mounts the Grid.js instance to the container
2919 * and renders the instance
2920 *
2921 * @param container
2922 */
2923 Grid.prototype.render = function (container) {
2924 if (!container) {
2925 log.error('Container element cannot be null', true);
2926 }
2927 if (container.childNodes.length > 0) {
2928 log.error("The container element " + container + " is not empty. Make sure the container is empty and call render() again");
2929 return this;
2930 }
2931 this.config.container = container;
2932 O(this.createElement(), container);
2933 return this;
2934 };
2935 return Grid;
2936 }(EventEmitter));
2937
2938 var t$1,u$1,r$1,o$1=0,i$1=[],c$1=n.__b,f$1=n.__r,e$1=n.diffed,a$1=n.__c,v$1=n.unmount;function m$1(t,r){n.__h&&n.__h(u$1,t,o$1||r),o$1=0;var i=u$1.__H||(u$1.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({}),i.__[t]}function y$1(r,o){var i=m$1(t$1++,3);!n.__s&&k$1(i.__H,o)&&(i.__=r,i.__H=o,u$1.__H.__h.push(i));}function s$1(n){return o$1=5,d$1(function(){return {current:n}},[])}function d$1(n,u){var r=m$1(t$1++,7);return k$1(r.__H,u)&&(r.__=n(),r.__H=u,r.__h=n),r.__}function x(){i$1.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g$1),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],n.__e(u,t.__v);}}),i$1=[];}n.__b=function(n){u$1=null,c$1&&c$1(n);},n.__r=function(n){f$1&&f$1(n),t$1=0;var r=(u$1=n.__c).__H;r&&(r.__h.forEach(g$1),r.__h.forEach(j$1),r.__h=[]);},n.diffed=function(t){e$1&&e$1(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i$1.push(o)&&r$1===n.requestAnimationFrame||((r$1=n.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b$1&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b$1&&(t=requestAnimationFrame(u));})(x)),u$1=void 0;},n.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g$1),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],n.__e(r,t.__v);}}),a$1&&a$1(t,u);},n.unmount=function(t){v$1&&v$1(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g$1);}catch(t){n.__e(t,u.__v);}};var b$1="function"==typeof requestAnimationFrame;function g$1(n){var t=u$1;"function"==typeof n.__c&&n.__c(),u$1=t;}function j$1(n){var t=u$1;n.__c=n.__(),u$1=t;}function k$1(n,t){return !n||n.length!==t.length||t.some(function(t,u){return t!==n[u]})}
2939
2940 exports.BaseActions = BaseActions;
2941 exports.BaseComponent = BaseComponent;
2942 exports.BaseStore = BaseStore;
2943 exports.Cell = Cell;
2944 exports.Component = d;
2945 exports.Config = Config;
2946 exports.Dispatcher = Dispatcher;
2947 exports.Grid = Grid;
2948 exports.PluginBaseComponent = PluginBaseComponent;
2949 exports.Row = Row;
2950 exports.className = className;
2951 exports.createElement = v;
2952 exports.createRef = y;
2953 exports.h = v;
2954 exports.html = html;
2955 exports.useEffect = y$1;
2956 exports.useRef = s$1;
2957
2958 Object.defineProperty(exports, '__esModule', { value: true });
2959
2960})));
2961//# sourceMappingURL=gridjs.development.js.map