kea-react
Version:
Componentes comunes de react
408 lines (407 loc) • 18.9 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__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;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
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) : new P(function (resolve) { resolve(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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, 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 };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var ReactSelect = require("react-select");
var async_1 = require("./async");
var formField_1 = require("./fields/formField");
var text_1 = require("./fields/text");
var search_1 = require("./search");
var react_rxk_1 = require("react-rxk");
/**Genera un arreglo de numeros consecutivos iniciando en el 0 */
function Rango(count) {
var r = [];
for (var i = 0; i < count; i++) {
r.push(i);
}
return r;
}
exports.Rango = Rango;
/**Componente que muestra un selector con botones */
var ButtonSelector = /** @class */ (function (_super) {
__extends(ButtonSelector, _super);
function ButtonSelector() {
return _super !== null && _super.apply(this, arguments) || this;
}
ButtonSelector.prototype.onClick = function (value) {
if (this.props.onChange)
this.props.onChange(value);
};
ButtonSelector.prototype.render = function () {
var _this = this;
return (React.createElement("ul", { className: "pagination pagination-sm" }, (this.props.items || [])
.map(function (x, i) {
return React.createElement("li", { key: x.value == null ? ("__null" + i) : (x.value + ""), className: x.disabled ? "disabled" :
_this.props.value == x.value ? "active" : "" },
React.createElement("a", {
/**Arreglo del z index, el selector activo sale por encima de los drop downs de los combos */
style: { zIndex: 0 }, title: x.tooltip ? (x.tooltip + "") : "", onClick: x.disabled ? undefined : (function () { return _this.onClick(x.value); }) }, x.label));
})));
};
return ButtonSelector;
}(React.PureComponent));
exports.ButtonSelector = ButtonSelector;
var reactSelectFix = {
menuContainerStyle: { 'zIndex': 999 },
filterOption: function (option, filter) { return search_1.search(filter, option.label); }
};
/**Selector simple */
var SelectBase = /** @class */ (function (_super) {
__extends(SelectBase, _super);
function SelectBase() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.handleOnChange = function (option) {
if (_this.props.onChange) {
_this.props.onChange(option && (_this.unmapValue(option.value)));
}
};
return _this;
}
SelectBase.prototype.mapValue = function (value) {
if (value == 0)
return "__NUMBERZERO__";
else if (typeof (value) == "string" || typeof (value) == "number") {
return value;
}
else if (typeof (value) == 'boolean') {
return "__BOOLEAN__" + value;
}
else if (value === null) {
return "__NULL__";
}
else if (value instanceof Date) {
return "__DATE__" + value.toISOString();
}
else {
return value;
}
};
SelectBase.prototype.unmapValue = function (value) {
if (value === "__BOOLEAN__" + true)
return true;
else if (value === "__BOOLEAN__" + false)
return false;
else if (value === "__NULL__")
return null;
else if (value === "__NUMBERZERO__")
return 0;
else if (typeof value == "string" && value.startsWith("__DATE__")) {
var part = value.substr("__DATE__".length);
return new Date(part);
}
else
return value;
};
SelectBase.prototype.selectedText = function () {
return __awaiter(this, void 0, void 0, function () {
var items, value, selected;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, (this.props.items || [])];
case 1:
items = _a.sent();
return [4 /*yield*/, this.props.value];
case 2:
value = _a.sent();
selected = items.filter(function (x) { return x.value == value; })[0];
return [2 /*return*/, (selected && (selected.label + "")) || "(ninguno)"];
}
});
});
};
SelectBase.prototype.mappedValue = function () {
return __awaiter(this, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_a = this.mapValue;
return [4 /*yield*/, this.props.value];
case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])];
}
});
});
};
SelectBase.prototype.items = function () {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
var mapItem;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.props.items) return [3 /*break*/, 2];
mapItem = function (x) { return ({ value: _this.mapValue(x.value), label: "" + x.label, className: x.style ? "alert-" + x.style : undefined }); };
return [4 /*yield*/, this.props.items];
case 1: return [2 /*return*/, (_a.sent()).map(mapItem)];
case 2: return [2 /*return*/, []];
}
});
});
};
SelectBase.prototype.render = function () {
var _this = this;
//En lugar de usar el kea.async para resolver la promesa de los items se la delegamos al ReactSelect para que se cargue mas
//rapido la interfaz de usuario cuando aún no estan disponibles las listas
var selectedText = this.selectedText();
var getSelect = function (value, options, cargando) {
return React.createElement(ReactSelect.default, __assign({ placeholder: "Seleccionar...", noResultsText: "No hay resultados.", options: options, isLoading: cargando, value: value, onChange: _this.handleOnChange }, reactSelectFix));
};
var realSelect = function (value, options) { return getSelect(value, options, false); };
var cargandoSelect = getSelect(undefined, [], true);
var error = this.props.error || ((!!this.props.required) && (this.props.value == null));
return (React.createElement(formField_1.FormField, { label: this.props.label, error: error }, this.props.isReadOnly ?
React.createElement(text_1.Text, { value: this.selectedText(), isReadOnly: true }) :
async_1.async(this.mappedValue(), function (value) {
return async_1.async(_this.items(), function (items) { return realSelect(value, items); }, { cargando: cargandoSelect });
})));
};
return SelectBase;
}(React.PureComponent));
/**Selector simple */
exports.Select = react_rxk_1.componentToRx(SelectBase);
/**Selector múltiple. El valor seleccionado es un arreglo de los valores de los elementos */
var MultiSelect = /** @class */ (function (_super) {
__extends(MultiSelect, _super);
function MultiSelect() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.handleOnChange = function (options) {
if (_this.props.onChange) {
_this.props.onChange(options && options.map(function (x) { return x.value; }) || []);
}
};
return _this;
}
MultiSelect.prototype.items = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.props.items) return [3 /*break*/, 2];
return [4 /*yield*/, this.props.items];
case 1: return [2 /*return*/, (_a.sent()).map(function (x) {
return { value: x.value, label: "" + x.label };
})];
case 2: return [2 /*return*/, []];
}
});
});
};
MultiSelect.prototype.render = function () {
var _this = this;
/*
Hay un problema con el ReactSelect multiple y asíncronom asi que en este caso usaremos el kea.async en lugar de delegar la promesa al react select
https://github.com/JedWatson/react-select/issues/1542
*/
var value = this.props.value == null ? [] : this.props.value;
var getSelect = function (options, cargando) {
return React.createElement(ReactSelect.default, __assign({ inputProps: { readOnly: _this.props.readonly || undefined }, placeholder: "Seleccionar...", noResultsText: "No hay resultados.", options: options, isLoading: cargando, value: value, multi: true, onChange: _this.props.readonly ? undefined : _this.handleOnChange }, reactSelectFix));
};
var realSelect = function (options) { return getSelect(options, false); };
var cargandoSelect = getSelect(value.map(function (x) { return ({ value: x, label: x }); }), true);
return (React.createElement(formField_1.FormField, { label: this.props.label }, async_1.async(this.items(), function (items) { return realSelect(items); }, { cargando: cargandoSelect })));
};
return MultiSelect;
}(React.PureComponent));
exports.MultiSelect = MultiSelect;
/**Componente que muestra un selector de botones paginado, útil cuando existen demasiadas opciones */
var PaginatedButtonSelector = /** @class */ (function (_super) {
__extends(PaginatedButtonSelector, _super);
function PaginatedButtonSelector(props) {
var _this = _super.call(this, props) || this;
_this.PageSize = 10;
_this.handleOnChange = function (value) {
if (!_this.props.onChange)
return;
var index = _this.CurrentIndex || 0;
var items = _this.Items;
if (value == "_next") {
_this.props.onChange(_this.GetValueAt(Math.min(items.length - 1, index + 1)));
}
else if (value == "_previous") {
_this.props.onChange(_this.GetValueAt(Math.max(0, index - 1)));
}
else {
_this.props.onChange(value);
}
};
return _this;
}
Object.defineProperty(PaginatedButtonSelector.prototype, "Items", {
/**Todos los items */
get: function () {
return this.props.items || [];
},
enumerable: true,
configurable: true
});
PaginatedButtonSelector.prototype.GetValueAt = function (index) {
return this.Items[index].value;
};
Object.defineProperty(PaginatedButtonSelector.prototype, "CurrentIndex", {
get: function () {
return this.GetIndex(this.props.value);
},
enumerable: true,
configurable: true
});
PaginatedButtonSelector.prototype.GetIndex = function (value) {
var items = this.Items;
for (var i = 0; i < items.length; i++) {
if (items[i].value == value)
return i;
}
return null;
};
Object.defineProperty(PaginatedButtonSelector.prototype, "PageItems", {
/**Elementos de la página actual */
get: function () {
var pageCount = this.PageCount;
var items = this.Items;
//Si no hay paginas, devolvemos items, que seria un arreglo vacio
if (pageCount <= 1)
return this.Items;
var page = this.CurrentPage;
var pageItems = this.Items.slice(this.CurrentPage * this.PageSize, (this.CurrentPage + 1) *
this.PageSize);
var pageSize = this.PageSize;
//Agregamos los puntos suspensivos al principio o al final de la lista:
var dots = { value: undefined, label: "...", disabled: true };
if (page > 0) {
var lastPageItem = (page - 1) * pageSize;
pageItems.splice(0, 0, dots);
if (lastPageItem != 0)
pageItems.splice(0, 0, items[lastPageItem]);
pageItems.splice(0, 0, items[0]);
}
if (page < (pageCount + 1)) {
var lastItem = items.length - 1;
var nextPageItem = Math.min(lastItem, (page + 2) * pageSize - 1);
pageItems.push(dots);
if (nextPageItem != lastItem)
pageItems.push(items[nextPageItem]);
pageItems.push(items[items.length - 1]);
}
pageItems.splice(0, 0, { value: "_previous", label: '«' });
pageItems.push({ value: "_next", label: '»' });
return pageItems;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PaginatedButtonSelector.prototype, "SelectedIndex", {
/**Indice seleccionado */
get: function () {
var index = this.CurrentIndex;
if (index === undefined)
return null;
else
return index;
},
enumerable: true,
configurable: true
});
Object.defineProperty(PaginatedButtonSelector.prototype, "CurrentPage", {
/**Pagina actual */
get: function () {
return Math.floor((this.SelectedIndex || 0) / this.PageSize);
},
enumerable: true,
configurable: true
});
Object.defineProperty(PaginatedButtonSelector.prototype, "PageCount", {
/**Cantidad de páginas */
get: function () {
return Math.ceil(this.Items.length / this.PageSize);
},
enumerable: true,
configurable: true
});
PaginatedButtonSelector.prototype.render = function () {
return (React.createElement(ButtonSelector, { items: this.PageItems, value: this.props.value, onChange: this.handleOnChange }));
};
return PaginatedButtonSelector;
}(React.PureComponent));
exports.PaginatedButtonSelector = PaginatedButtonSelector;
/**Un selector anidado */
var NeastedSelector = /** @class */ (function (_super) {
__extends(NeastedSelector, _super);
function NeastedSelector(props) {
var _this = _super.call(this, props) || this;
_this.handleParentChange = function (value) {
if (_this.props.onChildChange == null)
return;
//Si cambia el padre, deseleccionamos el hijo
_this.props.onChildChange(null);
_this.setState({ parentValue: value });
};
_this.state = {};
return _this;
}
Object.defineProperty(NeastedSelector.prototype, "PadreActual", {
get: function () {
if (this.props.parentValue == null)
return this.state.parentValue;
else
return this.props.parentValue;
},
enumerable: true,
configurable: true
});
NeastedSelector.prototype.render = function () {
return this.props.map(this.PadreActual, this.handleParentChange);
};
return NeastedSelector;
}(React.PureComponent));
exports.NeastedSelector = NeastedSelector;