@hashuplabs/omni-filter
Version:
OmniFilter Search component
433 lines • 24 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
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;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import React from 'react';
import { Component } from 'react';
import { FilterManager } from '..';
import OmniFilterFactory from '../filters/OmniFilterRegistry';
import { OmniToken } from '../OmniToken';
import { OmniFilterSuggestionWindow } from './OmniFilterSuggestionWindow';
import { OmniFilterToken } from './OmniFilterToken';
var OmniFilterBar = /** @class */ (function (_super) {
__extends(OmniFilterBar, _super);
function OmniFilterBar(props) {
var _this = _super.call(this, props) || this;
// _tokens: OmniToken[] = [];
_this._inputElement = null; // HTMLElement | null = null;
_this._scrollElement = null;
_this._filterManager = null;
if (_this.props.filterManager) {
_this._filterManagerClass = _this.props.filterManager;
}
else {
_this._filterManagerClass = FilterManager;
}
_this._entities = [];
_this.state = {
boxOffset: 0,
filterShowing: false,
activeToken: null,
tokenInput: '',
tokens: [],
inputElement: null,
};
return _this;
}
OmniFilterBar.prototype.initialize = function () {
return __awaiter(this, void 0, void 0, function () {
var el, restoreState, _initialTokens, fm, initialTok, tokens;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
el = document.querySelector('li.input-token > input');
this._inputElement = el;
this._scrollElement = el.closest('.scroll-container');
restoreState = {
filterShowing: false,
inputElement: this._inputElement,
};
_initialTokens = [];
Object.keys(this.props.filterSet).forEach(function (filterPropKey) {
var data = _this.props.filterSet[filterPropKey];
if (!OmniFilterFactory().exists(data.type)) {
throw Error('Invalid FIlter Type');
}
var _filterType = OmniFilterFactory().get(data.type);
var inst = {
entityName: filterPropKey,
filter: data,
type: new _filterType(data),
};
_this._entities.push(inst);
});
if (!this.props.filter) return [3 /*break*/, 2];
return [4 /*yield*/, this._filterManagerClass.fromJSON(this, this.props.filter)];
case 1:
fm = _a.sent();
fm.all().forEach(function (mappedToken) {
_initialTokens.push(mappedToken.token);
});
this._filterManager = fm;
_a.label = 2;
case 2:
initialTok = new OmniToken(this);
tokens = __spreadArray(__spreadArray([], _initialTokens, true), [initialTok], false);
this.setState(function (origState) {
return __assign(__assign(__assign({}, origState), restoreState), {
activeToken: initialTok,
tokens: tokens,
});
});
if (this.props.ready)
this.props.ready(this);
return [2 /*return*/];
}
});
});
};
OmniFilterBar.prototype.updatePosition = function (stateObject) {
if (!this._inputElement)
return;
if (!this._scrollElement)
return;
if (stateObject) {
stateObject.filterShowing = true;
stateObject.boxOffset = this._inputElement.offsetLeft - this._scrollElement.scrollLeft;
return;
}
this.setState({ filterShowing: true, boxOffset: this._inputElement.offsetLeft - this._scrollElement.scrollLeft });
};
OmniFilterBar.prototype.componentDidMount = function () {
this.initialize();
};
OmniFilterBar.prototype.onSuggestionUpdated = function (newToken) {
this.setState({
activeToken: newToken,
tokenInput: '',
});
// setTimeout(() => this._inputElement!.focus(), 350);
this._inputElement.value = '';
this._inputElement.focus();
if (this.props.tokenChanged) {
this.props.tokenChanged(this, newToken);
}
};
OmniFilterBar.prototype.onSuggestionCompleted = function (newToken) {
var _a, _b, _c;
var activeTokens = this.state.tokens;
var tok = new OmniToken(this);
activeTokens.push(tok);
// TODO: setTimeout(() => this._inputElement!.focus(), 350);
if (this._inputElement)
this._inputElement.value = '';
// this._inputElement!.focus();
if ((_a = newToken.entity) === null || _a === void 0 ? void 0 : _a.filter.apply)
(_c = (_b = newToken.entity) === null || _b === void 0 ? void 0 : _b.filter) === null || _c === void 0 ? void 0 : _c.apply(newToken);
this.onTokenAdded(this, newToken);
this.setState({
activeToken: tok,
tokens: activeTokens,
tokenInput: '',
});
};
OmniFilterBar.prototype.render = function () {
return React.createElement("div", { style: { marginTop: '1.5rem' } }, this.render_in());
};
OmniFilterBar.prototype.getTokens = function () {
return this.state.tokens.filter(function (f) { return f.hasValues; });
};
OmniFilterBar.prototype.indexOfToken = function (token) {
return this.state.tokens.findIndex(function (f) { return f.id === token.id; });
};
OmniFilterBar.prototype.removeToken = function (token) {
if (!token)
return;
// Store tokens as they are
var tokens = this.state.tokens;
var tokenIndex = this.state.tokens.findIndex(function (t) { return t.id === token.id; });
if (tokenIndex > -1) {
try {
this.onTokenRemoved(this, token);
}
catch (e) {
// tslint:disable-next-line: no-console
console.warn('REMOVE_TOKEN :: CAUGHT EXCEPTION: ', e);
}
tokens.splice(tokenIndex, 1);
this.setState(function (prevState) {
var ps = __assign({}, prevState);
ps.tokens = tokens;
return ps;
});
}
else {
// console.warn('Unable to locate indexOf token', token);
}
};
OmniFilterBar.prototype.onTokenAdded = function (_sender, token) {
if (this._filterManager) {
this._filterManager.addToken(token);
}
if (this.props.tokenAdded) {
this.props.tokenAdded(this, token);
}
if (this.props.tokenSetChanged) {
this.props.tokenSetChanged(this);
}
var allkeys = [];
this.state.tokens.map(function (item) {
allkeys.push(item.entityName);
});
var lastElement = this.state.tokens.slice((this.state.tokens.length - 2), (this.state.tokens.length - 1));
if (lastElement && lastElement.length && allkeys.indexOf(lastElement[0].entityName) > -1) {
this.state.tokens.splice((this.state.tokens.length - 2), 1);
this.state.tokens.splice(allkeys.indexOf(lastElement[0].entityName), 0, lastElement[0]);
}
};
OmniFilterBar.prototype.onTokenRemoved = function (_sender, token) {
if (this._filterManager) {
this._filterManager.removeToken(token);
}
if (this.props.tokenRemoved) {
this.props.tokenRemoved(this, token);
}
if (this.props.tokenSetChanged) {
this.props.tokenSetChanged(this);
}
};
/*private onTokenChanged(_sender: OmniFilterBar, token: OmniToken ){
this._filterManager?.removeToken( token );
this._filterManager?.addToken(token);
if( this.props.tokenSetChanged ){
this.props.tokenSetChanged( this );
}
}*/
OmniFilterBar.prototype.render_in = function () {
var _this = this;
var _a, _b;
var allkeys = [];
if (this.props.enableTokenGrouping) {
this.state.tokens.map(function (item) {
allkeys.push(item.entityName);
});
var lastElement = this.state.tokens.slice((this.state.tokens.length - 2), (this.state.tokens.length - 1));
if (lastElement && lastElement.length && allkeys.indexOf(lastElement[0].entityName) > -1) {
this.state.tokens.splice((this.state.tokens.length - 2), 1);
this.state.tokens.splice(allkeys.indexOf(lastElement[0].entityName), 0, lastElement[0]);
}
}
// var skipSet=false;
return (React.createElement("div", null,
React.createElement("div", { className: "filtered-search-box", style: {
position: 'relative',
flex: '1',
display: 'flex',
width: '100%',
minWidth: '0',
border: '1px solid #dbdbdb',
backgroundColor: '#fff',
} },
React.createElement("div", { className: "filtered-search-box-input-container", style: {
position: 'relative',
minWidth: 0,
height: '100%',
backgroundColor: '#FFF',
flex: '1',
} },
React.createElement("div", { className: "scroll-container", style: {
display: 'flex',
overflowX: 'auto',
// whiteSpace: 'nowrap',
width: '100%',
} },
React.createElement("ul", { className: "tokens-container list-unstyled", style: {
display: 'flex',
flex: '1',
paddingLeft: '12px',
position: 'relative',
marginBottom: '0',
padding: '0',
margin: '0',
width: '1px',
listStyle: 'none',
} },
this.state.tokens.map(function (filter, k) {
var _a;
return (React.createElement("div", { key: k, style: { display: 'flex' } },
React.createElement(OmniFilterToken, { token: filter, controller: _this }),
filter.isComplete && !(!_this.state.filterShowing && k === _this.state.tokens.length - 2) ? (React.createElement("li", { style: {
flexShrink: 'unset',
marginTop: '7px',
marginBottom: '4px',
color: '#999',
marginRight: '5px',
}, key: "A".concat(k) },
React.createElement("div", { style: { display: 'flex' } }, allkeys.includes(filter.entityName, k + 1) ? ((_a = _this.props.tokenGroupSeparator) !== null && _a !== void 0 ? _a : "AND") : "AND"))) : (React.createElement("template", { key: "tx".concat(k) }))));
}),
React.createElement("li", { className: "input-token" },
React.createElement("input", { placeholder: (_a = this.props.placeholder) !== null && _a !== void 0 ? _a : 'Search', onFocus: function () {
var _a;
(_a = _this._inputElement) === null || _a === void 0 ? void 0 : _a.setAttribute('_hasFocus', '1');
_this.updatePosition();
}, onBlur: function () {
var _a;
// setTimeout(()=>this.setState({ filterShowing: false }),200);
// setTimeout(()=>this.setState({ filterShowing: false }),200);
(_a = _this._inputElement) === null || _a === void 0 ? void 0 : _a.removeAttribute('_hasFocus');
setTimeout(function () {
var _a;
if ((_a = _this._inputElement) === null || _a === void 0 ? void 0 : _a.hasAttribute('_hasFocus'))
return;
_this.setState({ filterShowing: false });
}, 200);
}, onKeyUp: function (e) {
var _a;
_this.updatePosition();
var newState = {
tokenInput: '',
};
switch (e.key) {
case 'Escape':
newState.filterShowing = false;
break;
case 'Backspace':
if (!((_a = _this._inputElement) === null || _a === void 0 ? void 0 : _a.value.length)) {
// Step backwards into previous token / token part
if (_this.state.activeToken.isEmpty) {
// Pop tokens and set active to previous
var tokens = _this.state.tokens;
if (tokens.length === 1) {
return;
}
var headToken_1 = tokens[tokens.length - 1];
if (!headToken_1.marked) {
headToken_1.mark();
setTimeout(function () {
headToken_1.marked = false;
}, 2000);
return;
}
headToken_1.marked = false;
_this.removeToken(headToken_1);
var prevToken = tokens[tokens.length ? tokens.length - 1 : 0];
try {
_this.onTokenRemoved(_this, prevToken);
}
catch (e) {
// TODO: Log error
}
_this.state.inputElement.value = prevToken.back();
newState.tokens = tokens;
newState.activeToken = prevToken;
}
else {
var prevToken_1 = _this.state.tokens[_this.state.tokens.length - 1];
if (!prevToken_1)
return;
/* if( !skipSet ){
prevToken.mark();
skipSet=true;
return;
}*/
if (!prevToken_1.marked) {
prevToken_1.mark();
setTimeout(function () {
prevToken_1.marked = false;
}, 2000);
return;
}
prevToken_1.marked = false;
_this.state.inputElement.value = prevToken_1.back();
}
}
_this.updatePosition(newState);
break;
}
newState.tokenInput = e.currentTarget.value;
_this.setState(function (prevState) { return (__assign(__assign({}, prevState), newState)); });
}, autoComplete: "off", className: "form-control", width: "100%", style: {
width: '100%',
position: 'relative',
minWidth: '200px',
paddingRight: '25px',
paddingLeft: '0',
height: '37px',
boxShadow: 'none',
outline: 'none',
borderColor: 'transparent',
} })))),
React.createElement(OmniFilterSuggestionWindow, { inputElement: this.state.inputElement, tokenInput: this.state.tokenInput, onComplete: function (newToken) { return _this.onSuggestionCompleted(newToken); }, onUpdate: function (newToken) { return _this.onSuggestionUpdated(newToken); }, offset: this.state.boxOffset, visible: this.state.filterShowing, token: (_b = this.state.activeToken) !== null && _b !== void 0 ? _b : new OmniToken(this), filters: this._entities })))));
};
return OmniFilterBar;
}(Component));
export { OmniFilterBar };
//# sourceMappingURL=OmniFilterBar.js.map