diff --git a/lib/Database.test.js b/lib/Database.test.js index 2851be1d..11cb4faf 100644 --- a/lib/Database.test.js +++ b/lib/Database.test.js @@ -1,7 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var Database_1 = require("./database/Database"); -test("finds filters by primary key only", function () { +const Database_1 = require("./database/Database"); +test("finds filters by primary key only", () => { expect(Database_1.getWherePrimaryKey(null)).toBeNull(); expect(Database_1.getWherePrimaryKey({ type: "field", table: "t1", column: "x" })).toBeNull(); expect(Database_1.getWherePrimaryKey({ type: "id", table: "t1" })).toBeNull(); diff --git a/lib/PageStackDisplay.js b/lib/PageStackDisplay.js index d2036c29..a2f19007 100644 --- a/lib/PageStackDisplay.js +++ b/lib/PageStackDisplay.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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) { @@ -32,200 +8,130 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PageStackDisplay = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importDefault(require("react")); -var ContextVarsInjector_1 = __importDefault(require("./widgets/ContextVarsInjector")); -var ModalPopupComponent_1 = __importDefault(require("react-library/lib/ModalPopupComponent")); -var uuid_1 = __importDefault(require("uuid")); +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importDefault(require("react")); +const ContextVarsInjector_1 = __importDefault(require("./widgets/ContextVarsInjector")); +const ModalPopupComponent_1 = __importDefault(require("react-library/lib/ModalPopupComponent")); +const uuid_1 = __importDefault(require("uuid")); require("./PageStackDisplay.css"); /** Maintains and displays the stack of pages, including modals */ -var PageStackDisplay = /** @class */ (function (_super) { - __extends(PageStackDisplay, _super); - function PageStackDisplay(props) { - var _this = _super.call(this, props) || this; - _this.renderChildBlock = function (instanceCtx, childBlockDef) { +class PageStackDisplay extends react_1.default.Component { + constructor(props) { + super(props); + this.renderChildBlock = (instanceCtx, childBlockDef) => { // Create block if (childBlockDef) { - var block = instanceCtx.createBlock(childBlockDef); + const block = instanceCtx.createBlock(childBlockDef); return block.renderInstance(instanceCtx); } return null; }; - _this.handleClose = function () { - _this.closePage(); + this.handleClose = () => { + this.closePage(); }; /** Stores the registration for validation of a child block and returns an unregister function */ - _this.registerChildForValidation = function (pageIndex, validate) { - var key = uuid_1.default(); - _this.validationRegistrations[key] = { pageIndex: pageIndex, validate: validate }; - return function () { - delete _this.validationRegistrations[key]; + this.registerChildForValidation = (pageIndex, validate) => { + const key = uuid_1.default(); + this.validationRegistrations[key] = { pageIndex: pageIndex, validate: validate }; + return () => { + delete this.validationRegistrations[key]; }; }; // Display initial page - _this.state = { + this.state = { pages: props.initialPage ? [props.initialPage] : [] }; - _this.validationRegistrations = {}; - return _this; + this.validationRegistrations = {}; } - PageStackDisplay.prototype.openPage = function (page) { + openPage(page) { this.setState({ pages: this.state.pages.concat(page) }); - }; + } /** Replace current page with specified one */ - PageStackDisplay.prototype.replacePage = function (page) { - return __awaiter(this, void 0, void 0, function () { - var pageIndex, result, pages; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - if (this.state.pages.length == 0) { - throw new Error("Zero pages in stack"); - } - pageIndex = this.state.pages.length - 1; - return [4 /*yield*/, this.validatePage(pageIndex)]; - case 1: - result = _a.sent(); - if (!result) { - return [2 /*return*/, false]; - } - pages = this.state.pages.slice(); - pages.splice(pages.length - 1, 1); - pages.push(page); - this.setState({ pages: pages }); - return [2 /*return*/, true]; - } - }); + replacePage(page) { + return __awaiter(this, void 0, void 0, function* () { + if (this.state.pages.length == 0) { + throw new Error("Zero pages in stack"); + } + // Validate all instances within page + const pageIndex = this.state.pages.length - 1; + const result = yield this.validatePage(pageIndex); + if (!result) { + return false; + } + const pages = this.state.pages.slice(); + pages.splice(pages.length - 1, 1); + pages.push(page); + this.setState({ pages }); + return true; }); - }; + } /** Close top page. Returns whether successful and pages still open */ - PageStackDisplay.prototype.closePage = function () { - return __awaiter(this, void 0, void 0, function () { - var pageIndex, result, pages; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - if (this.state.pages.length == 0) { - throw new Error("Zero pages in stack"); - } - pageIndex = this.state.pages.length - 1; - return [4 /*yield*/, this.validatePage(pageIndex)]; - case 1: - result = _a.sent(); - if (!result) { - return [2 /*return*/, { success: false, pageCount: this.state.pages.length }]; - } - pages = this.state.pages.slice(); - pages.splice(pages.length - 1, 1); - this.setState({ pages: pages }); - return [2 /*return*/, { success: true, pageCount: pages.length }]; - } - }); + closePage() { + return __awaiter(this, void 0, void 0, function* () { + if (this.state.pages.length == 0) { + throw new Error("Zero pages in stack"); + } + // Validate all instances within page + const pageIndex = this.state.pages.length - 1; + const result = yield this.validatePage(pageIndex); + if (!result) { + return { success: false, pageCount: this.state.pages.length }; + } + const pages = this.state.pages.slice(); + pages.splice(pages.length - 1, 1); + this.setState({ pages }); + return { success: true, pageCount: pages.length }; }); - }; + } /** Closes all pages. true for success, false for failure */ - PageStackDisplay.prototype.closeAllPages = function () { - return __awaiter(this, void 0, void 0, function () { - var pages, pageIndex, result; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - pages = this.state.pages.slice(); - _a.label = 1; - case 1: - if (!(pages.length > 0)) return [3 /*break*/, 3]; - pageIndex = pages.length - 1; - return [4 /*yield*/, this.validatePage(pageIndex)]; - case 2: - result = _a.sent(); - if (!result) { - return [2 /*return*/, false]; - } - pages.splice(pages.length - 1, 1); - return [3 /*break*/, 1]; - case 3: - this.setState({ pages: [] }); - return [2 /*return*/, true]; + closeAllPages() { + return __awaiter(this, void 0, void 0, function* () { + const pages = this.state.pages.slice(); + while (pages.length > 0) { + // Validate all instances within page + const pageIndex = pages.length - 1; + const result = yield this.validatePage(pageIndex); + if (!result) { + return false; } - }); + pages.splice(pages.length - 1, 1); + } + this.setState({ pages: [] }); + return true; }); - }; + } /** Validates a single page (by pageIndex), showing an error if fails */ - PageStackDisplay.prototype.validatePage = function (pageIndex) { - return __awaiter(this, void 0, void 0, function () { - var validationMessages, _i, _a, key, value, msg; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - validationMessages = []; - _i = 0, _a = Object.keys(this.validationRegistrations); - _b.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 4]; - key = _a[_i]; - value = this.validationRegistrations[key]; - if (value.pageIndex != pageIndex) { - return [3 /*break*/, 3]; - } - return [4 /*yield*/, value.validate()]; - case 2: - msg = _b.sent(); - if (msg != null) { - validationMessages.push(msg); - } - _b.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: - if (validationMessages.length > 0) { - // "" just blocks - if (lodash_1.default.compact(validationMessages).length > 0) { - alert(lodash_1.default.compact(validationMessages).join("\n")); - } - return [2 /*return*/, false]; - } - return [2 /*return*/, true]; + validatePage(pageIndex) { + return __awaiter(this, void 0, void 0, function* () { + const validationMessages = []; + for (const key of Object.keys(this.validationRegistrations)) { + const value = this.validationRegistrations[key]; + if (value.pageIndex != pageIndex) { + continue; + } + const msg = yield value.validate(); + if (msg != null) { + validationMessages.push(msg); } - }); + } + if (validationMessages.length > 0) { + // "" just blocks + if (lodash_1.default.compact(validationMessages).length > 0) { + alert(lodash_1.default.compact(validationMessages).join("\n")); + } + return false; + } + return true; }); - }; - PageStackDisplay.prototype.renderPageContents = function (page, pageIndex) { - var _this = this; + } + renderPageContents(page, pageIndex) { // Lookup widget - var widgetDef = this.props.baseCtx.widgetLibrary.widgets[page.widgetId]; + const widgetDef = this.props.baseCtx.widgetLibrary.widgets[page.widgetId]; if (!widgetDef) { return react_1.default.createElement("div", { className: "alert alert-danger" }, "Widget not found"); } @@ -234,30 +140,30 @@ var PageStackDisplay = /** @class */ (function (_super) { return null; } // Create outer instanceCtx. Context variables will be injected after - var outerInstanceCtx = __assign(__assign({}, this.props.baseCtx), { pageStack: this.props.overridePageStack || this, contextVars: [], contextVarValues: {}, getContextVarExprValue: function () { throw new Error("Non-existant context variable"); }, onSelectContextVar: function () { throw new Error("Non-existant context variable"); }, setFilter: function () { throw new Error("Non-existant context variable"); }, getFilters: function () { throw new Error("Non-existant context variable"); }, renderChildBlock: this.renderChildBlock, registerForValidation: this.registerChildForValidation.bind(null, pageIndex) }); - var injectedContextVars = (this.props.baseCtx.globalContextVars || []) + const outerInstanceCtx = Object.assign(Object.assign({}, this.props.baseCtx), { pageStack: this.props.overridePageStack || this, contextVars: [], contextVarValues: {}, getContextVarExprValue: () => { throw new Error("Non-existant context variable"); }, onSelectContextVar: () => { throw new Error("Non-existant context variable"); }, setFilter: () => { throw new Error("Non-existant context variable"); }, getFilters: () => { throw new Error("Non-existant context variable"); }, renderChildBlock: this.renderChildBlock, registerForValidation: this.registerChildForValidation.bind(null, pageIndex) }); + const injectedContextVars = (this.props.baseCtx.globalContextVars || []) .concat(widgetDef.contextVars) .concat(widgetDef.privateContextVars || []); // Page context var values contains global and context vars. Add private values - var injectedContextVarValues = __assign(__assign({}, page.contextVarValues), (lodash_1.default.pick(widgetDef.privateContextVarValues || {}, (widgetDef.privateContextVars || []).map(function (cv) { return cv.id; })))); + const injectedContextVarValues = Object.assign(Object.assign({}, page.contextVarValues), (lodash_1.default.pick(widgetDef.privateContextVarValues || {}, (widgetDef.privateContextVars || []).map(cv => cv.id)))); // Wrap in context var injector - return react_1.default.createElement(ContextVarsInjector_1.default, { injectedContextVars: injectedContextVars, innerBlock: widgetDef.blockDef, injectedContextVarValues: injectedContextVarValues, instanceCtx: __assign(__assign({}, outerInstanceCtx), { database: page.database }) }, function (innerInstanceCtx, loading, refreshing) { + return react_1.default.createElement(ContextVarsInjector_1.default, { injectedContextVars: injectedContextVars, innerBlock: widgetDef.blockDef, injectedContextVarValues: injectedContextVarValues, instanceCtx: Object.assign(Object.assign({}, outerInstanceCtx), { database: page.database }) }, (innerInstanceCtx, loading, refreshing) => { if (loading) { return react_1.default.createElement("div", { style: { color: "#AAA", textAlign: "center" } }, react_1.default.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); } - return (react_1.default.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, _this.renderChildBlock(innerInstanceCtx, widgetDef.blockDef))); + return (react_1.default.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, this.renderChildBlock(innerInstanceCtx, widgetDef.blockDef))); }); - }; - PageStackDisplay.prototype.renderPage = function (page, index) { + } + renderPage(page, index) { // Determine if invisible (behind a normal page) - var invisible = false; - for (var i = index + 1; i < this.state.pages.length; i++) { + let invisible = false; + for (let i = index + 1; i < this.state.pages.length; i++) { if (this.state.pages[i].type === "normal") { invisible = true; } } - var contents = this.renderPageContents(page, index); + const contents = this.renderPageContents(page, index); switch (page.type) { case "normal": return (react_1.default.createElement("div", { style: { display: invisible ? "none" : "block" }, key: index }, @@ -268,20 +174,14 @@ var PageStackDisplay = /** @class */ (function (_super) { case "inline": return (react_1.default.createElement("div", { style: { display: invisible ? "none" : "block" }, key: index }, contents)); } - }; - PageStackDisplay.prototype.render = function () { - var _this = this; - return this.state.pages.map(function (page, index) { return _this.renderPage(page, index); }); - }; - return PageStackDisplay; -}(react_1.default.Component)); -exports.PageStackDisplay = PageStackDisplay; -var NormalPage = /** @class */ (function (_super) { - __extends(NormalPage, _super); - function NormalPage() { - return _super !== null && _super.apply(this, arguments) || this; } - NormalPage.prototype.render = function () { + render() { + return this.state.pages.map((page, index) => this.renderPage(page, index)); + } +} +exports.PageStackDisplay = PageStackDisplay; +class NormalPage extends react_1.default.Component { + render() { return (react_1.default.createElement("div", { className: "normal-page" }, !this.props.isFirst || this.props.title ? react_1.default.createElement("div", { className: "normal-page-header", key: "header" }, @@ -292,16 +192,10 @@ var NormalPage = /** @class */ (function (_super) { this.props.title)) : null, react_1.default.createElement("div", { key: "contents", className: "normal-page-contents" }, this.props.children))); - }; - return NormalPage; -}(react_1.default.Component)); -var ModalPage = /** @class */ (function (_super) { - __extends(ModalPage, _super); - function ModalPage() { - return _super !== null && _super.apply(this, arguments) || this; } - ModalPage.prototype.render = function () { +} +class ModalPage extends react_1.default.Component { + render() { return (react_1.default.createElement(ModalPopupComponent_1.default, { onClose: this.props.onClose, size: this.props.size, header: this.props.title, showCloseX: true }, this.props.children)); - }; - return ModalPage; -}(react_1.default.Component)); + } +} diff --git a/lib/__fixtures__/mockDatabase.js b/lib/__fixtures__/mockDatabase.js index f3419fd3..641f0d02 100644 --- a/lib/__fixtures__/mockDatabase.js +++ b/lib/__fixtures__/mockDatabase.js @@ -1,10 +1,10 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = (function () { +exports.default = () => { return { query: jest.fn(), addChangeListener: jest.fn(), removeChangeListener: jest.fn(), transaction: jest.fn() }; -}); +}; diff --git a/lib/__fixtures__/mockInstanceCtx.js b/lib/__fixtures__/mockInstanceCtx.js index 6a99a1c3..d3e0fdf3 100644 --- a/lib/__fixtures__/mockInstanceCtx.js +++ b/lib/__fixtures__/mockInstanceCtx.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.default = (function () { +exports.default = () => { return { createBlock: jest.fn(), contextVars: [], @@ -9,7 +9,7 @@ exports.default = (function () { actionLibrary: {}, pageStack: {}, contextVarValues: {}, - getFilters: function () { return []; }, + getFilters: () => [], setFilter: jest.fn(), locale: "en", onSelectContextVar: jest.fn(), @@ -17,7 +17,7 @@ exports.default = (function () { dataSource: {}, renderChildBlock: jest.fn(), widgetLibrary: { widgets: {} }, - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => () => { }, + T: (str) => str }; -}); +}; diff --git a/lib/__fixtures__/schema.js b/lib/__fixtures__/schema.js index e1de1e79..7d20caaa 100644 --- a/lib/__fixtures__/schema.js +++ b/lib/__fixtures__/schema.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var mwater_expressions_1 = require("mwater-expressions"); +const mwater_expressions_1 = require("mwater-expressions"); function simpleSchema() { - var schema = new mwater_expressions_1.Schema(); + let schema = new mwater_expressions_1.Schema(); schema = schema.addTable({ id: "t1", name: { _base: "en", en: "T1" }, primaryKey: "primary", contents: [ { id: "text", name: { _base: "en", en: "Text" }, type: "text" }, { id: "number", name: { _base: "en", en: "Number" }, type: "number" }, diff --git a/lib/contextVarValues.js b/lib/contextVarValues.js index ab407991..fa4a0466 100644 --- a/lib/contextVarValues.js +++ b/lib/contextVarValues.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,18 +20,14 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateContextVarValue = exports.ContextVarValueEditor = void 0; -var React = __importStar(require("react")); -var blocks_1 = require("./widgets/blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const React = __importStar(require("react")); +const blocks_1 = require("./widgets/blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); /** Allows editing of the value for one context variable */ -var ContextVarValueEditor = /** @class */ (function (_super) { - __extends(ContextVarValueEditor, _super); - function ContextVarValueEditor() { - return _super !== null && _super.apply(this, arguments) || this; - } - ContextVarValueEditor.prototype.render = function () { - var value = this.props.contextVarValue; +class ContextVarValueEditor extends React.Component { + render() { + const value = this.props.contextVarValue; if (this.props.contextVar.type === "row" && this.props.schema.getTable(this.props.contextVar.table)) { return React.createElement(mwater_expressions_ui_1.IdLiteralComponent, { schema: this.props.schema, dataSource: this.props.dataSource, idTable: this.props.contextVar.table, value: value, onChange: this.props.onContextVarValueChange }); } @@ -52,28 +35,27 @@ var ContextVarValueEditor = /** @class */ (function (_super) { return React.createElement(mwater_expressions_ui_1.ExprComponent, { schema: this.props.schema, dataSource: this.props.dataSource, table: this.props.contextVar.table, types: ["boolean"], value: value, onChange: this.props.onContextVarValueChange, variables: blocks_1.createExprVariables(this.props.availContextVars) }); } return React.createElement(mwater_expressions_ui_1.ExprComponent, { schema: this.props.schema, dataSource: this.props.dataSource, table: this.props.contextVar.table || null, types: [this.props.contextVar.type], idTable: this.props.contextVar.idTable, enumValues: this.props.contextVar.enumValues, value: value, onChange: this.props.onContextVarValueChange, variables: blocks_1.createExprVariables(this.props.availContextVars), preferLiteral: true }); - }; - return ContextVarValueEditor; -}(React.Component)); + } +} exports.ContextVarValueEditor = ContextVarValueEditor; /** Validate a context var value */ function validateContextVarValue(schema, contextVar, allContextVars, value) { - var exprValidator = new mwater_expressions_1.ExprValidator(schema, blocks_1.createExprVariables(allContextVars)); + const exprValidator = new mwater_expressions_1.ExprValidator(schema, blocks_1.createExprVariables(allContextVars)); // Check type if (contextVar.type == "row") { if (value != null && typeof (value) != "string" && typeof (value) != "number") { - return "Invalid value for row variable " + contextVar.name; + return `Invalid value for row variable ${contextVar.name}`; } } else if (contextVar.type == "rowset") { // rowset must be a boolean expression - var error = exprValidator.validateExpr(value, { table: contextVar.table, types: ["boolean"] }); + const error = exprValidator.validateExpr(value, { table: contextVar.table, types: ["boolean"] }); if (error) { return error; } } else { - var error = exprValidator.validateExpr(value, { types: [contextVar.type] }); + const error = exprValidator.validateExpr(value, { types: [contextVar.type] }); if (error) { return error; } diff --git a/lib/contexts.js b/lib/contexts.js index dddf8047..809a0850 100644 --- a/lib/contexts.js +++ b/lib/contexts.js @@ -4,19 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFilteredContextVarValues = void 0; -var lodash_1 = __importDefault(require("lodash")); +const lodash_1 = __importDefault(require("lodash")); /** Gets context variables with filters baked into rowsets. Use for all queries, as that may depend on rowset filters */ function getFilteredContextVarValues(instanceCtx) { - var results = {}; - for (var _i = 0, _a = instanceCtx.contextVars; _i < _a.length; _i++) { - var cv = _a[_i]; + const results = {}; + for (const cv of instanceCtx.contextVars) { if (cv.type == "rowset") { // Create and expression - var expr = { + const expr = { type: "op", op: "and", table: cv.table, - exprs: lodash_1.default.compact([instanceCtx.contextVarValues[cv.id]].concat(lodash_1.default.map(instanceCtx.getFilters(cv.id), function (f) { return f.expr; }))) + exprs: lodash_1.default.compact([instanceCtx.contextVarValues[cv.id]].concat(lodash_1.default.map(instanceCtx.getFilters(cv.id), f => f.expr))) }; if (expr.exprs.length == 1) { results[cv.id] = expr.exprs[0]; diff --git a/lib/database/BatchingCache.js b/lib/database/BatchingCache.js index ba5b6728..26ecb233 100644 --- a/lib/database/BatchingCache.js +++ b/lib/database/BatchingCache.js @@ -4,59 +4,55 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BatchingCache = void 0; -var canonical_json_1 = __importDefault(require("canonical-json")); +const canonical_json_1 = __importDefault(require("canonical-json")); /** Cache that batches multiple identical requests to avoid repeating the same * query over and over while the first request is in progress */ -var BatchingCache = /** @class */ (function () { - function BatchingCache(process) { +class BatchingCache { + constructor(process) { this.cache = {}; this.process = process; } - BatchingCache.prototype.get = function (request) { - var _this = this; + get(request) { // Check if known - var key = canonical_json_1.default(request); - var existing = this.cache[key]; + const key = canonical_json_1.default(request); + const existing = this.cache[key]; if (existing) { if (existing.status == "complete") { return Promise.resolve(existing.value); } // Is pending, add to promises - return new Promise(function (resolve, reject) { - existing.promises.push({ resolve: resolve, reject: reject }); + return new Promise((resolve, reject) => { + existing.promises.push({ resolve, reject }); }); } // Create promise - return new Promise(function (resolve, reject) { - var entry = { - promises: [{ resolve: resolve, reject: reject }], + return new Promise((resolve, reject) => { + const entry = { + promises: [{ resolve, reject }], status: "pending", request: request }; // Add to cache - _this.cache[key] = entry; + this.cache[key] = entry; // Perform actual process - _this.process(request).then(function (value) { + this.process(request).then((value) => { // Mark completed entry.status = "complete"; entry.value = value; // Resolve all promises - for (var _i = 0, _a = entry.promises; _i < _a.length; _i++) { - var promise = _a[_i]; + for (const promise of entry.promises) { promise.resolve(value); } - }).catch(function (err) { + }).catch((err) => { // Remove from cache - delete _this.cache[key]; + delete this.cache[key]; // Reject all promises - for (var _i = 0, _a = entry.promises; _i < _a.length; _i++) { - var promise = _a[_i]; + for (const promise of entry.promises) { promise.reject(err); } }); }); - }; - return BatchingCache; -}()); + } +} exports.BatchingCache = BatchingCache; diff --git a/lib/database/DataSourceDatabase.js b/lib/database/DataSourceDatabase.js index ed9156a2..70f86753 100644 --- a/lib/database/DataSourceDatabase.js +++ b/lib/database/DataSourceDatabase.js @@ -4,23 +4,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataSourceDatabase = void 0; -var lodash_1 = __importDefault(require("lodash")); -var QueryCompiler_1 = require("./QueryCompiler"); -var blocks_1 = require("../widgets/blocks"); +const lodash_1 = __importDefault(require("lodash")); +const QueryCompiler_1 = require("./QueryCompiler"); +const blocks_1 = require("../widgets/blocks"); /** Database which is driven from a data source. Changes must be handled externally and updates triggered manually */ -var DataSourceDatabase = /** @class */ (function () { - function DataSourceDatabase(schema, dataSource, transactionHandler) { +class DataSourceDatabase { + constructor(schema, dataSource, transactionHandler) { this.schema = schema; this.dataSource = dataSource; this.transactionHandler = transactionHandler; this.changeListeners = []; } - DataSourceDatabase.prototype.query = function (options, contextVars, filteredContextVarValues) { - var _this = this; - var queryCompiler = new QueryCompiler_1.QueryCompiler(this.schema, blocks_1.createExprVariables(contextVars), blocks_1.createExprVariableValues(contextVars, filteredContextVarValues)); - var _a = queryCompiler.compileQuery(options), jsonql = _a.jsonql, rowMapper = _a.rowMapper; - return new Promise(function (resolve, reject) { - _this.dataSource.performQuery(jsonql, function (error, rows) { + query(options, contextVars, filteredContextVarValues) { + const queryCompiler = new QueryCompiler_1.QueryCompiler(this.schema, blocks_1.createExprVariables(contextVars), blocks_1.createExprVariableValues(contextVars, filteredContextVarValues)); + const { jsonql, rowMapper } = queryCompiler.compileQuery(options); + return new Promise((resolve, reject) => { + this.dataSource.performQuery(jsonql, (error, rows) => { if (error) { reject(error); } @@ -30,28 +29,26 @@ var DataSourceDatabase = /** @class */ (function () { } }); }); - }; + } /** Adds a listener which is called with each change to the database */ - DataSourceDatabase.prototype.addChangeListener = function (changeListener) { + addChangeListener(changeListener) { this.changeListeners = lodash_1.default.union(this.changeListeners, [changeListener]); - }; - DataSourceDatabase.prototype.removeChangeListener = function (changeListener) { + } + removeChangeListener(changeListener) { this.changeListeners = lodash_1.default.difference(this.changeListeners, [changeListener]); - }; + } /** Force change event to fire after clearing cache */ - DataSourceDatabase.prototype.triggerChange = function () { + triggerChange() { this.dataSource.clearCache(); - for (var _i = 0, _a = this.changeListeners; _i < _a.length; _i++) { - var changeListener = _a[_i]; + for (const changeListener of this.changeListeners) { changeListener(); } - }; - DataSourceDatabase.prototype.transaction = function () { + } + transaction() { if (!this.transactionHandler) { throw new Error("Not implemented"); } return this.transactionHandler(); - }; - return DataSourceDatabase; -}()); + } +} exports.DataSourceDatabase = DataSourceDatabase; diff --git a/lib/database/Database.js b/lib/database/Database.js index 9d91f99b..390b7a3e 100644 --- a/lib/database/Database.js +++ b/lib/database/Database.js @@ -8,300 +8,179 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useDatabaseChangeListener = exports.stableSort = exports.isQueryAggregate = exports.getWherePrimaryKey = exports.performEvalQuery = exports.NullDatabase = void 0; -var lodash_1 = __importDefault(require("lodash")); -var stable_1 = __importDefault(require("stable")); -var react_1 = require("react"); +const lodash_1 = __importDefault(require("lodash")); +const stable_1 = __importDefault(require("stable")); +const react_1 = require("react"); /** Database which performs no actions and always returns blank query results */ -var NullDatabase = /** @class */ (function () { - function NullDatabase() { +class NullDatabase { + query(options, contextVars, contextVarValues) { + return __awaiter(this, void 0, void 0, function* () { return []; }); } - NullDatabase.prototype.query = function (options, contextVars, contextVarValues) { - return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { - return [2 /*return*/, []]; - }); }); - }; /** Adds a listener which is called with each change to the database */ - NullDatabase.prototype.addChangeListener = function (changeListener) { return; }; - NullDatabase.prototype.removeChangeListener = function (changeListener) { return; }; - NullDatabase.prototype.transaction = function () { return new NullTransaction(); }; - return NullDatabase; -}()); + addChangeListener(changeListener) { return; } + removeChangeListener(changeListener) { return; } + transaction() { return new NullTransaction(); } +} exports.NullDatabase = NullDatabase; /** Transaction which performs no actions */ -var NullTransaction = /** @class */ (function () { - function NullTransaction() { - } +class NullTransaction { /** Adds a row, returning the primary key as a promise */ - NullTransaction.prototype.addRow = function (table, values) { - return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { - return [2 /*return*/, null]; - }); }); - }; - NullTransaction.prototype.updateRow = function (table, primaryKey, updates) { - return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { - return [2 /*return*/]; - }); }); - }; - NullTransaction.prototype.removeRow = function (table, primaryKey) { - return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { - return [2 /*return*/]; - }); }); - }; - NullTransaction.prototype.commit = function () { - return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { - return [2 /*return*/, []]; - }); }); - }; - return NullTransaction; -}()); + addRow(table, values) { + return __awaiter(this, void 0, void 0, function* () { return null; }); + } + updateRow(table, primaryKey, updates) { + return __awaiter(this, void 0, void 0, function* () { return; }); + } + removeRow(table, primaryKey) { + return __awaiter(this, void 0, void 0, function* () { return; }); + } + commit() { + return __awaiter(this, void 0, void 0, function* () { return []; }); + } +} /** Evaluates a database query given a set of rows of the type that are needed by the PromiseExprEvaluator. * Useful for performing a query on a non-SQL database, e.g. in memory or MongoDb, etc. */ function performEvalQuery(options) { - return __awaiter(this, void 0, void 0, function () { - var query, evalRows, exprEval, exprUtils, tempRows, contextRows_1, wherePromises, whereValues_1, selects, orderBys, contextRows, _i, tempRows_1, tempRow, i, i, _a, tempRows_2, tempRow, i, _b, _c, i, _d, _e, groups, _f, _g, group, tempRow, i, i, _h, _j, group, tempRow, i, _k, _l, i, _m, _o, tempRow, i, _p, _q, i, _r, _s, _loop_1, i, projectedRows, _t, tempRows_3, tempRow, projectedRow, i; - return __generator(this, function (_u) { - switch (_u.label) { - case 0: - query = options.query, evalRows = options.evalRows, exprEval = options.exprEval, exprUtils = options.exprUtils; - tempRows = evalRows.map(function (r) { return ({ row: r }); }); - if (!query.where) return [3 /*break*/, 2]; - contextRows_1 = tempRows.map(function (tr) { return tr.row; }); - wherePromises = tempRows.map(function (tempRow) { return exprEval.evaluate(query.where, { row: tempRow.row, rows: contextRows_1 }); }); - return [4 /*yield*/, Promise.all(wherePromises)]; - case 1: - whereValues_1 = _u.sent(); - tempRows = tempRows.filter(function (row, index) { return whereValues_1[index] == true; }); - _u.label = 2; - case 2: - selects = Object.keys(query.select).map(function (id) { return ({ - id: id, - expr: query.select[id], - isAggr: exprUtils.getExprAggrStatus(query.select[id]) === "aggregate" - }); }); - orderBys = (query.orderBy || []).map(function (orderBy) { return ({ - expr: orderBy.expr, - isAggr: exprUtils.getExprAggrStatus(orderBy.expr) === "aggregate" - }); }); - contextRows = tempRows.map(function (tr) { return tr.row; }); - for (_i = 0, tempRows_1 = tempRows; _i < tempRows_1.length; _i++) { - tempRow = tempRows_1[_i]; - for (i = 0; i < selects.length; i++) { - if (!selects[i].isAggr) { - tempRow["s" + i] = exprEval.evaluate(selects[i].expr, { row: tempRow.row, rows: contextRows }); - } - } - for (i = 0; i < orderBys.length; i++) { - if (!orderBys[i].isAggr) { - tempRow["o" + i] = exprEval.evaluate(orderBys[i].expr, { row: tempRow.row, rows: contextRows }); - } - } + return __awaiter(this, void 0, void 0, function* () { + const { query, evalRows, exprEval, exprUtils } = options; + // Create temporary rows to manipulate + let tempRows = evalRows.map(r => ({ row: r })); + // Filter by where clause (in parallel) + if (query.where) { + const contextRows = tempRows.map(tr => tr.row); + const wherePromises = tempRows.map(tempRow => exprEval.evaluate(query.where, { row: tempRow.row, rows: contextRows })); + const whereValues = yield Promise.all(wherePromises); + tempRows = tempRows.filter((row, index) => whereValues[index] == true); + } + // Get list of selects in { id, expr, isAggr } format + const selects = Object.keys(query.select).map(id => ({ + id: id, + expr: query.select[id], + isAggr: exprUtils.getExprAggrStatus(query.select[id]) === "aggregate" + })); + // Get list of orderBys in { expr, isAggr } format + const orderBys = (query.orderBy || []).map(orderBy => ({ + expr: orderBy.expr, + isAggr: exprUtils.getExprAggrStatus(orderBy.expr) === "aggregate" + })); + // Evaluate all non-aggr selects and non-aggr orderbys + const contextRows = tempRows.map(tr => tr.row); + for (const tempRow of tempRows) { + for (let i = 0; i < selects.length; i++) { + if (!selects[i].isAggr) { + tempRow["s" + i] = exprEval.evaluate(selects[i].expr, { row: tempRow.row, rows: contextRows }); + } + } + for (let i = 0; i < orderBys.length; i++) { + if (!orderBys[i].isAggr) { + tempRow["o" + i] = exprEval.evaluate(orderBys[i].expr, { row: tempRow.row, rows: contextRows }); + } + } + } + // Evaluate promises + for (const tempRow of tempRows) { + for (let i = 0; i < selects.length; i++) { + if (!selects[i].isAggr) { + tempRow["s" + i] = yield tempRow["s" + i]; + } + } + for (let i = 0; i < orderBys.length; i++) { + if (!orderBys[i].isAggr) { + tempRow["o" + i] = yield tempRow["o" + i]; + } + } + } + // If any aggregate expressions, perform transform to aggregate + if (selects.find(s => s.isAggr) || orderBys.find(o => o.isAggr)) { + // Group by all non-aggregate selects and non-aggregate order bys + const groups = lodash_1.default.groupBy(tempRows, tempRow => { + // Concat stringified version of all non-aggr values + let key = ""; + for (let i = 0; i < selects.length; i++) { + if (!selects[i].isAggr) { + key += ":" + tempRow["s" + i]; } - _a = 0, tempRows_2 = tempRows; - _u.label = 3; - case 3: - if (!(_a < tempRows_2.length)) return [3 /*break*/, 12]; - tempRow = tempRows_2[_a]; - i = 0; - _u.label = 4; - case 4: - if (!(i < selects.length)) return [3 /*break*/, 7]; - if (!!selects[i].isAggr) return [3 /*break*/, 6]; - _b = tempRow; - _c = "s" + i; - return [4 /*yield*/, tempRow["s" + i]]; - case 5: - _b[_c] = _u.sent(); - _u.label = 6; - case 6: - i++; - return [3 /*break*/, 4]; - case 7: - i = 0; - _u.label = 8; - case 8: - if (!(i < orderBys.length)) return [3 /*break*/, 11]; - if (!!orderBys[i].isAggr) return [3 /*break*/, 10]; - _d = tempRow; - _e = "o" + i; - return [4 /*yield*/, tempRow["o" + i]]; - case 9: - _d[_e] = _u.sent(); - _u.label = 10; - case 10: - i++; - return [3 /*break*/, 8]; - case 11: - _a++; - return [3 /*break*/, 3]; - case 12: - if (!(selects.find(function (s) { return s.isAggr; }) || orderBys.find(function (o) { return o.isAggr; }))) return [3 /*break*/, 23]; - groups = lodash_1.default.groupBy(tempRows, function (tempRow) { - // Concat stringified version of all non-aggr values - var key = ""; - for (var i = 0; i < selects.length; i++) { - if (!selects[i].isAggr) { - key += ":" + tempRow["s" + i]; - } - } - for (var i = 0; i < orderBys.length; i++) { - if (!orderBys[i].isAggr) { - key += ":" + tempRow["o" + i]; - } - } - return key; - }); - // Evaluate each group, adding aggregate expressions to first item of each group - for (_f = 0, _g = Object.values(groups); _f < _g.length; _f++) { - group = _g[_f]; - tempRow = group[0]; - // Evaluate all aggr selects and aggr orderbys - for (i = 0; i < selects.length; i++) { - if (selects[i].isAggr) { - tempRow["s" + i] = exprEval.evaluate(selects[i].expr, { row: tempRow.row, rows: group.map(function (r) { return r.row; }) }); - } - } - for (i = 0; i < orderBys.length; i++) { - if (orderBys[i].isAggr) { - tempRow["o" + i] = exprEval.evaluate(orderBys[i].expr, { row: tempRow.row, rows: group.map(function (r) { return r.row; }) }); - } - } + } + for (let i = 0; i < orderBys.length; i++) { + if (!orderBys[i].isAggr) { + key += ":" + tempRow["o" + i]; } - _h = 0, _j = Object.values(groups); - _u.label = 13; - case 13: - if (!(_h < _j.length)) return [3 /*break*/, 22]; - group = _j[_h]; - tempRow = group[0]; - i = 0; - _u.label = 14; - case 14: - if (!(i < selects.length)) return [3 /*break*/, 17]; - if (!selects[i].isAggr) return [3 /*break*/, 16]; - _k = tempRow; - _l = "s" + i; - return [4 /*yield*/, tempRow["s" + i]]; - case 15: - _k[_l] = _u.sent(); - _u.label = 16; - case 16: - i++; - return [3 /*break*/, 14]; - case 17: - i = 0; - _u.label = 18; - case 18: - if (!(i < orderBys.length)) return [3 /*break*/, 21]; - if (!orderBys[i].isAggr) return [3 /*break*/, 20]; - _m = tempRow; - _o = "o" + i; - return [4 /*yield*/, tempRow["o" + i]]; - case 19: - _m[_o] = _u.sent(); - _u.label = 20; - case 20: - i++; - return [3 /*break*/, 18]; - case 21: - _h++; - return [3 /*break*/, 13]; - case 22: - // Flatten groups into single rows each - tempRows = lodash_1.default.map(Object.values(groups), function (group) { return group[0]; }); - _u.label = 23; - case 23: - if (!(selects.every(function (s) { return s.isAggr; }) && orderBys.every(function (o) { return o.isAggr; }) && tempRows.length == 0)) return [3 /*break*/, 32]; - tempRow = {}; - i = 0; - _u.label = 24; - case 24: - if (!(i < selects.length)) return [3 /*break*/, 27]; - _p = tempRow; - _q = "s" + i; - return [4 /*yield*/, exprEval.evaluate(selects[i].expr, { rows: [] })]; - case 25: - _p[_q] = _u.sent(); - _u.label = 26; - case 26: - i++; - return [3 /*break*/, 24]; - case 27: - i = 0; - _u.label = 28; - case 28: - if (!(i < orderBys.length)) return [3 /*break*/, 31]; - _r = tempRow; - _s = "o" + i; - return [4 /*yield*/, exprEval.evaluate(orderBys[i].expr, { rows: [] })]; - case 29: - _r[_s] = _u.sent(); - _u.label = 30; - case 30: - i++; - return [3 /*break*/, 28]; - case 31: - tempRows.push(tempRow); - _u.label = 32; - case 32: - // Order by - if (query.orderBy && query.orderBy.length > 0) { - _loop_1 = function (i) { - tempRows = stableSort(tempRows, function (tempRow) { return tempRow["o" + i]; }, query.orderBy[i].dir); - }; - // Sort by orders in reverse to prioritize first - for (i = query.orderBy.length - 1; i >= 0; i--) { - _loop_1(i); - } + } + return key; + }); + // Evaluate each group, adding aggregate expressions to first item of each group + for (const group of Object.values(groups)) { + const tempRow = group[0]; + // Evaluate all aggr selects and aggr orderbys + for (let i = 0; i < selects.length; i++) { + if (selects[i].isAggr) { + tempRow["s" + i] = exprEval.evaluate(selects[i].expr, { row: tempRow.row, rows: group.map(r => r.row) }); } - // Limit - if (query.limit) { - tempRows = lodash_1.default.take(tempRows, query.limit); + } + for (let i = 0; i < orderBys.length; i++) { + if (orderBys[i].isAggr) { + tempRow["o" + i] = exprEval.evaluate(orderBys[i].expr, { row: tempRow.row, rows: group.map(r => r.row) }); } - projectedRows = []; - for (_t = 0, tempRows_3 = tempRows; _t < tempRows_3.length; _t++) { - tempRow = tempRows_3[_t]; - projectedRow = {}; - // Project each one - for (i = 0; i < selects.length; i++) { - projectedRow[selects[i].id] = tempRow["s" + i]; - } - projectedRows.push(projectedRow); + } + } + // Evaluate promises + for (const group of Object.values(groups)) { + const tempRow = group[0]; + // Evaluate all aggr selects and aggr orderbys + for (let i = 0; i < selects.length; i++) { + if (selects[i].isAggr) { + tempRow["s" + i] = yield tempRow["s" + i]; } - return [2 /*return*/, projectedRows]; + } + for (let i = 0; i < orderBys.length; i++) { + if (orderBys[i].isAggr) { + tempRow["o" + i] = yield tempRow["o" + i]; + } + } + } + // Flatten groups into single rows each + tempRows = lodash_1.default.map(Object.values(groups), (group) => group[0]); + } + // If all aggregate and no rows, create single row to mirror SQL behaviour of creating single evaluated row + if (selects.every(s => s.isAggr) && orderBys.every(o => o.isAggr) && tempRows.length == 0) { + const tempRow = {}; + // Evaluate all selects and orderbys + for (let i = 0; i < selects.length; i++) { + tempRow["s" + i] = yield exprEval.evaluate(selects[i].expr, { rows: [] }); } - }); + for (let i = 0; i < orderBys.length; i++) { + tempRow["o" + i] = yield exprEval.evaluate(orderBys[i].expr, { rows: [] }); + } + tempRows.push(tempRow); + } + // Order by + if (query.orderBy && query.orderBy.length > 0) { + // Sort by orders in reverse to prioritize first + for (let i = query.orderBy.length - 1; i >= 0; i--) { + tempRows = stableSort(tempRows, (tempRow) => tempRow["o" + i], query.orderBy[i].dir); + } + } + // Limit + if (query.limit) { + tempRows = lodash_1.default.take(tempRows, query.limit); + } + // Create selects + const projectedRows = []; + for (const tempRow of tempRows) { + const projectedRow = {}; + // Project each one + for (let i = 0; i < selects.length; i++) { + projectedRow[selects[i].id] = tempRow["s" + i]; + } + projectedRows.push(projectedRow); + } + return projectedRows; }); } exports.performEvalQuery = performEvalQuery; @@ -323,14 +202,12 @@ function getWherePrimaryKey(where) { exports.getWherePrimaryKey = getWherePrimaryKey; /** Determine if a query is aggregate (either select or order clauses) */ function isQueryAggregate(query, exprUtils) { - for (var _i = 0, _a = Object.values(query.select); _i < _a.length; _i++) { - var select = _a[_i]; + for (const select of Object.values(query.select)) { if (exprUtils.getExprAggrStatus(select) === "aggregate") { return true; } } - for (var _b = 0, _c = query.orderBy || []; _b < _c.length; _b++) { - var orderBy = _c[_b]; + for (const orderBy of query.orderBy || []) { if (exprUtils.getExprAggrStatus(orderBy.expr) === "aggregate") { return true; } @@ -340,7 +217,7 @@ function isQueryAggregate(query, exprUtils) { exports.isQueryAggregate = isQueryAggregate; /** Stable sort on field */ function stableSort(items, iteratee, direction) { - return stable_1.default(items, function (a, b) { return direction == "asc" ? normalCompare(iteratee(a), iteratee(b)) : normalCompare(iteratee(b), iteratee(a)); }); + return stable_1.default(items, (a, b) => direction == "asc" ? normalCompare(iteratee(a), iteratee(b)) : normalCompare(iteratee(b), iteratee(a))); } exports.stableSort = stableSort; /** Compare two values in normal sense of the word (numbers as numbers, strings as strings with locale) */ @@ -362,13 +239,13 @@ function normalCompare(a, b) { } /** Hook to listen for database changes. Returns an integer that increments with each change */ function useDatabaseChangeListener(database) { - var _a = react_1.useState(0), incr = _a[0], setIncr = _a[1]; - var listener = react_1.useCallback(function () { - setIncr(function (cur) { return cur + 1; }); + const [incr, setIncr] = react_1.useState(0); + const listener = react_1.useCallback(() => { + setIncr(cur => cur + 1); }, []); - react_1.useEffect(function () { + react_1.useEffect(() => { database.addChangeListener(listener); - return function () { + return () => { database.removeChangeListener(listener); }; }, [database]); diff --git a/lib/database/QueryCompiler.js b/lib/database/QueryCompiler.js index b580553a..69dfb7d6 100644 --- a/lib/database/QueryCompiler.js +++ b/lib/database/QueryCompiler.js @@ -20,10 +20,10 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryCompiler = void 0; -var mwater_expressions_1 = require("mwater-expressions"); -var _ = __importStar(require("lodash")); -var QueryCompiler = /** @class */ (function () { - function QueryCompiler(schema, variables, variableValues) { +const mwater_expressions_1 = require("mwater-expressions"); +const _ = __importStar(require("lodash")); +class QueryCompiler { + constructor(schema, variables, variableValues) { this.schema = schema; this.variables = variables; this.variableValues = variableValues; @@ -32,11 +32,11 @@ var QueryCompiler = /** @class */ (function () { * rows to the ones requested by the query. This is necessary due to invalid select aliases * that queries may have, so we normalize to c0, c1, etc. in the query */ - QueryCompiler.prototype.compileQuery = function (options) { - var exprUtils = new mwater_expressions_1.ExprUtils(this.schema, this.variables); - var exprCompiler = new mwater_expressions_1.ExprCompiler(this.schema, this.variables, this.variableValues); + compileQuery(options) { + const exprUtils = new mwater_expressions_1.ExprUtils(this.schema, this.variables); + const exprCompiler = new mwater_expressions_1.ExprCompiler(this.schema, this.variables, this.variableValues); // Create shell of query - var query = { + const query = { type: "query", selects: [], from: exprCompiler.compileTable(options.from, "main"), @@ -46,15 +46,15 @@ var QueryCompiler = /** @class */ (function () { if (options.distinct) { query.distinct = true; } - var colKeys = _.keys(options.select); + const colKeys = _.keys(options.select); // Determine if any aggregate - var isAggr = Object.values(options.select).some(function (expr) { return exprUtils.getExprAggrStatus(expr) === "aggregate"; }) - || (options.orderBy || []).some(function (order) { return exprUtils.getExprAggrStatus(order.expr) === "aggregate"; }); + const isAggr = Object.values(options.select).some(expr => exprUtils.getExprAggrStatus(expr) === "aggregate") + || (options.orderBy || []).some(order => exprUtils.getExprAggrStatus(order.expr) === "aggregate"); // For each column - colKeys.forEach(function (colKey, colIndex) { - var colExpr = options.select[colKey]; - var exprType = exprUtils.getExprType(colExpr); - var compiledExpr = exprCompiler.compileExpr({ expr: colExpr, tableAlias: "main" }); + colKeys.forEach((colKey, colIndex) => { + const colExpr = options.select[colKey]; + const exprType = exprUtils.getExprType(colExpr); + let compiledExpr = exprCompiler.compileExpr({ expr: colExpr, tableAlias: "main" }); // Handle special case of geometry, converting to GeoJSON if (exprType === "geometry") { // Convert to 4326 (lat/long). Force ::geometry for null @@ -78,12 +78,12 @@ var QueryCompiler = /** @class */ (function () { }); // Compile orderings if (options.orderBy) { - options.orderBy.forEach(function (order, index) { + options.orderBy.forEach((order, index) => { // Add as select so we can use ordinals. Prevents https://github.com/mWater/mwater-visualization/issues/165 query.selects.push({ type: "select", expr: exprCompiler.compileExpr({ expr: order.expr, tableAlias: "main" }), - alias: "o_" + index + alias: `o_${index}` }); query.orderBy.push({ ordinal: colKeys.length + index + 1, direction: order.dir, nulls: (order.dir === "desc" ? "last" : "first") }); // Add group by if non-aggregate @@ -101,15 +101,14 @@ var QueryCompiler = /** @class */ (function () { query.where = exprCompiler.compileExpr({ expr: options.where, tableAlias: "main" }); } // Create row mapper - var rowMapper = function (row) { + const rowMapper = (row) => { // Transform rows to change c_N to columns keys - var pairs = Object.entries(row) - .filter(function (pair) { return pair[0].startsWith("c_"); }) - .map(function (pair) { return [colKeys[parseInt(pair[0].substr(2))], pair[1]]; }); + const pairs = Object.entries(row) + .filter((pair) => pair[0].startsWith("c_")) + .map(pair => [colKeys[parseInt(pair[0].substr(2))], pair[1]]); return _.zipObject(pairs); }; - return { jsonql: query, rowMapper: rowMapper }; - }; - return QueryCompiler; -}()); + return { jsonql: query, rowMapper }; + } +} exports.QueryCompiler = QueryCompiler; diff --git a/lib/database/QueryCompiler.test.js b/lib/database/QueryCompiler.test.js index a2bdd97f..3b562100 100644 --- a/lib/database/QueryCompiler.test.js +++ b/lib/database/QueryCompiler.test.js @@ -3,18 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var QueryCompiler_1 = require("./QueryCompiler"); -var schema_1 = __importDefault(require("../__fixtures__/schema")); -var variables = [{ id: "varnumber", name: { _base: "en", en: "Varnumber" }, type: "number" }]; -var variableValues = { varnumber: { type: "literal", valueType: "number", value: 123 } }; -var schema = schema_1.default(); -var compiler = new QueryCompiler_1.QueryCompiler(schema, variables, variableValues); -test("compiles simple query", function () { - var options = { +const QueryCompiler_1 = require("./QueryCompiler"); +const schema_1 = __importDefault(require("../__fixtures__/schema")); +const variables = [{ id: "varnumber", name: { _base: "en", en: "Varnumber" }, type: "number" }]; +const variableValues = { varnumber: { type: "literal", valueType: "number", value: 123 } }; +const schema = schema_1.default(); +const compiler = new QueryCompiler_1.QueryCompiler(schema, variables, variableValues); +test("compiles simple query", () => { + const options = { select: { x: { type: "field", table: "t1", column: "text" } }, from: "t1", }; - var _a = compiler.compileQuery(options), jsonql = _a.jsonql, rowMapper = _a.rowMapper; + const { jsonql, rowMapper } = compiler.compileQuery(options); expect(jsonql).toEqual({ type: "query", selects: [ @@ -26,13 +26,13 @@ test("compiles simple query", function () { }); expect(rowMapper({ c_0: "abc", o_0: "xyz" })).toEqual({ x: "abc" }); }); -test("compiles distinct query", function () { - var options = { +test("compiles distinct query", () => { + const options = { select: { x: { type: "field", table: "t1", column: "text" } }, distinct: true, from: "t1", }; - var _a = compiler.compileQuery(options), jsonql = _a.jsonql, rowMapper = _a.rowMapper; + const { jsonql, rowMapper } = compiler.compileQuery(options); expect(jsonql).toEqual({ type: "query", selects: [ @@ -45,8 +45,8 @@ test("compiles distinct query", function () { }); expect(rowMapper({ c_0: "abc", o_0: "xyz" })).toEqual({ x: "abc" }); }); -test("compiles aggregated, limited query", function () { - var options = { +test("compiles aggregated, limited query", () => { + const options = { select: { x: { type: "field", table: "t1", column: "text" }, y: { type: "op", table: "t1", op: "count", exprs: [] } @@ -54,7 +54,7 @@ test("compiles aggregated, limited query", function () { from: "t1", limit: 10 }; - var _a = compiler.compileQuery(options), jsonql = _a.jsonql, rowMapper = _a.rowMapper; + const { jsonql, rowMapper } = compiler.compileQuery(options); expect(jsonql).toEqual({ type: "query", selects: [ @@ -68,14 +68,14 @@ test("compiles aggregated, limited query", function () { }); expect(rowMapper({ c_0: "abc", c_1: "xyz" })).toEqual({ x: "abc", y: "xyz" }); }); -test("compiles ordered where query", function () { - var options = { +test("compiles ordered where query", () => { + const options = { select: { x: { type: "field", table: "t1", column: "text" } }, from: "t1", where: { type: "field", table: "t1", column: "boolean" }, orderBy: [{ expr: { type: "field", table: "t1", column: "number" }, dir: "desc" }] }; - var _a = compiler.compileQuery(options), jsonql = _a.jsonql, rowMapper = _a.rowMapper; + const { jsonql, rowMapper } = compiler.compileQuery(options); expect(jsonql).toEqual({ type: "query", selects: [ @@ -88,12 +88,12 @@ test("compiles ordered where query", function () { orderBy: [{ ordinal: 2, direction: "desc", nulls: "last" }] }); }); -test("compiles variable query", function () { - var options = { +test("compiles variable query", () => { + const options = { select: { x: { type: "variable", variableId: "varnumber" } }, from: "t1", }; - var _a = compiler.compileQuery(options), jsonql = _a.jsonql, rowMapper = _a.rowMapper; + const { jsonql, rowMapper } = compiler.compileQuery(options); expect(jsonql).toEqual({ type: "query", selects: [ diff --git a/lib/database/VirtualDatabase.js b/lib/database/VirtualDatabase.js index 733a2b51..6365b5b5 100644 --- a/lib/database/VirtualDatabase.js +++ b/lib/database/VirtualDatabase.js @@ -1,15 +1,4 @@ "use strict"; -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) { @@ -19,60 +8,31 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var Database_1 = require("./Database"); -var mwater_expressions_1 = require("mwater-expressions"); -var lodash_1 = __importDefault(require("lodash")); -var uuid_1 = require("uuid"); -var blocks_1 = require("../widgets/blocks"); -var BatchingCache_1 = require("./BatchingCache"); +const Database_1 = require("./Database"); +const mwater_expressions_1 = require("mwater-expressions"); +const lodash_1 = __importDefault(require("lodash")); +const uuid_1 = require("uuid"); +const blocks_1 = require("../widgets/blocks"); +const BatchingCache_1 = require("./BatchingCache"); /** * Database which is backed by a real database, but can accept changes such as adds, updates or removes * without sending them to the real database until commit is called. * The query results obtained from the database incorporate the changes that have been made to it (mutations). * commit or rollback must be called to unlisten for changes and the database should be discarded thereafter. */ -var VirtualDatabase = /** @class */ (function () { - function VirtualDatabase(database, schema, locale) { - var _this = this; - this.handleChange = function () { - for (var _i = 0, _a = _this.changeListeners; _i < _a.length; _i++) { - var changeListener = _a[_i]; +class VirtualDatabase { + constructor(database, schema, locale) { + this.handleChange = () => { + for (const changeListener of this.changeListeners) { changeListener(); } // Clear caches - _this.queryCache = new BatchingCache_1.BatchingCache(function (request) { - return _this.database.query(request.queryOptions, request.contextVars, request.contextVarValues); + this.queryCache = new BatchingCache_1.BatchingCache(request => { + return this.database.query(request.queryOptions, request.contextVars, request.contextVarValues); }); }; this.database = database; @@ -83,52 +43,43 @@ var VirtualDatabase = /** @class */ (function () { this.tempPrimaryKeys = []; this.destroyed = false; // Create cache that calls underlying database - this.queryCache = new BatchingCache_1.BatchingCache(function (request) { - return _this.database.query(request.queryOptions, request.contextVars, request.contextVarValues); + this.queryCache = new BatchingCache_1.BatchingCache(request => { + return this.database.query(request.queryOptions, request.contextVars, request.contextVarValues); }); database.addChangeListener(this.handleChange); } - VirtualDatabase.prototype.query = function (query, contextVars, contextVarValues) { - return __awaiter(this, void 0, void 0, function () { - var variables, variableValues, exprUtils, exprEval, evalRows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - variables = blocks_1.createExprVariables(contextVars); - variableValues = blocks_1.createExprVariableValues(contextVars, contextVarValues); - exprUtils = new mwater_expressions_1.ExprUtils(this.schema, variables); - // Pass through if no changes and not id query - if (this.shouldPassthrough(query, exprUtils, contextVars, contextVarValues)) { - return [2 /*return*/, this.database.query(query, contextVars, contextVarValues)]; - } - exprEval = new mwater_expressions_1.PromiseExprEvaluator({ schema: this.schema, locale: this.locale, variables: variables, variableValues: variableValues }); - return [4 /*yield*/, this.queryEvalRows(query.from, query.where || null, contextVars, contextVarValues)]; - case 1: - evalRows = (_a.sent()); - // Perform actual query - return [2 /*return*/, Database_1.performEvalQuery({ evalRows: evalRows, exprUtils: exprUtils, exprEval: exprEval, query: query })]; - } - }); + query(query, contextVars, contextVarValues) { + return __awaiter(this, void 0, void 0, function* () { + const variables = blocks_1.createExprVariables(contextVars); + const variableValues = blocks_1.createExprVariableValues(contextVars, contextVarValues); + const exprUtils = new mwater_expressions_1.ExprUtils(this.schema, variables); + // Pass through if no changes and not id query + if (this.shouldPassthrough(query, exprUtils, contextVars, contextVarValues)) { + return this.database.query(query, contextVars, contextVarValues); + } + const exprEval = new mwater_expressions_1.PromiseExprEvaluator({ schema: this.schema, locale: this.locale, variables, variableValues }); + // Create rows to evaluate (just use where clause to filter) + const evalRows = (yield this.queryEvalRows(query.from, query.where || null, contextVars, contextVarValues)); + // Perform actual query + return Database_1.performEvalQuery({ evalRows, exprUtils, exprEval, query: query }); }); - }; + } /** Determine if query should be simply sent to the underlying database. * Do if no mutations to any tables referenced *and* it is not a simple id = query which * is best to cache *and* it doesn't reference temporary primary keys */ - VirtualDatabase.prototype.shouldPassthrough = function (query, exprUtils, contextVars, contextVarValues) { + shouldPassthrough(query, exprUtils, contextVars, contextVarValues) { // Determine which tables are referenced - var tablesReferenced = [query.from]; - for (var _i = 0, _a = Object.values(query.select); _i < _a.length; _i++) { - var expr = _a[_i]; - tablesReferenced = tablesReferenced.concat(exprUtils.getReferencedFields(expr).map(function (f) { return f.table; })); + let tablesReferenced = [query.from]; + for (const expr of Object.values(query.select)) { + tablesReferenced = tablesReferenced.concat(exprUtils.getReferencedFields(expr).map(f => f.table)); } - tablesReferenced = tablesReferenced.concat(exprUtils.getReferencedFields(query.where || null).map(function (f) { return f.table; })); - for (var _b = 0, _c = query.orderBy || []; _b < _c.length; _b++) { - var orderBy = _c[_b]; - tablesReferenced = tablesReferenced.concat(exprUtils.getReferencedFields(orderBy.expr).map(function (f) { return f.table; })); + tablesReferenced = tablesReferenced.concat(exprUtils.getReferencedFields(query.where || null).map(f => f.table)); + for (const orderBy of query.orderBy || []) { + tablesReferenced = tablesReferenced.concat(exprUtils.getReferencedFields(orderBy.expr).map(f => f.table)); } tablesReferenced = lodash_1.default.uniq(tablesReferenced); - var mutatedTables = lodash_1.default.uniq(this.mutations.map(function (m) { return m.table; })); + const mutatedTables = lodash_1.default.uniq(this.mutations.map(m => m.table)); // Can't passthrough if depends on mutated table if (lodash_1.default.intersection(tablesReferenced, mutatedTables).length > 0) { return false; @@ -142,109 +93,86 @@ var VirtualDatabase = /** @class */ (function () { return false; } return true; - }; + } /** Test if an expression references a temporary primary key, meaning it cannot be sent to the server */ - VirtualDatabase.prototype.doesReferenceTempPk = function (expr, exprUtils, contextVars, contextVarValues) { - var _this = this; + doesReferenceTempPk(expr, exprUtils, contextVars, contextVarValues) { if (!expr) { return false; } // Inline variables, since if an expression references a variable that has the value of a temporary primary key, // it won't show up in the JSON unless inlined - var inlinedExpr = exprUtils.inlineVariableValues(expr, blocks_1.createExprVariableValues(contextVars, contextVarValues)); - return (JSON.stringify(inlinedExpr).match(/"pk_[0-9a-zA-Z]+_temp"/g) || []).some(function (m) { return _this.tempPrimaryKeys.includes(JSON.parse(m)); }); - }; + const inlinedExpr = exprUtils.inlineVariableValues(expr, blocks_1.createExprVariableValues(contextVars, contextVarValues)); + return (JSON.stringify(inlinedExpr).match(/"pk_[0-9a-zA-Z]+_temp"/g) || []).some(m => this.tempPrimaryKeys.includes(JSON.parse(m))); + } /** Adds a listener which is called with each change to the database */ - VirtualDatabase.prototype.addChangeListener = function (changeListener) { + addChangeListener(changeListener) { this.changeListeners = lodash_1.default.union(this.changeListeners, [changeListener]); - }; - VirtualDatabase.prototype.removeChangeListener = function (changeListener) { + } + removeChangeListener(changeListener) { this.changeListeners = lodash_1.default.difference(this.changeListeners, [changeListener]); - }; - VirtualDatabase.prototype.transaction = function () { + } + transaction() { if (this.destroyed) { throw new Error("Cannot start transaction on destroyed database"); } return new VirtualDatabaseTransaction(this); - }; + } /** Commit the changes that have been applied to this virtual database to the real underlying database and destroy the virtual database */ - VirtualDatabase.prototype.commit = function () { - return __awaiter(this, void 0, void 0, function () { - var txn, pkMapping, _i, _a, mutation, _b, mappedValues, primaryKey, mappedUpdates, updatePrimaryKey, removePrimaryKey; - return __generator(this, function (_c) { - switch (_c.label) { - case 0: - if (this.mutations.length === 0) { - this.destroyed = true; - this.database.removeChangeListener(this.handleChange); - return [2 /*return*/]; - } - txn = this.database.transaction(); - pkMapping = {}; - _i = 0, _a = this.mutations; - _c.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 9]; - mutation = _a[_i]; - _b = mutation.type; - switch (_b) { - case "add": return [3 /*break*/, 2]; - case "update": return [3 /*break*/, 4]; - case "remove": return [3 /*break*/, 6]; - } - return [3 /*break*/, 8]; - case 2: - mappedValues = this.replaceTempPrimaryKeys(mutation.values, function (pk) { + commit() { + return __awaiter(this, void 0, void 0, function* () { + if (this.mutations.length === 0) { + this.destroyed = true; + this.database.removeChangeListener(this.handleChange); + return; + } + // Apply mutations in one transaction + const txn = this.database.transaction(); + // Store mapping from temp to real primary keys + const pkMapping = {}; + for (const mutation of this.mutations) { + switch (mutation.type) { + case "add": + // Map any primary keys + const mappedValues = this.replaceTempPrimaryKeys(mutation.values, (pk) => { if (pkMapping[pk]) { return pkMapping[pk]; } throw new Error("Missing mapping for " + pk); }); - return [4 /*yield*/, txn.addRow(mutation.table, mappedValues)]; - case 3: - primaryKey = _c.sent(); + const primaryKey = yield txn.addRow(mutation.table, mappedValues); pkMapping[mutation.primaryKey] = primaryKey; - return [3 /*break*/, 8]; - case 4: - mappedUpdates = this.replaceTempPrimaryKeys(mutation.updates, function (pk) { + break; + case "update": + // Map any primary keys + const mappedUpdates = this.replaceTempPrimaryKeys(mutation.updates, (pk) => { if (pkMapping[pk]) { return pkMapping[pk]; } throw new Error("Missing mapping for " + pk); }); - updatePrimaryKey = pkMapping[mutation.primaryKey] ? pkMapping[mutation.primaryKey] : mutation.primaryKey; - return [4 /*yield*/, txn.updateRow(mutation.table, updatePrimaryKey, mappedUpdates)]; - case 5: - _c.sent(); - return [3 /*break*/, 8]; - case 6: - removePrimaryKey = pkMapping[mutation.primaryKey] ? pkMapping[mutation.primaryKey] : mutation.primaryKey; - return [4 /*yield*/, txn.removeRow(mutation.table, removePrimaryKey)]; - case 7: - _c.sent(); - return [3 /*break*/, 8]; - case 8: - _i++; - return [3 /*break*/, 1]; - case 9: return [4 /*yield*/, txn.commit()]; - case 10: - _c.sent(); - this.mutations = []; - this.destroyed = true; - this.database.removeChangeListener(this.handleChange); - return [2 /*return*/]; + const updatePrimaryKey = pkMapping[mutation.primaryKey] ? pkMapping[mutation.primaryKey] : mutation.primaryKey; + yield txn.updateRow(mutation.table, updatePrimaryKey, mappedUpdates); + break; + case "remove": + const removePrimaryKey = pkMapping[mutation.primaryKey] ? pkMapping[mutation.primaryKey] : mutation.primaryKey; + yield txn.removeRow(mutation.table, removePrimaryKey); + break; } - }); + } + yield txn.commit(); + this.mutations = []; + this.destroyed = true; + this.database.removeChangeListener(this.handleChange); }); - }; + } /** Rollback any changes and destroy the virtual database */ - VirtualDatabase.prototype.rollback = function () { + rollback() { this.mutations = []; this.destroyed = true; this.database.removeChangeListener(this.handleChange); - }; + } /** Determine if a column should be included in the underlying query */ - VirtualDatabase.prototype.shouldIncludeColumn = function (column) { + shouldIncludeColumn(column) { // Compute expressions on the fly if (column.expr) { return false; @@ -254,245 +182,202 @@ var VirtualDatabase = /** @class */ (function () { return false; } return true; - }; + } /** Create the rows as needed by PromiseExprEvaluator for a query */ - VirtualDatabase.prototype.queryEvalRows = function (from, where, contextVars, contextVarValues) { - return __awaiter(this, void 0, void 0, function () { - var variables, exprUtils, queryOptions, updatedIds, _i, _a, column, rows; - var _this = this; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - variables = blocks_1.createExprVariables(contextVars); - exprUtils = new mwater_expressions_1.ExprUtils(this.schema, variables); - queryOptions = { - select: { - id: { type: "id", table: from } - }, - from: from, - where: where - }; - updatedIds = lodash_1.default.uniq(this.mutations.filter(function (m) { return m.type == "update"; }).map(function (m) { return m.primaryKey; })); - if (updatedIds.length > 0 && where) { - queryOptions.where = { - type: "op", - op: "or", - table: from, - exprs: [ - { type: "op", table: from, op: "= any", exprs: [ - { type: "id", table: from }, - { type: "literal", valueType: "id[]", idTable: from, value: updatedIds } - ] }, - where - ] - }; - } - // Add a select for each column - for (_i = 0, _a = this.schema.getColumns(from); _i < _a.length; _i++) { - column = _a[_i]; - if (this.shouldIncludeColumn(column)) { - queryOptions.select["c_" + column.id] = { type: "field", table: from, column: column.id }; - } - } - if (!this.tempPrimaryKeys.includes(Database_1.getWherePrimaryKey(where))) return [3 /*break*/, 1]; - rows = []; - return [3 /*break*/, 4]; - case 1: - if (!this.doesReferenceTempPk(where, exprUtils, contextVars, contextVarValues)) return [3 /*break*/, 2]; - // This is a tricky decision, as there is a query that references a temporary primary key - // and as such, rows that do not exist. This part of the query cannot be sent to the real - // database. However, a query that had a *not* on that condition would incorrectly be missing - // any real matching rows. - rows = []; - return [3 /*break*/, 4]; - case 2: return [4 /*yield*/, this.queryCache.get({ queryOptions: queryOptions, contextVars: contextVars, contextVarValues: contextVarValues })]; - case 3: - rows = _b.sent(); - _b.label = 4; - case 4: return [4 /*yield*/, this.mutateRows(rows, from, where, contextVars, contextVarValues) - // Convert to rows as expr evaluator expects - ]; - case 5: - // Apply mutations - rows = _b.sent(); - // Convert to rows as expr evaluator expects - return [2 /*return*/, rows.map(function (row) { return _this.createEvalRow(row, from, contextVars, contextVarValues); })]; + queryEvalRows(from, where, contextVars, contextVarValues) { + return __awaiter(this, void 0, void 0, function* () { + const variables = blocks_1.createExprVariables(contextVars); + const exprUtils = new mwater_expressions_1.ExprUtils(this.schema, variables); + // Create query with c_ for all columns, id and just the where clause + let queryOptions = { + select: { + id: { type: "id", table: from } + }, + from: from, + where: where + }; + // Alter where clause to include any rows that have been updated, as the update + // may have altered the row in such a way as it now matches the where clause + const updatedIds = lodash_1.default.uniq(this.mutations.filter(m => m.type == "update").map(m => m.primaryKey)); + if (updatedIds.length > 0 && where) { + queryOptions.where = { + type: "op", + op: "or", + table: from, + exprs: [ + { type: "op", table: from, op: "= any", exprs: [ + { type: "id", table: from }, + { type: "literal", valueType: "id[]", idTable: from, value: updatedIds } + ] }, + where + ] + }; + } + // Add a select for each column + for (const column of this.schema.getColumns(from)) { + if (this.shouldIncludeColumn(column)) { + queryOptions.select["c_" + column.id] = { type: "field", table: from, column: column.id }; } - }); + } + // Perform query + let rows; + // Skip if us just a query on a temporary row, which will not match anything + if (this.tempPrimaryKeys.includes(Database_1.getWherePrimaryKey(where))) { + rows = []; + } + else if (this.doesReferenceTempPk(where, exprUtils, contextVars, contextVarValues)) { + // This is a tricky decision, as there is a query that references a temporary primary key + // and as such, rows that do not exist. This part of the query cannot be sent to the real + // database. However, a query that had a *not* on that condition would incorrectly be missing + // any real matching rows. + rows = []; + } + else { + rows = yield this.queryCache.get({ queryOptions: queryOptions, contextVars: contextVars, contextVarValues: contextVarValues }); + } + // Apply mutations + rows = yield this.mutateRows(rows, from, where, contextVars, contextVarValues); + // Convert to rows as expr evaluator expects + return rows.map(row => this.createEvalRow(row, from, contextVars, contextVarValues)); }); - }; + } /** Replace temporary primary keys with different value */ - VirtualDatabase.prototype.replaceTempPrimaryKeys = function (input, replaceWith) { - var json = JSON.stringify(input); - json = json.replace(new RegExp(/"pk_[0-9a-zA-Z]+_temp"/, "g"), function (tempPkJson) { return JSON.stringify(replaceWith(JSON.parse(tempPkJson))); }); + replaceTempPrimaryKeys(input, replaceWith) { + let json = JSON.stringify(input); + json = json.replace(new RegExp(/"pk_[0-9a-zA-Z]+_temp"/, "g"), (tempPkJson) => JSON.stringify(replaceWith(JSON.parse(tempPkJson)))); return JSON.parse(json); - }; + } /** Create a single row structured for evaluation from a row in format { id: , c_: value, ... } */ - VirtualDatabase.prototype.createEvalRow = function (row, from, contextVars, contextVarValues) { - var _this = this; + createEvalRow(row, from, contextVars, contextVarValues) { return { - getPrimaryKey: function () { return Promise.resolve(row.id); }, - getField: function (columnId) { return __awaiter(_this, void 0, void 0, function () { - var column, joinRows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - column = this.schema.getColumn(from, columnId); - if (!(column.type === "join" && column.join.type == "1-n" && column.join.inverse)) return [3 /*break*/, 2]; - return [4 /*yield*/, this.queryEvalRows(column.join.toTable, { - type: "op", op: "=", - table: column.join.toTable, exprs: [ - { type: "field", table: column.join.toTable, column: column.join.inverse }, - { type: "literal", valueType: "id", idTable: from, value: row.id } - ] - }, contextVars, contextVarValues)]; - case 1: - joinRows = _a.sent(); - return [2 /*return*/, Promise.all(joinRows.map(function (r) { return r.getPrimaryKey(); }))]; - case 2: - // Non n-1 or 1-1 joins not available - if (column.type == "join" && column.join.type != "n-1" && column.join.type != "1-1") { - console.warn("Attempt to get join field " + columnId); - return [2 /*return*/, null]; - } - // Return simple value - return [2 /*return*/, row["c_" + columnId]]; + getPrimaryKey: () => Promise.resolve(row.id), + getField: (columnId) => __awaiter(this, void 0, void 0, function* () { + const column = this.schema.getColumn(from, columnId); + // Special case is 1-n join with inverse, as they are not included in the query + if (column.type === "join" && column.join.type == "1-n" && column.join.inverse) { + // Get the rows and then extract the primary keys + const joinRows = yield this.queryEvalRows(column.join.toTable, { + type: "op", op: "=", + table: column.join.toTable, exprs: [ + { type: "field", table: column.join.toTable, column: column.join.inverse }, + { type: "literal", valueType: "id", idTable: from, value: row.id } + ] + }, contextVars, contextVarValues); + return Promise.all(joinRows.map(r => r.getPrimaryKey())); + } + // Non n-1 or 1-1 joins not available + if (column.type == "join" && column.join.type != "n-1" && column.join.type != "1-1") { + console.warn(`Attempt to get join field ${columnId}`); + return null; + } + // Return simple value + return row["c_" + columnId]; + }), + followJoin: (columnId) => __awaiter(this, void 0, void 0, function* () { + const column = this.schema.getColumn(from, columnId); + const idTable = column.type == "id" || column.type == "id[]" ? column.idTable : column.join.toTable; + // Inverse 1-n uses the inverse column to get rows, as these are not included in the row values + if (column.type == "join" && column.join.type === "1-n" && column.join.inverse) { + const joinRows = yield this.queryEvalRows(column.join.toTable, { + type: "op", op: "=", table: idTable, + exprs: [ + { type: "field", table: idTable, column: column.join.inverse }, + { type: "literal", valueType: "id", idTable: from, value: row.id } + ] + }, contextVars, contextVarValues); + return joinRows; + } + // Non n-1 or 1-1 joins not available + if (column.type == "join" && column.join.type != "n-1" && column.join.type != "1-1") { + console.warn(`Attempt to get join field ${columnId}`); + return null; + } + // For ones with single row + if (column.type == "id" || column.type == "join") { + // Short-circuit if null/undefined + if (row["c_" + columnId] == null) { + return null; } - }); - }); }, - followJoin: function (columnId) { return __awaiter(_this, void 0, void 0, function () { - var column, idTable, joinRows, joinRows, joinRows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - column = this.schema.getColumn(from, columnId); - idTable = column.type == "id" || column.type == "id[]" ? column.idTable : column.join.toTable; - if (!(column.type == "join" && column.join.type === "1-n" && column.join.inverse)) return [3 /*break*/, 2]; - return [4 /*yield*/, this.queryEvalRows(column.join.toTable, { - type: "op", op: "=", table: idTable, - exprs: [ - { type: "field", table: idTable, column: column.join.inverse }, - { type: "literal", valueType: "id", idTable: from, value: row.id } - ] - }, contextVars, contextVarValues)]; - case 1: - joinRows = _a.sent(); - return [2 /*return*/, joinRows]; - case 2: - // Non n-1 or 1-1 joins not available - if (column.type == "join" && column.join.type != "n-1" && column.join.type != "1-1") { - console.warn("Attempt to get join field " + columnId); - return [2 /*return*/, null]; - } - if (!(column.type == "id" || column.type == "join")) return [3 /*break*/, 4]; - // Short-circuit if null/undefined - if (row["c_" + columnId] == null) { - return [2 /*return*/, null]; - } - return [4 /*yield*/, this.queryEvalRows(idTable, { - type: "op", op: "=", table: idTable, exprs: [ - { type: "id", table: idTable }, - { type: "literal", valueType: "id", idTable: idTable, value: row["c_" + columnId] } - ] - }, contextVars, contextVarValues)]; - case 3: - joinRows = _a.sent(); - return [2 /*return*/, joinRows[0] || null]; - case 4: - if (!(column.type == "id[]")) return [3 /*break*/, 6]; - // Short-circuit if null/undefined - if (row["c_" + columnId] == null || row["c_" + columnId].length == 0) { - return [2 /*return*/, []]; - } - return [4 /*yield*/, this.queryEvalRows(idTable, { - type: "op", op: "= any", table: idTable, exprs: [ - { type: "id", table: idTable }, - { type: "literal", valueType: "id", idTable: idTable, value: row["c_" + columnId] } - ] - }, contextVars, contextVarValues)]; - case 5: - joinRows = _a.sent(); - return [2 /*return*/, joinRows]; - case 6: throw new Error("Not implemented"); + const joinRows = yield this.queryEvalRows(idTable, { + type: "op", op: "=", table: idTable, exprs: [ + { type: "id", table: idTable }, + { type: "literal", valueType: "id", idTable: idTable, value: row["c_" + columnId] } + ] + }, contextVars, contextVarValues); + return joinRows[0] || null; + } + // For ones with multiple rows + if (column.type == "id[]") { + // Short-circuit if null/undefined + if (row["c_" + columnId] == null || row["c_" + columnId].length == 0) { + return []; } - }); - }); } + const joinRows = yield this.queryEvalRows(idTable, { + type: "op", op: "= any", table: idTable, exprs: [ + { type: "id", table: idTable }, + { type: "literal", valueType: "id", idTable: idTable, value: row["c_" + columnId] } + ] + }, contextVars, contextVarValues); + return joinRows; + } + throw new Error("Not implemented"); + }) }; - }; + } /** Apply all known mutations to a set of rows */ - VirtualDatabase.prototype.mutateRows = function (rows, from, where, contextVars, contextVarValues) { - return __awaiter(this, void 0, void 0, function () { - var variables, variableValues, _loop_1, _i, _a, mutation, filteredRows, exprEval, _b, rows_1, row, evalRow; - return __generator(this, function (_c) { - switch (_c.label) { - case 0: - variables = blocks_1.createExprVariables(contextVars); - variableValues = blocks_1.createExprVariableValues(contextVars, contextVarValues); - // Copy rows to be mutated safely - rows = rows.slice(); - _loop_1 = function (mutation) { - // Only from correct table - if (mutation.table !== from) { - return "continue"; - } - if (mutation.type === "add") { - var newRow = lodash_1.default.mapKeys(mutation.values, function (v, k) { return "c_" + k; }); - rows.push(__assign({ id: mutation.primaryKey }, newRow)); - } - // TODO: This is O(nxm) where n is number of rows and m - if (mutation.type === "update") { - for (var i = 0; i < rows.length; i++) { - if (rows[i].id === mutation.primaryKey) { - var update = lodash_1.default.mapKeys(mutation.updates, function (v, k) { return "c_" + k; }); - rows[i] = __assign(__assign({}, rows[i]), update); - } - } - } - if (mutation.type === "remove") { - rows = rows.filter(function (row) { return row.id !== mutation.primaryKey; }); - } - }; - for (_i = 0, _a = this.mutations; _i < _a.length; _i++) { - mutation = _a[_i]; - _loop_1(mutation); - } - if (!where) return [3 /*break*/, 5]; - filteredRows = []; - exprEval = new mwater_expressions_1.PromiseExprEvaluator({ schema: this.schema, locale: this.locale, variables: variables, variableValues: variableValues }); - _b = 0, rows_1 = rows; - _c.label = 1; - case 1: - if (!(_b < rows_1.length)) return [3 /*break*/, 4]; - row = rows_1[_b]; - evalRow = this.createEvalRow(row, from, contextVars, contextVarValues); - return [4 /*yield*/, exprEval.evaluate(where, { row: evalRow })]; - case 2: - if (_c.sent()) { - filteredRows.push(row); + mutateRows(rows, from, where, contextVars, contextVarValues) { + return __awaiter(this, void 0, void 0, function* () { + const variables = blocks_1.createExprVariables(contextVars); + const variableValues = blocks_1.createExprVariableValues(contextVars, contextVarValues); + // Copy rows to be mutated safely + rows = rows.slice(); + for (const mutation of this.mutations) { + // Only from correct table + if (mutation.table !== from) { + continue; + } + if (mutation.type === "add") { + const newRow = lodash_1.default.mapKeys(mutation.values, (v, k) => "c_" + k); + rows.push(Object.assign({ id: mutation.primaryKey }, newRow)); + } + // TODO: This is O(nxm) where n is number of rows and m + if (mutation.type === "update") { + for (let i = 0; i < rows.length; i++) { + if (rows[i].id === mutation.primaryKey) { + const update = lodash_1.default.mapKeys(mutation.updates, (v, k) => "c_" + k); + rows[i] = Object.assign(Object.assign({}, rows[i]), update); } - _c.label = 3; - case 3: - _b++; - return [3 /*break*/, 1]; - case 4: - rows = filteredRows; - _c.label = 5; - case 5: return [2 /*return*/, rows]; + } } - }); + if (mutation.type === "remove") { + rows = rows.filter(row => row.id !== mutation.primaryKey); + } + } + // Re-filter rows + if (where) { + const filteredRows = []; + const exprEval = new mwater_expressions_1.PromiseExprEvaluator({ schema: this.schema, locale: this.locale, variables, variableValues }); + for (const row of rows) { + const evalRow = this.createEvalRow(row, from, contextVars, contextVarValues); + if (yield exprEval.evaluate(where, { row: evalRow })) { + filteredRows.push(row); + } + } + rows = filteredRows; + } + return rows; }); - }; - return VirtualDatabase; -}()); + } +} exports.default = VirtualDatabase; -var VirtualDatabaseTransaction = /** @class */ (function () { - function VirtualDatabaseTransaction(virtualDatabase) { +class VirtualDatabaseTransaction { + constructor(virtualDatabase) { this.virtualDatabase = virtualDatabase; this.mutations = []; } - VirtualDatabaseTransaction.prototype.addRow = function (table, values) { + addRow(table, values) { // Use a pattern for easy replacement - var primaryKey = "pk_" + uuid_1.v4().replace(/-/g, "") + "_temp"; + const primaryKey = `pk_${uuid_1.v4().replace(/-/g, "")}_temp`; // Save temporary primary key this.virtualDatabase.tempPrimaryKeys.push(primaryKey); this.mutations.push({ @@ -502,8 +387,8 @@ var VirtualDatabaseTransaction = /** @class */ (function () { values: values }); return Promise.resolve(primaryKey); - }; - VirtualDatabaseTransaction.prototype.updateRow = function (table, primaryKey, updates) { + } + updateRow(table, primaryKey, updates) { this.mutations.push({ type: "update", table: table, @@ -511,12 +396,12 @@ var VirtualDatabaseTransaction = /** @class */ (function () { updates: updates }); return Promise.resolve(); - }; - VirtualDatabaseTransaction.prototype.removeRow = function (table, primaryKey) { + } + removeRow(table, primaryKey) { // Remove locally if local if (this.virtualDatabase.tempPrimaryKeys.includes(primaryKey)) { - this.mutations = this.mutations.filter(function (m) { return m.primaryKey !== primaryKey; }); - this.virtualDatabase.mutations = this.virtualDatabase.mutations.filter(function (m) { return m.primaryKey !== primaryKey; }); + this.mutations = this.mutations.filter(m => m.primaryKey !== primaryKey); + this.virtualDatabase.mutations = this.virtualDatabase.mutations.filter(m => m.primaryKey !== primaryKey); return Promise.resolve(); } this.mutations.push({ @@ -525,64 +410,51 @@ var VirtualDatabaseTransaction = /** @class */ (function () { primaryKey: primaryKey }); return Promise.resolve(); - }; - VirtualDatabaseTransaction.prototype.commit = function () { - var primaryKeys = this.mutations.map(function (m) { return m.type == "add" ? m.primaryKey : null; }); - var _loop_2 = function (mutation) { + } + commit() { + const primaryKeys = this.mutations.map(m => m.type == "add" ? m.primaryKey : null); + // Clear mutations and transfer to main database + for (const mutation of this.mutations) { if (mutation.type == "add") { // Add mutations are always performed - this_1.virtualDatabase.mutations.push(mutation); + this.virtualDatabase.mutations.push(mutation); } else if (mutation.type == "update") { // Combine with add if present - var existingAdd = this_1.virtualDatabase.mutations.find(function (m) { - return m.table == mutation.table - && m.type == "add" - && m.primaryKey == mutation.primaryKey; - }); + const existingAdd = this.virtualDatabase.mutations.find(m => m.table == mutation.table + && m.type == "add" + && m.primaryKey == mutation.primaryKey); if (existingAdd) { - existingAdd.values = __assign(__assign({}, existingAdd.values), mutation.updates); - return "continue"; + existingAdd.values = Object.assign(Object.assign({}, existingAdd.values), mutation.updates); + continue; } // Combine with update if present - var existingUpdate = this_1.virtualDatabase.mutations.find(function (m) { - return m.table == mutation.table - && m.type == "update" - && m.primaryKey == mutation.primaryKey; - }); + const existingUpdate = this.virtualDatabase.mutations.find(m => m.table == mutation.table + && m.type == "update" + && m.primaryKey == mutation.primaryKey); if (existingUpdate) { - existingUpdate.updates = __assign(__assign({}, existingUpdate.updates), mutation.updates); - return "continue"; + existingUpdate.updates = Object.assign(Object.assign({}, existingUpdate.updates), mutation.updates); + continue; } - this_1.virtualDatabase.mutations.push(mutation); + this.virtualDatabase.mutations.push(mutation); } else if (mutation.type == "remove") { // Remove add if present // Combine with add if present - var existingAddIndex = this_1.virtualDatabase.mutations.findIndex(function (m) { - return m.table == mutation.table - && m.type == "add" - && m.primaryKey == mutation.primaryKey; - }); + const existingAddIndex = this.virtualDatabase.mutations.findIndex(m => m.table == mutation.table + && m.type == "add" + && m.primaryKey == mutation.primaryKey); if (existingAddIndex >= 0) { - this_1.virtualDatabase.mutations.splice(existingAddIndex, 1); - return "continue"; + this.virtualDatabase.mutations.splice(existingAddIndex, 1); + continue; } - this_1.virtualDatabase.mutations.push(mutation); + this.virtualDatabase.mutations.push(mutation); } - }; - var this_1 = this; - // Clear mutations and transfer to main database - for (var _i = 0, _a = this.mutations; _i < _a.length; _i++) { - var mutation = _a[_i]; - _loop_2(mutation); } this.mutations = []; - for (var _b = 0, _c = this.virtualDatabase.changeListeners; _b < _c.length; _b++) { - var changeListener = _c[_b]; + for (const changeListener of this.virtualDatabase.changeListeners) { changeListener(); } return Promise.resolve(primaryKeys); - }; - return VirtualDatabaseTransaction; -}()); + } +} diff --git a/lib/database/VirtualDatabase.test.js b/lib/database/VirtualDatabase.test.js index 7d38cdcc..27c1234a 100644 --- a/lib/database/VirtualDatabase.test.js +++ b/lib/database/VirtualDatabase.test.js @@ -27,46 +27,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var VirtualDatabase_1 = __importDefault(require("./VirtualDatabase")); -var mockDatabase_1 = __importDefault(require("../__fixtures__/mockDatabase")); -var schema_1 = __importDefault(require("../__fixtures__/schema")); -var mwater_expressions_1 = require("mwater-expressions"); -var _ = __importStar(require("lodash")); -var schema = schema_1.default(); -var db; -var vdb; -var t2Where = { +const VirtualDatabase_1 = __importDefault(require("./VirtualDatabase")); +const mockDatabase_1 = __importDefault(require("../__fixtures__/mockDatabase")); +const schema_1 = __importDefault(require("../__fixtures__/schema")); +const mwater_expressions_1 = require("mwater-expressions"); +const _ = __importStar(require("lodash")); +const schema = schema_1.default(); +let db; +let vdb; +const t2Where = { type: "op", op: "=", table: "t2", @@ -75,446 +48,292 @@ var t2Where = { { type: "literal", valueType: "number", value: 5 } ] }; -beforeEach(function () { +beforeEach(() => { db = mockDatabase_1.default(); vdb = new VirtualDatabase_1.default(db, schema, "en"); }); /** Simulates a change to the virtual database to prevent passthrough */ -var preventPassthrough = function () { - var tx = vdb.transaction(); +const preventPassthrough = () => { + const tx = vdb.transaction(); tx.removeRow("t1", "NONSUCH"); tx.removeRow("t2", "NONSUCH"); tx.commit(); }; -test("shouldIncludeColumn includes regular columns and joins without inverse", function () { +test("shouldIncludeColumn includes regular columns and joins without inverse", () => { expect(vdb.shouldIncludeColumn({ id: "text", type: "text", name: { _base: "en" } })).toBe(true); expect(vdb.shouldIncludeColumn({ id: "text", type: "text", name: { _base: "en" }, expr: { type: "literal", valueType: "text", value: "xyz" } })).toBe(false); expect(vdb.shouldIncludeColumn(schema.getColumn("t1", "1-2"))).toBe(false); expect(vdb.shouldIncludeColumn(schema.getColumn("t2", "id1"))).toBe(true); }); -test("trigger change if underlying database changed", function () { - var changed = false; - vdb.addChangeListener(function () { changed = true; }); +test("trigger change if underlying database changed", () => { + let changed = false; + vdb.addChangeListener(() => { changed = true; }); // Fire change db.addChangeListener.mock.calls[0][0](); expect(changed).toBe(true); }); -test("queries with where clause and included columns", function () { return __awaiter(void 0, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - db.query.mockResolvedValue([]); - preventPassthrough(); // Test how queries are transformed by preventing passthrough - return [4 /*yield*/, vdb.query({ - select: { - x: { type: "field", table: "t2", column: "text" } - }, - from: "t2", - where: t2Where, - orderBy: [{ expr: { type: "field", table: "t2", column: "text" }, dir: "desc" }], - limit: 10 - }, [], {})]; - case 1: - _a.sent(); - expect(db.query.mock.calls[0][0]).toEqual({ - select: { - id: { type: "id", table: "t2" }, - c_text: { type: "field", table: "t2", column: "text" }, - c_number: { type: "field", table: "t2", column: "number" }, - c_id1: { type: "field", table: "t2", column: "id1" } - }, - from: "t2", - where: t2Where - }); - return [2 /*return*/]; - } +test("queries with where clause and included columns", () => __awaiter(void 0, void 0, void 0, function* () { + db.query.mockResolvedValue([]); + preventPassthrough(); // Test how queries are transformed by preventing passthrough + yield vdb.query({ + select: { + x: { type: "field", table: "t2", column: "text" } + }, + from: "t2", + where: t2Where, + orderBy: [{ expr: { type: "field", table: "t2", column: "text" }, dir: "desc" }], + limit: 10 + }, [], {}); + expect(db.query.mock.calls[0][0]).toEqual({ + select: { + id: { type: "id", table: "t2" }, + c_text: { type: "field", table: "t2", column: "text" }, + c_number: { type: "field", table: "t2", column: "number" }, + c_id1: { type: "field", table: "t2", column: "id1" } + }, + from: "t2", + where: t2Where }); -}); }); -describe("select, order, limit", function () { - var performQuery = function (rawRowsByTable, queryOptions) { return __awaiter(void 0, void 0, void 0, function () { - return __generator(this, function (_a) { - // Set up mock database to return raw rows with c_ prefixed on column names - // This simulates a real database call - db.query = (function (qo) { return __awaiter(void 0, void 0, void 0, function () { - var rows, exprEval, filteredRows, _loop_1, _i, rows_1, row; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - rows = rawRowsByTable[qo.from]; - if (!qo.where) return [3 /*break*/, 5]; - exprEval = new mwater_expressions_1.PromiseExprEvaluator({ schema: schema }); - filteredRows = []; - _loop_1 = function (row) { - var evalRow; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - evalRow = { - getPrimaryKey: function () { return Promise.resolve(row.id); }, - getField: function (columnId) { return Promise.resolve(row[columnId]); }, - followJoin: function (columnId) { return Promise.reject(new Error("Not implemented")); } - }; - return [4 /*yield*/, exprEval.evaluate(qo.where, { row: evalRow })]; - case 1: - if (_a.sent()) { - filteredRows.push(row); - } - return [2 /*return*/]; - } - }); - }; - _i = 0, rows_1 = rows; - _a.label = 1; - case 1: - if (!(_i < rows_1.length)) return [3 /*break*/, 4]; - row = rows_1[_i]; - return [5 /*yield**/, _loop_1(row)]; - case 2: - _a.sent(); - _a.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: - rows = filteredRows; - _a.label = 5; - case 5: - // Prepend c_ to non-id columns - rows = rows.map(function (row) { return _.mapKeys(row, function (v, k) { return k === "id" ? "id" : "c_" + k; }); }); - return [2 /*return*/, rows]; - } - }); - }); }); - // Perform query - return [2 /*return*/, vdb.query(queryOptions, [], {})]; - }); - }); }; - test("simple query", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "field", table: "t1", column: "text" } }, - from: "t1" - }; - return [4 /*yield*/, performQuery({ t1: [{ id: 1, text: "abc" }] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: "abc" } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("aggr count expr", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { - x: { type: "field", table: "t1", column: "text" }, - y: { type: "op", table: "t1", op: "count", exprs: [] } - }, - from: "t1" - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1, text: "abc" }, - { id: 2, text: "abc" }, - { id: 3, text: "def" } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: "abc", y: 2 }, - { x: "def", y: 1 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("count empty", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { - x: { type: "op", table: "t1", op: "count", exprs: [] } - }, - from: "t1" - }; - return [4 /*yield*/, performQuery({ t1: [] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 0 }, - ]); - return [2 /*return*/]; - } - }); - }); }); - test("orderby query with limit", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "field", table: "t1", column: "text" } }, - from: "t1", - orderBy: [{ expr: { type: "field", table: "t1", column: "number" }, dir: "desc" }], - limit: 2 - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1, text: "a", number: 1 }, - { id: 2, text: "b", number: 2 }, - { id: 3, text: "c", number: 3 } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: "c" }, - { x: "b" } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("orderby query with capitalization", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "id", table: "t1" } }, - from: "t1", - orderBy: [ - { expr: { type: "field", table: "t1", column: "text" }, dir: "asc" }, - { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } - ], - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1, text: "a", number: 1 }, - { id: 2, text: "a", number: 2 }, - { id: 3, text: "b", number: 3 }, - { id: 4, text: "A", number: 4 } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 2 }, - { x: 1 }, - { x: 4 }, - { x: 3 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("orderby query with nulls", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "id", table: "t1" } }, - from: "t1", - orderBy: [ - { expr: { type: "field", table: "t1", column: "text" }, dir: "asc" }, - { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } - ], - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1, text: "a", number: 1 }, - { id: 2, text: null, number: 2 }, - { id: 3, text: "b", number: 3 }, - { id: 4, text: "z", number: 4 } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 1 }, - { x: 3 }, - { x: 4 }, - { x: 2 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("orderby query with numbers", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "id", table: "t1" } }, - from: "t1", - orderBy: [ - { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } - ], - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1, number: 1 }, - { id: 2, number: 2 }, - { id: 3, number: 3 }, - { id: 4, number: 11 } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 4 }, - { x: 3 }, - { x: 2 }, - { x: 1 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("id join", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "field", table: "t2", column: "id1" } }, - from: "t2" - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: "a", text: "a", number: 1 } - ], t2: [ - { id: 1, text: "a", number: 1, "id1": "a" } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: "a" } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("n-1 scalar", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "scalar", joins: ["id1"], table: "t2", expr: { type: "field", table: "t1", column: "text" } } }, - from: "t2" - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1, text: "abc" } - ], t2: [ - { id: 101, "id1": 1 } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: "abc" } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("1-n scalar", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "scalar", joins: ["1-2"], table: "t1", expr: { - type: "op", op: "sum", table: "t1", exprs: [{ type: "field", table: "t2", column: "number" }] - } } }, - from: "t1" - }; - return [4 /*yield*/, performQuery({ t1: [ - { id: 1 }, - { id: 2 } - ], t2: [ - { id: 101, "id1": 1, number: 1 }, - { id: 102, "id1": 1, number: 2 }, - { id: 103, "id1": 2, number: 4 } - ] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 3 }, - { x: 4 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("caches backend queries", function () { return __awaiter(void 0, void 0, void 0, function () { - var qopts; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - qopts = { - select: { x: { type: "field", table: "t1", column: "text" } }, - from: "t1" - }; - return [4 /*yield*/, performQuery({ t1: [{ id: 1, text: "abc" }] }, qopts) - // Should not crash as uses cached query - ]; - case 1: - _a.sent(); - // Should not crash as uses cached query - return [4 /*yield*/, performQuery(null, qopts)]; - case 2: - // Should not crash as uses cached query - _a.sent(); - return [2 /*return*/]; - } - }); - }); }); - test("does not query rows that are not yet added", function () { return __awaiter(void 0, void 0, void 0, function () { - var tx, pk, qopts; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - tx = vdb.transaction(); - return [4 /*yield*/, tx.addRow("t1", {})]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, tx.commit()]; - case 2: - _a.sent(); - qopts = { - select: { x: { type: "field", table: "t1", column: "text" } }, - from: "t1", - where: { type: "op", table: "t1", op: "=", exprs: [ - { type: "id", table: "t1" }, - { type: "literal", valueType: "id", value: pk } - ] } +})); +describe("select, order, limit", () => { + const performQuery = (rawRowsByTable, queryOptions) => __awaiter(void 0, void 0, void 0, function* () { + // Set up mock database to return raw rows with c_ prefixed on column names + // This simulates a real database call + db.query = ((qo) => __awaiter(void 0, void 0, void 0, function* () { + // Get rows + let rows; + rows = rawRowsByTable[qo.from]; + // Filter rows by where + if (qo.where) { + const exprEval = new mwater_expressions_1.PromiseExprEvaluator({ schema }); + const filteredRows = []; + for (const row of rows) { + const evalRow = { + getPrimaryKey: () => Promise.resolve(row.id), + getField: (columnId) => Promise.resolve(row[columnId]), + followJoin: (columnId) => Promise.reject(new Error("Not implemented")) }; - // Should not crash as doesn't pass along - return [4 /*yield*/, performQuery(null, qopts)]; - case 3: - // Should not crash as doesn't pass along - _a.sent(); - return [2 /*return*/]; + if (yield exprEval.evaluate(qo.where, { row: evalRow })) { + filteredRows.push(row); + } + } + rows = filteredRows; } - }); - }); }); - describe("transactions", function () { - var numberField = { type: "field", table: "t1", column: "number" }; - var qopts = { + // Prepend c_ to non-id columns + rows = rows.map((row) => _.mapKeys(row, (v, k) => k === "id" ? "id" : "c_" + k)); + return rows; + })); + // Perform query + return vdb.query(queryOptions, [], {}); + }); + test("simple query", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "field", table: "t1", column: "text" } }, + from: "t1" + }; + const rows = yield performQuery({ t1: [{ id: 1, text: "abc" }] }, qopts); + expect(rows).toEqual([ + { x: "abc" } + ]); + })); + test("aggr count expr", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { + x: { type: "field", table: "t1", column: "text" }, + y: { type: "op", table: "t1", op: "count", exprs: [] } + }, + from: "t1" + }; + const rows = yield performQuery({ t1: [ + { id: 1, text: "abc" }, + { id: 2, text: "abc" }, + { id: 3, text: "def" } + ] }, qopts); + expect(rows).toEqual([ + { x: "abc", y: 2 }, + { x: "def", y: 1 } + ]); + })); + test("count empty", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { + x: { type: "op", table: "t1", op: "count", exprs: [] } + }, + from: "t1" + }; + const rows = yield performQuery({ t1: [] }, qopts); + expect(rows).toEqual([ + { x: 0 }, + ]); + })); + test("orderby query with limit", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "field", table: "t1", column: "text" } }, + from: "t1", + orderBy: [{ expr: { type: "field", table: "t1", column: "number" }, dir: "desc" }], + limit: 2 + }; + const rows = yield performQuery({ t1: [ + { id: 1, text: "a", number: 1 }, + { id: 2, text: "b", number: 2 }, + { id: 3, text: "c", number: 3 } + ] }, qopts); + expect(rows).toEqual([ + { x: "c" }, + { x: "b" } + ]); + })); + test("orderby query with capitalization", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "id", table: "t1" } }, + from: "t1", + orderBy: [ + { expr: { type: "field", table: "t1", column: "text" }, dir: "asc" }, + { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } + ], + }; + const rows = yield performQuery({ t1: [ + { id: 1, text: "a", number: 1 }, + { id: 2, text: "a", number: 2 }, + { id: 3, text: "b", number: 3 }, + { id: 4, text: "A", number: 4 } + ] }, qopts); + expect(rows).toEqual([ + { x: 2 }, + { x: 1 }, + { x: 4 }, + { x: 3 } + ]); + })); + test("orderby query with nulls", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "id", table: "t1" } }, + from: "t1", + orderBy: [ + { expr: { type: "field", table: "t1", column: "text" }, dir: "asc" }, + { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } + ], + }; + const rows = yield performQuery({ t1: [ + { id: 1, text: "a", number: 1 }, + { id: 2, text: null, number: 2 }, + { id: 3, text: "b", number: 3 }, + { id: 4, text: "z", number: 4 } + ] }, qopts); + expect(rows).toEqual([ + { x: 1 }, + { x: 3 }, + { x: 4 }, + { x: 2 } + ]); + })); + test("orderby query with numbers", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "id", table: "t1" } }, + from: "t1", + orderBy: [ + { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } + ], + }; + const rows = yield performQuery({ t1: [ + { id: 1, number: 1 }, + { id: 2, number: 2 }, + { id: 3, number: 3 }, + { id: 4, number: 11 } + ] }, qopts); + expect(rows).toEqual([ + { x: 4 }, + { x: 3 }, + { x: 2 }, + { x: 1 } + ]); + })); + test("id join", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "field", table: "t2", column: "id1" } }, + from: "t2" + }; + const rows = yield performQuery({ t1: [ + { id: "a", text: "a", number: 1 } + ], t2: [ + { id: 1, text: "a", number: 1, "id1": "a" } + ] }, qopts); + expect(rows).toEqual([ + { x: "a" } + ]); + })); + test("n-1 scalar", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "scalar", joins: ["id1"], table: "t2", expr: { type: "field", table: "t1", column: "text" } } }, + from: "t2" + }; + const rows = yield performQuery({ t1: [ + { id: 1, text: "abc" } + ], t2: [ + { id: 101, "id1": 1 } + ] }, qopts); + expect(rows).toEqual([ + { x: "abc" } + ]); + })); + test("1-n scalar", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "scalar", joins: ["1-2"], table: "t1", expr: { + type: "op", op: "sum", table: "t1", exprs: [{ type: "field", table: "t2", column: "number" }] + } } }, + from: "t1" + }; + const rows = yield performQuery({ t1: [ + { id: 1 }, + { id: 2 } + ], t2: [ + { id: 101, "id1": 1, number: 1 }, + { id: 102, "id1": 1, number: 2 }, + { id: 103, "id1": 2, number: 4 } + ] }, qopts); + expect(rows).toEqual([ + { x: 3 }, + { x: 4 } + ]); + })); + test("caches backend queries", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + const qopts = { + select: { x: { type: "field", table: "t1", column: "text" } }, + from: "t1" + }; + yield performQuery({ t1: [{ id: 1, text: "abc" }] }, qopts); + // Should not crash as uses cached query + yield performQuery(null, qopts); + })); + test("does not query rows that are not yet added", () => __awaiter(void 0, void 0, void 0, function* () { + const tx = vdb.transaction(); + const pk = yield tx.addRow("t1", {}); + yield tx.commit(); + const qopts = { + select: { x: { type: "field", table: "t1", column: "text" } }, + from: "t1", + where: { type: "op", table: "t1", op: "=", exprs: [ + { type: "id", table: "t1" }, + { type: "literal", valueType: "id", value: pk } + ] } + }; + // Should not crash as doesn't pass along + yield performQuery(null, qopts); + })); + describe("transactions", () => { + const numberField = { type: "field", table: "t1", column: "number" }; + const qopts = { select: { x: numberField }, from: "t1", where: { type: "op", op: ">", table: "t1", exprs: [ @@ -523,343 +342,175 @@ describe("select, order, limit", function () { ] }, orderBy: [{ expr: numberField, dir: "asc" }] }; - test("waits until transaction committed", function () { return __awaiter(void 0, void 0, void 0, function () { - var rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - preventPassthrough(); // Test how queries are transformed by preventing passthrough - vdb.transaction().addRow("t1", { number: 6 }); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 5 }] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 5 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("insert relevant row", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 6 })]; - case 1: - _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 2: - _a.sent(); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 5 }] }, qopts)]; - case 3: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 5 }, - { x: 6 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("insert irrelevant rows", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 1 })]; - case 1: - _a.sent(); - return [4 /*yield*/, txn.addRow("t2", { number: 6 })]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 3: - _a.sent(); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 5 }] }, qopts)]; - case 4: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 5 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("update relevant row", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - txn.updateRow("t1", 1, { number: 7 }); - txn.commit(); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 5 }, { id: 2, number: 6 }] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 6 }, - { x: 7 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("update relevant row to become irrelevant", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - txn.updateRow("t1", 1, { number: 2 }); - txn.commit(); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 5 }, { id: 2, number: 6 }] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 6 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("update irrelevant row to become relevant", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - txn.updateRow("t1", 1, { number: 7 }); - txn.commit(); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 2 }, { id: 2, number: 6 }] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 6 }, - { x: 7 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("remove relevant row", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - txn.removeRow("t1", 1); - txn.commit(); - return [4 /*yield*/, performQuery({ t1: [{ id: 1, number: 5 }, { id: 2, number: 6 }] }, qopts)]; - case 1: - rows = _a.sent(); - expect(rows).toEqual([ - { x: 6 } - ]); - return [2 /*return*/]; - } - }); - }); }); - test("notifies change listener", function () { return __awaiter(void 0, void 0, void 0, function () { - var changeListener, txn; - return __generator(this, function (_a) { - changeListener = jest.fn(); - vdb.addChangeListener(changeListener); - txn = vdb.transaction(); - txn.removeRow("t1", 1); - expect(changeListener.mock.calls.length).toBe(0); - txn.commit(); - expect(changeListener.mock.calls.length).toBe(1); - return [2 /*return*/]; - }); - }); }); - test("commits changes", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, pk, mockTransaction; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 1 })]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.removeRow("t1", 1)]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.commit() - // Mock underlying transaction - ]; - case 3: - _a.sent(); - mockTransaction = { - addRow: jest.fn(), - updateRow: jest.fn(), - removeRow: jest.fn(), - commit: jest.fn() - }; - db.transaction.mockReturnValue(mockTransaction); - // Commit to underlying database - return [4 /*yield*/, vdb.commit()]; - case 4: - // Commit to underlying database - _a.sent(); - expect(mockTransaction.addRow.mock.calls[0]).toEqual(["t1", { number: 1 }]); - expect(mockTransaction.removeRow.mock.calls[0]).toEqual(["t1", 1]); - expect(function () { return vdb.transaction(); }).toThrow(); - return [2 /*return*/]; - } - }); - }); }); - test("shortcuts updating inserted row", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, pk; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 1 })]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.updateRow("t1", pk, { number: 2 })]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 3: - _a.sent(); - expect(vdb.mutations).toEqual([{ - type: "add", - table: "t1", - primaryKey: pk, - values: { number: 2 } - }]); - return [2 /*return*/]; - } - }); - }); }); - test("shortcuts updating row", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.updateRow("t1", 1, { number: 2 })]; - case 1: - _a.sent(); - return [4 /*yield*/, txn.updateRow("t1", 1, { number: 3 })]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 3: - _a.sent(); - expect(vdb.mutations).toEqual([{ - type: "update", - table: "t1", - primaryKey: 1, - updates: { number: 3 } - }]); - return [2 /*return*/]; - } - }); - }); }); - test("shortcuts removing inserted row", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, pk; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 1 })]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.removeRow("t1", pk)]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 3: - _a.sent(); - expect(vdb.mutations).toEqual([]); - return [2 /*return*/]; - } - }); - }); }); - test("substitutes temporary primary keys", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, pk, pk2, mockTransaction; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 1 })]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.updateRow("t1", pk, { number: 2 })]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.addRow("t2", { "2-1": pk })]; - case 3: - pk2 = _a.sent(); - return [4 /*yield*/, txn.commit() - // Mock underlying transaction - ]; - case 4: - _a.sent(); - mockTransaction = { - addRow: jest.fn(), - updateRow: jest.fn(), - removeRow: jest.fn(), - commit: jest.fn() - }; - db.transaction.mockReturnValue(mockTransaction); - // Mock return pks - mockTransaction.addRow.mockResolvedValueOnce("PKA"); - mockTransaction.addRow.mockResolvedValueOnce("PKB"); - // Commit to underlying database - return [4 /*yield*/, vdb.commit()]; - case 5: - // Commit to underlying database - _a.sent(); - expect(mockTransaction.addRow.mock.calls[0]).toEqual(["t1", { number: 2 }]); - expect(mockTransaction.addRow.mock.calls[1]).toEqual(["t2", { "2-1": "PKA" }]); - return [2 /*return*/]; - } - }); - }); }); - test("removes virtual rows locally", function () { return __awaiter(void 0, void 0, void 0, function () { - var txn, pk, mockTransaction; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - txn = vdb.transaction(); - return [4 /*yield*/, txn.addRow("t1", { number: 1 })]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.updateRow("t1", pk, { number: 2 })]; - case 2: - _a.sent(); - return [4 /*yield*/, txn.removeRow("t2", pk)]; - case 3: - _a.sent(); - return [4 /*yield*/, txn.commit() - // Mock underlying transaction - ]; - case 4: - _a.sent(); - mockTransaction = { - addRow: jest.fn(), - updateRow: jest.fn(), - removeRow: jest.fn(), - commit: jest.fn() - }; - db.transaction.mockReturnValue(mockTransaction); - // Commit to underlying database - return [4 /*yield*/, vdb.commit()]; - case 5: - // Commit to underlying database - _a.sent(); - expect(mockTransaction.addRow.mock.calls.length).toBe(0); - expect(mockTransaction.updateRow.mock.calls.length).toBe(0); - expect(mockTransaction.removeRow.mock.calls.length).toBe(0); - return [2 /*return*/]; - } - }); - }); }); + test("waits until transaction committed", () => __awaiter(void 0, void 0, void 0, function* () { + preventPassthrough(); // Test how queries are transformed by preventing passthrough + vdb.transaction().addRow("t1", { number: 6 }); + const rows = yield performQuery({ t1: [{ id: 1, number: 5 }] }, qopts); + expect(rows).toEqual([ + { x: 5 } + ]); + })); + test("insert relevant row", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + yield txn.addRow("t1", { number: 6 }); + yield txn.commit(); + const rows = yield performQuery({ t1: [{ id: 1, number: 5 }] }, qopts); + expect(rows).toEqual([ + { x: 5 }, + { x: 6 } + ]); + })); + test("insert irrelevant rows", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + yield txn.addRow("t1", { number: 1 }); + yield txn.addRow("t2", { number: 6 }); + yield txn.commit(); + const rows = yield performQuery({ t1: [{ id: 1, number: 5 }] }, qopts); + expect(rows).toEqual([ + { x: 5 } + ]); + })); + test("update relevant row", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + txn.updateRow("t1", 1, { number: 7 }); + txn.commit(); + const rows = yield performQuery({ t1: [{ id: 1, number: 5 }, { id: 2, number: 6 }] }, qopts); + expect(rows).toEqual([ + { x: 6 }, + { x: 7 } + ]); + })); + test("update relevant row to become irrelevant", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + txn.updateRow("t1", 1, { number: 2 }); + txn.commit(); + const rows = yield performQuery({ t1: [{ id: 1, number: 5 }, { id: 2, number: 6 }] }, qopts); + expect(rows).toEqual([ + { x: 6 } + ]); + })); + test("update irrelevant row to become relevant", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + txn.updateRow("t1", 1, { number: 7 }); + txn.commit(); + const rows = yield performQuery({ t1: [{ id: 1, number: 2 }, { id: 2, number: 6 }] }, qopts); + expect(rows).toEqual([ + { x: 6 }, + { x: 7 } + ]); + })); + test("remove relevant row", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + txn.removeRow("t1", 1); + txn.commit(); + const rows = yield performQuery({ t1: [{ id: 1, number: 5 }, { id: 2, number: 6 }] }, qopts); + expect(rows).toEqual([ + { x: 6 } + ]); + })); + test("notifies change listener", () => __awaiter(void 0, void 0, void 0, function* () { + const changeListener = jest.fn(); + vdb.addChangeListener(changeListener); + const txn = vdb.transaction(); + txn.removeRow("t1", 1); + expect(changeListener.mock.calls.length).toBe(0); + txn.commit(); + expect(changeListener.mock.calls.length).toBe(1); + })); + test("commits changes", () => __awaiter(void 0, void 0, void 0, function* () { + // Create changes + const txn = vdb.transaction(); + const pk = yield txn.addRow("t1", { number: 1 }); + yield txn.removeRow("t1", 1); + yield txn.commit(); + // Mock underlying transaction + const mockTransaction = { + addRow: jest.fn(), + updateRow: jest.fn(), + removeRow: jest.fn(), + commit: jest.fn() + }; + db.transaction.mockReturnValue(mockTransaction); + // Commit to underlying database + yield vdb.commit(); + expect(mockTransaction.addRow.mock.calls[0]).toEqual(["t1", { number: 1 }]); + expect(mockTransaction.removeRow.mock.calls[0]).toEqual(["t1", 1]); + expect(() => vdb.transaction()).toThrow(); + })); + test("shortcuts updating inserted row", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + const pk = yield txn.addRow("t1", { number: 1 }); + yield txn.updateRow("t1", pk, { number: 2 }); + yield txn.commit(); + expect(vdb.mutations).toEqual([{ + type: "add", + table: "t1", + primaryKey: pk, + values: { number: 2 } + }]); + })); + test("shortcuts updating row", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + yield txn.updateRow("t1", 1, { number: 2 }); + yield txn.updateRow("t1", 1, { number: 3 }); + yield txn.commit(); + expect(vdb.mutations).toEqual([{ + type: "update", + table: "t1", + primaryKey: 1, + updates: { number: 3 } + }]); + })); + test("shortcuts removing inserted row", () => __awaiter(void 0, void 0, void 0, function* () { + const txn = vdb.transaction(); + const pk = yield txn.addRow("t1", { number: 1 }); + yield txn.removeRow("t1", pk); + yield txn.commit(); + expect(vdb.mutations).toEqual([]); + })); + test("substitutes temporary primary keys", () => __awaiter(void 0, void 0, void 0, function* () { + // Create changes + const txn = vdb.transaction(); + const pk = yield txn.addRow("t1", { number: 1 }); + yield txn.updateRow("t1", pk, { number: 2 }); + const pk2 = yield txn.addRow("t2", { "2-1": pk }); + yield txn.commit(); + // Mock underlying transaction + const mockTransaction = { + addRow: jest.fn(), + updateRow: jest.fn(), + removeRow: jest.fn(), + commit: jest.fn() + }; + db.transaction.mockReturnValue(mockTransaction); + // Mock return pks + mockTransaction.addRow.mockResolvedValueOnce("PKA"); + mockTransaction.addRow.mockResolvedValueOnce("PKB"); + // Commit to underlying database + yield vdb.commit(); + expect(mockTransaction.addRow.mock.calls[0]).toEqual(["t1", { number: 2 }]); + expect(mockTransaction.addRow.mock.calls[1]).toEqual(["t2", { "2-1": "PKA" }]); + })); + test("removes virtual rows locally", () => __awaiter(void 0, void 0, void 0, function* () { + // Create changes + const txn = vdb.transaction(); + const pk = yield txn.addRow("t1", { number: 1 }); + yield txn.updateRow("t1", pk, { number: 2 }); + yield txn.removeRow("t2", pk); + yield txn.commit(); + // Mock underlying transaction + const mockTransaction = { + addRow: jest.fn(), + updateRow: jest.fn(), + removeRow: jest.fn(), + commit: jest.fn() + }; + db.transaction.mockReturnValue(mockTransaction); + // Commit to underlying database + yield vdb.commit(); + expect(mockTransaction.addRow.mock.calls.length).toBe(0); + expect(mockTransaction.updateRow.mock.calls.length).toBe(0); + expect(mockTransaction.removeRow.mock.calls.length).toBe(0); + })); }); }); diff --git a/lib/demo.js b/lib/demo.js index 9706f68f..d687f9d6 100644 --- a/lib/demo.js +++ b/lib/demo.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -46,133 +33,90 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var BlockFactory_1 = __importDefault(require("./widgets/BlockFactory")); -var mwater_expressions_1 = require("mwater-expressions"); -var widgetLibrary_1 = require("./designer/widgetLibrary"); -var MWaterDataSource_1 = __importDefault(require("mwater-expressions/lib/MWaterDataSource")); -var ActionLibrary_1 = require("./widgets/ActionLibrary"); -var lodash_1 = __importDefault(require("lodash")); -var ez_localize_1 = require("ez-localize"); +const React = __importStar(require("react")); +const BlockFactory_1 = __importDefault(require("./widgets/BlockFactory")); +const mwater_expressions_1 = require("mwater-expressions"); +const widgetLibrary_1 = require("./designer/widgetLibrary"); +const MWaterDataSource_1 = __importDefault(require("mwater-expressions/lib/MWaterDataSource")); +const ActionLibrary_1 = require("./widgets/ActionLibrary"); +const lodash_1 = __importDefault(require("lodash")); +const ez_localize_1 = require("ez-localize"); // import 'bootstrap/dist/css/bootstrap.css' // import 'font-awesome/css/font-awesome.css' require("./Demo.css"); -var ReactDOM = __importStar(require("react-dom")); -var blockPaletteEntries_1 = require("./designer/blockPaletteEntries"); -var react_dnd_1 = require("react-dnd"); -var react_dnd_html5_backend_1 = __importDefault(require("react-dnd-html5-backend")); -var DataSourceDatabase_1 = require("./database/DataSourceDatabase"); -var basicBlockFactory = new BlockFactory_1.default(); -var defaultWidgetLibrary = { +const ReactDOM = __importStar(require("react-dom")); +const blockPaletteEntries_1 = require("./designer/blockPaletteEntries"); +const react_dnd_1 = require("react-dnd"); +const react_dnd_html5_backend_1 = __importDefault(require("react-dnd-html5-backend")); +const DataSourceDatabase_1 = require("./database/DataSourceDatabase"); +const basicBlockFactory = new BlockFactory_1.default(); +const defaultWidgetLibrary = { widgets: {} }; -var initialWidgetLibrary = JSON.parse(window.localStorage.getItem("widgetLibrary") || "null") || defaultWidgetLibrary; -var urlParams = new URLSearchParams(window.location.search); -var client = urlParams.get('client'); -var extraTables = lodash_1.default.compact((urlParams.get('extraTables') || "").split(",")); -var dataSource = new MWaterDataSource_1.default("https://api.mwater.co/v3/", client, { localCaching: false, serverCaching: false }); -var actionLibrary = new ActionLibrary_1.ActionLibrary(); -var MockTransaction = /** @class */ (function () { - function MockTransaction() { - } - MockTransaction.prototype.addRow = function (table, values) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - console.log("add(" + table + ", " + JSON.stringify(values) + ")"); - return [2 /*return*/, "1"]; - }); +const initialWidgetLibrary = JSON.parse(window.localStorage.getItem("widgetLibrary") || "null") || defaultWidgetLibrary; +const urlParams = new URLSearchParams(window.location.search); +const client = urlParams.get('client'); +const extraTables = lodash_1.default.compact((urlParams.get('extraTables') || "").split(",")); +const dataSource = new MWaterDataSource_1.default("https://api.mwater.co/v3/", client, { localCaching: false, serverCaching: false }); +const actionLibrary = new ActionLibrary_1.ActionLibrary(); +class MockTransaction { + addRow(table, values) { + return __awaiter(this, void 0, void 0, function* () { + console.log(`add(${table}, ${JSON.stringify(values)})`); + return "1"; }); - }; - MockTransaction.prototype.updateRow = function (table, primaryKey, updates) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - console.log("update(" + table + ", " + primaryKey + ", " + JSON.stringify(updates) + ")"); - return [2 /*return*/]; - }); + } + updateRow(table, primaryKey, updates) { + return __awaiter(this, void 0, void 0, function* () { + console.log(`update(${table}, ${primaryKey}, ${JSON.stringify(updates)})`); }); - }; - MockTransaction.prototype.removeRow = function (table, primaryKey) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - console.log("remove(" + table + ", " + primaryKey + ")"); - return [2 /*return*/]; - }); + } + removeRow(table, primaryKey) { + return __awaiter(this, void 0, void 0, function* () { + console.log(`remove(${table}, ${primaryKey})`); }); - }; - MockTransaction.prototype.commit = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - console.log("commit()"); - alert("Note: updated ignored"); - return [2 /*return*/, []]; - }); + } + commit() { + return __awaiter(this, void 0, void 0, function* () { + console.log("commit()"); + alert("Note: updated ignored"); + return []; }); - }; - return MockTransaction; -}()); -var Demo = /** @class */ (function (_super) { - __extends(Demo, _super); - function Demo(props) { - var _this = _super.call(this, props) || this; - _this.handleWidgetLibraryChange = function (widgetLibrary) { - _this.setState({ widgetLibrary: widgetLibrary }); + } +} +let Demo = class Demo extends React.Component { + constructor(props) { + super(props); + this.handleWidgetLibraryChange = (widgetLibrary) => { + this.setState({ widgetLibrary }); // console.log(JSON.stringify(widgetLibrary, null, 2)) window.localStorage.setItem("widgetLibrary", JSON.stringify(widgetLibrary)); }; - _this.handleOpenTabsChange = function (openTabs) { - _this.setState({ openTabs: openTabs }); + this.handleOpenTabsChange = (openTabs) => { + this.setState({ openTabs: openTabs }); window.localStorage.setItem("openTabs", JSON.stringify(openTabs)); }; - _this.state = { + this.state = { widgetLibrary: initialWidgetLibrary, openTabs: lodash_1.default.intersection(JSON.parse(window.localStorage.getItem("openTabs") || "null") || [], lodash_1.default.keys(initialWidgetLibrary.widgets)) }; - return _this; } - Demo.prototype.componentDidMount = function () { - var _this = this; - fetch("https://api.mwater.co/v3/schema?client=" + (client || "") + "&extraTables=" + extraTables.join(",")).then(function (req) { return req.json(); }).then(function (json) { - var schema = new mwater_expressions_1.Schema(json); - var database = new DataSourceDatabase_1.DataSourceDatabase(schema, dataSource, function () { return new MockTransaction(); }); - _this.setState({ schema: schema, database: database }); + componentDidMount() { + fetch("https://api.mwater.co/v3/schema?client=" + (client || "") + "&extraTables=" + extraTables.join(",")).then(req => req.json()).then(json => { + const schema = new mwater_expressions_1.Schema(json); + const database = new DataSourceDatabase_1.DataSourceDatabase(schema, dataSource, () => new MockTransaction()); + this.setState({ schema, database }); }); - }; - Demo.prototype.render = function () { + } + render() { if (!this.state.schema || !this.state.database) { return React.createElement("div", null, "Loading..."); } - var baseCtx = { + const baseCtx = { widgetLibrary: this.state.widgetLibrary, createBlock: basicBlockFactory.createBlock, actionLibrary: actionLibrary, @@ -191,10 +135,9 @@ var Demo = /** @class */ (function (_super) { }; return (React.createElement("div", { style: { padding: 5, height: "100vh" } }, React.createElement(widgetLibrary_1.WidgetLibraryDesigner, { baseCtx: baseCtx, dataSource: dataSource, openTabs: this.state.openTabs, onOpenTabsChange: this.handleOpenTabsChange, onWidgetLibraryChange: this.handleWidgetLibraryChange, blockPaletteEntries: blockPaletteEntries_1.defaultBlockPaletteEntries }))); - }; - Demo = __decorate([ - react_dnd_1.DragDropContext(react_dnd_html5_backend_1.default) - ], Demo); - return Demo; -}(React.Component)); + } +}; +Demo = __decorate([ + react_dnd_1.DragDropContext(react_dnd_html5_backend_1.default) +], Demo); ReactDOM.render(React.createElement(Demo, null), document.getElementById('main')); diff --git a/lib/designer/AddWizardPalette.js b/lib/designer/AddWizardPalette.js index da60ef63..e8e61c1d 100644 --- a/lib/designer/AddWizardPalette.js +++ b/lib/designer/AddWizardPalette.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -35,35 +22,30 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var react_dnd_1 = require("react-dnd"); -var uuid_1 = __importDefault(require("uuid")); -var blockSourceSpec = { - beginDrag: function () { +const React = __importStar(require("react")); +const react_dnd_1 = require("react-dnd"); +const uuid_1 = __importDefault(require("uuid")); +const blockSourceSpec = { + beginDrag() { return { blockDef: { id: uuid_1.default(), type: "addWizard" } }; }, - endDrag: function (props, monitor) { + endDrag(props, monitor) { if (monitor.didDrop()) { props.onSelect(monitor.getItem().blockDef.id); } } }; /** Button that can be dragged into the designer to create an addWizard block */ -var AddWizardPalette = /** @class */ (function (_super) { - __extends(AddWizardPalette, _super); - function AddWizardPalette() { - return _super !== null && _super.apply(this, arguments) || this; - } - AddWizardPalette.prototype.render = function () { +class AddWizardPalette extends React.Component { + render() { return (this.props.connectDragSource(React.createElement("button", { type: "button", className: "btn btn-default btn-sm active", style: { cursor: "move" } }, React.createElement("i", { className: "fa fa-arrows" }), " Add Block"))); - }; - return AddWizardPalette; -}(React.Component)); -var collect = function (connect) { + } +} +const collect = (connect) => { return { connectDragSource: connect.dragSource() }; }; exports.default = react_dnd_1.DragSource("ui-builder-block", blockSourceSpec, collect)(AddWizardPalette); diff --git a/lib/designer/BlockWrapper.js b/lib/designer/BlockWrapper.js index 058a70a2..2019d8f2 100644 --- a/lib/designer/BlockWrapper.js +++ b/lib/designer/BlockWrapper.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -32,53 +19,53 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var blocks_1 = require("../widgets/blocks"); -var react_dnd_1 = require("react-dnd"); +const React = __importStar(require("react")); +const blocks_1 = require("../widgets/blocks"); +const react_dnd_1 = require("react-dnd"); require("./BlockWrapper.css"); -var ReactDOM = __importStar(require("react-dom")); -var blockSourceSpec = { - beginDrag: function (props) { +const ReactDOM = __importStar(require("react-dom")); +const blockSourceSpec = { + beginDrag(props) { return { blockDef: props.blockDef }; }, - isDragging: function (props, monitor) { + isDragging(props, monitor) { return monitor.getItem().blockDef && (props.blockDef.id === monitor.getItem().blockDef.id); } }; -var blockTargetSpec = { +const blockTargetSpec = { // Called when an block hovers over this component - hover: function (props, monitor, component) { + hover(props, monitor, component) { // Hovering over self does nothing - var hoveringId = monitor.getItem().blockDef.id; - var myId = props.blockDef.id; + const hoveringId = monitor.getItem().blockDef.id; + const myId = props.blockDef.id; if (hoveringId === myId) { component.setState({ hoverSide: null }); return; } - var side = getDropSide(monitor, component); + const side = getDropSide(monitor, component); // Set the state component.setState({ hoverSide: side }); }, - canDrop: function (props, monitor) { + canDrop(props, monitor) { if (!monitor.getItem().blockDef) { return false; } - var hoveringId = monitor.getItem().blockDef.id; - var myId = props.blockDef.id; + const hoveringId = monitor.getItem().blockDef.id; + const myId = props.blockDef.id; return (hoveringId !== myId); }, - drop: function (props, monitor, component) { + drop(props, monitor, component) { if (monitor.didDrop()) { return; } // Defer to next cycle to prevent drop error - var dropSide = component.state.hoverSide; - var sourceBlockDef = monitor.getItem().blockDef; - var targetBlockDef = props.blockDef; - setTimeout(function () { - props.store.alterBlock(targetBlockDef.id, function (b) { return blocks_1.dropBlock(sourceBlockDef, b, dropSide); }, sourceBlockDef.id); + const dropSide = component.state.hoverSide; + const sourceBlockDef = monitor.getItem().blockDef; + const targetBlockDef = props.blockDef; + setTimeout(() => { + props.store.alterBlock(targetBlockDef.id, (b) => blocks_1.dropBlock(sourceBlockDef, b, dropSide), sourceBlockDef.id); }, 0); } }; @@ -86,16 +73,16 @@ var blockTargetSpec = { function getDropSide(monitor, component) { // Get underlying component // const blockComponent = component.getDecoratedComponentInstance() - var blockComponent = component; + const blockComponent = component; // Get bounds of component - var hoverBoundingRect = ReactDOM.findDOMNode(blockComponent).getBoundingClientRect(); - var clientOffset = monitor.getClientOffset(); + const hoverBoundingRect = ReactDOM.findDOMNode(blockComponent).getBoundingClientRect(); + const clientOffset = monitor.getClientOffset(); // Get position within hovered item - var hoverClientX = clientOffset.x - hoverBoundingRect.left; - var hoverClientY = clientOffset.y - hoverBoundingRect.top; + const hoverClientX = clientOffset.x - hoverBoundingRect.left; + const hoverClientY = clientOffset.y - hoverBoundingRect.top; // Determine if over is more left, right, top or bottom - var fractionX = hoverClientX / (hoverBoundingRect.right - hoverBoundingRect.left); - var fractionY = hoverClientY / (hoverBoundingRect.bottom - hoverBoundingRect.top); + const fractionX = hoverClientX / (hoverBoundingRect.right - hoverBoundingRect.left); + const fractionY = hoverClientY / (hoverBoundingRect.bottom - hoverBoundingRect.top); if (fractionX > fractionY) { // top or right if ((1 - fractionX) > fractionY) { // top or left return blocks_1.DropSide.top; @@ -114,19 +101,17 @@ function getDropSide(monitor, component) { } } /** Wraps a block in a draggable control with an x to remove */ -var BlockWrapper = /** @class */ (function (_super) { - __extends(BlockWrapper, _super); - function BlockWrapper(props) { - var _this = _super.call(this, props) || this; - _this.handleClick = function (ev) { +class BlockWrapper extends React.Component { + constructor(props) { + super(props); + this.handleClick = (ev) => { ev.stopPropagation(); - _this.props.onSelect(); + this.props.onSelect(); }; - _this.state = { hoverSide: null }; - return _this; + this.state = { hoverSide: null }; } - BlockWrapper.prototype.renderHover = function () { - var lineStyle = {}; + renderHover() { + const lineStyle = {}; lineStyle.position = "absolute"; if (this.props.isOver) { switch (this.state.hoverSide) { @@ -160,10 +145,10 @@ var BlockWrapper = /** @class */ (function (_super) { else { return null; } - }; - BlockWrapper.prototype.render = function () { - var selected = this.props.selectedBlockId === this.props.blockDef.id; - var className = "block-wrapper"; + } + render() { + const selected = this.props.selectedBlockId === this.props.blockDef.id; + let className = "block-wrapper"; if (this.props.validationError) { className += " validation-error"; } @@ -176,15 +161,14 @@ var BlockWrapper = /** @class */ (function (_super) { React.createElement("i", { className: "fa fa-remove" })) : null, this.renderHover(), this.props.children)))); - }; - return BlockWrapper; -}(React.Component)); -var dropTarget = react_dnd_1.DropTarget("ui-builder-block", blockTargetSpec, function (connect, monitor) { return ({ + } +} +const dropTarget = react_dnd_1.DropTarget("ui-builder-block", blockTargetSpec, (connect, monitor) => ({ connectDropTarget: connect.dropTarget(), isOver: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop() -}); })(BlockWrapper); -exports.default = react_dnd_1.DragSource("ui-builder-block", blockSourceSpec, function (connect, monitor) { return ({ +}))(BlockWrapper); +exports.default = react_dnd_1.DragSource("ui-builder-block", blockSourceSpec, (connect, monitor) => ({ connectDragSource: connect.dragSource(), isDragging: monitor.isDragging() -}); })(dropTarget); +}))(dropTarget); diff --git a/lib/designer/ClipboardPalette.js b/lib/designer/ClipboardPalette.js index 44006e4b..ac3d7334 100644 --- a/lib/designer/ClipboardPalette.js +++ b/lib/designer/ClipboardPalette.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -32,33 +19,33 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var react_dnd_1 = require("react-dnd"); -var blocks_1 = require("../widgets/blocks"); +const React = __importStar(require("react")); +const react_dnd_1 = require("react-dnd"); +const blocks_1 = require("../widgets/blocks"); var clipboardContents = null; -var blockSourceSpec = { - canDrag: function (props) { +const blockSourceSpec = { + canDrag: (props) => { return clipboardContents != null; }, - beginDrag: function (props) { + beginDrag: (props) => { return { blockDef: blocks_1.duplicateBlockDef(clipboardContents, props.createBlock) }; }, - endDrag: function (props, monitor) { + endDrag: (props, monitor) => { if (monitor.didDrop()) { props.onSelect(monitor.getItem().blockDef.id); } } }; -var blockTargetSpec = { - canDrop: function (props, monitor) { +const blockTargetSpec = { + canDrop(props, monitor) { if (!monitor.getItem().blockDef) { return false; } return true; }, - drop: function (props, monitor, component) { + drop(props, monitor, component) { if (monitor.didDrop()) { return; } @@ -66,25 +53,20 @@ var blockTargetSpec = { } }; /** Button that can be dragged or dropped to access the clipboard */ -var ClipboardPalette = /** @class */ (function (_super) { - __extends(ClipboardPalette, _super); - function ClipboardPalette() { - return _super !== null && _super.apply(this, arguments) || this; - } - ClipboardPalette.prototype.render = function () { - var className = this.props.isOver ? "btn btn-primary btn-sm active" : "btn btn-default btn-sm active"; +class ClipboardPalette extends React.Component { + render() { + const className = this.props.isOver ? "btn btn-primary btn-sm active" : "btn btn-default btn-sm active"; return (this.props.connectDropTarget(this.props.connectDragSource(React.createElement("button", { type: "button", className: className, style: { cursor: "move" } }, React.createElement("i", { className: "fa fa-arrows" }), " Clipboard")))); - }; - return ClipboardPalette; -}(React.Component)); -var collect = function (connect) { + } +} +const collect = (connect) => { return { connectDragSource: connect.dragSource() }; }; -var dropTarget = react_dnd_1.DropTarget("ui-builder-block", blockTargetSpec, function (connect, monitor) { return ({ +const dropTarget = react_dnd_1.DropTarget("ui-builder-block", blockTargetSpec, (connect, monitor) => ({ connectDropTarget: connect.dropTarget(), isOver: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop() -}); })(ClipboardPalette); +}))(ClipboardPalette); exports.default = react_dnd_1.DragSource("ui-builder-block", blockSourceSpec, collect)(dropTarget); diff --git a/lib/designer/ErrorBoundary.js b/lib/designer/ErrorBoundary.js index 426c49f4..7e9207a8 100644 --- a/lib/designer/ErrorBoundary.js +++ b/lib/designer/ErrorBoundary.js @@ -1,34 +1,19 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); +const react_1 = __importDefault(require("react")); /** Makes a react error boundary that shows the error rather than crashing the app */ -var ErrorBoundary = /** @class */ (function (_super) { - __extends(ErrorBoundary, _super); - function ErrorBoundary(props) { - var _this = _super.call(this, props) || this; - _this.state = {}; - return _this; +class ErrorBoundary extends react_1.default.Component { + constructor(props) { + super(props); + this.state = {}; } - ErrorBoundary.prototype.componentDidCatch = function (error, errorInfo) { - this.setState({ error: error, errorInfo: errorInfo }); - }; - ErrorBoundary.prototype.render = function () { + componentDidCatch(error, errorInfo) { + this.setState({ error, errorInfo }); + } + render() { if (this.state.error) { return (react_1.default.createElement("div", { className: "alert alert-danger" }, "Error: ", @@ -37,7 +22,6 @@ var ErrorBoundary = /** @class */ (function (_super) { react_1.default.createElement("pre", null, this.state.errorInfo.componentStack))); } return this.props.children; - }; - return ErrorBoundary; -}(react_1.default.Component)); + } +} exports.default = ErrorBoundary; diff --git a/lib/designer/NewTab.js b/lib/designer/NewTab.js index 6bdc84bd..395f8c51 100644 --- a/lib/designer/NewTab.js +++ b/lib/designer/NewTab.js @@ -4,26 +4,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NewTab = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = require("react"); -var uuid = require("uuid"); -var SearchBlockInstance_1 = require("../widgets/blocks/search/SearchBlockInstance"); -var react_2 = __importDefault(require("react")); +const lodash_1 = __importDefault(require("lodash")); +const react_1 = require("react"); +const uuid = require("uuid"); +const SearchBlockInstance_1 = require("../widgets/blocks/search/SearchBlockInstance"); +const react_2 = __importDefault(require("react")); /** Tab which lists existing tabs and offers a button to create a new tab */ -exports.NewTab = function (props) { +exports.NewTab = (props) => { /** Search state */ - var _a = react_1.useState(""), search = _a[0], setSearch = _a[1]; + const [search, setSearch] = react_1.useState(""); // Which widgets have errors - var _b = react_1.useState([]), errors = _b[0], setErrors = _b[1]; + const [errors, setErrors] = react_1.useState([]); /** Collapsed groups (persisted to local storage) */ - var _c = react_1.useState(JSON.parse(window.localStorage.getItem("UIBuilder.collapsedWidgetGroups") || "[]")), collapsedGroups = _c[0], setCollapsedGroups = _c[1]; + const [collapsedGroups, setCollapsedGroups] = react_1.useState(JSON.parse(window.localStorage.getItem("UIBuilder.collapsedWidgetGroups") || "[]")); // Check each widget for errors - react_1.useEffect(function () { + react_1.useEffect(() => { // For each widget - var widgetErrors = []; - for (var _i = 0, _a = Object.values(props.widgetLibrary.widgets); _i < _a.length; _i++) { - var widgetDef = _a[_i]; - var error = props.validateWidget(widgetDef); + const widgetErrors = []; + for (const widgetDef of Object.values(props.widgetLibrary.widgets)) { + const error = props.validateWidget(widgetDef); if (error) { widgetErrors.push(widgetDef.id); } @@ -31,8 +30,8 @@ exports.NewTab = function (props) { setErrors(widgetErrors); }, []); // Focus on load - var searchControl = react_1.useRef(null); - react_1.useEffect(function () { + const searchControl = react_1.useRef(null); + react_1.useEffect(() => { if (searchControl.current) { searchControl.current.focus(); } @@ -60,18 +59,18 @@ exports.NewTab = function (props) { } function toggleGroup(group) { if (collapsedGroups.includes(group)) { - var newCollapsedGroups = collapsedGroups.filter(function (g) { return g != group; }); + const newCollapsedGroups = collapsedGroups.filter(g => g != group); setCollapsedGroups(newCollapsedGroups); window.localStorage.setItem("UIBuilder.collapsedWidgetGroups", JSON.stringify(newCollapsedGroups)); } else { - var newCollapsedGroups = collapsedGroups.concat([group]); + const newCollapsedGroups = collapsedGroups.concat([group]); setCollapsedGroups(newCollapsedGroups); window.localStorage.setItem("UIBuilder.collapsedWidgetGroups", JSON.stringify(newCollapsedGroups)); } } function renderWidgetGroupHeader(group) { - return react_2.default.createElement("h4", { style: { cursor: "pointer" }, onClick: function () { return toggleGroup(group); } }, + return react_2.default.createElement("h4", { style: { cursor: "pointer" }, onClick: () => toggleGroup(group) }, react_2.default.createElement("span", { style: { color: "#38D" } }, collapsedGroups.includes(group) ? react_2.default.createElement("i", { className: "fa fa-fw fa-caret-right" }) : react_2.default.createElement("i", { className: "fa fa-fw fa-caret-down" }), "\u00A0"), @@ -81,7 +80,7 @@ exports.NewTab = function (props) { return (react_2.default.createElement("div", null, hasGroups ? renderWidgetGroupHeader(group) : null, !collapsedGroups.includes(group) ? - react_2.default.createElement("ul", { className: "list-group" }, widgets.map(function (widget) { return (react_2.default.createElement("li", { className: "list-group-item", style: { cursor: "pointer" }, key: widget.id, onClick: props.onOpenWidget.bind(null, widget.id) }, + react_2.default.createElement("ul", { className: "list-group" }, widgets.map(widget => (react_2.default.createElement("li", { className: "list-group-item", style: { cursor: "pointer" }, key: widget.id, onClick: props.onOpenWidget.bind(null, widget.id) }, react_2.default.createElement("span", { style: { float: "right" }, onClick: handleRemoveWidget.bind(null, widget.id) }, react_2.default.createElement("i", { className: "fa fa-fw fa-remove" })), react_2.default.createElement("span", { style: { float: "right" }, onClick: handleDuplicateWidget.bind(null, widget) }, @@ -93,13 +92,13 @@ exports.NewTab = function (props) { widget.name, widget.description ? react_2.default.createElement("span", { className: "text-muted" }, " - ", - widget.description) : null)); })) + widget.description) : null)))) : null)); } function renderExistingWidgets() { - var widgets = Object.values(props.widgetLibrary.widgets); + let widgets = Object.values(props.widgetLibrary.widgets); // Filter by search - widgets = widgets.filter(function (widget) { + widgets = widgets.filter(widget => { if (!search) { return true; } @@ -118,11 +117,11 @@ exports.NewTab = function (props) { return false; }); // Get groups and sort - var groups = lodash_1.default.uniq(widgets.map(function (w) { return w.group; })); + const groups = lodash_1.default.uniq(widgets.map(w => w.group)); groups.sort(); // Render each group - return groups.map(function (group) { - var groupWidgets = lodash_1.default.sortBy(widgets.filter(function (w) { return w.group == group; }), "name"); + return groups.map(group => { + const groupWidgets = lodash_1.default.sortBy(widgets.filter(w => w.group == group), "name"); return renderWidgetGroup(group, groupWidgets, !(groups.length == 1 && groups[0] == undefined)); }); } diff --git a/lib/designer/WidgetDesigner.js b/lib/designer/WidgetDesigner.js index 4a99e811..29ed539f 100644 --- a/lib/designer/WidgetDesigner.js +++ b/lib/designer/WidgetDesigner.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -46,154 +22,148 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var lodash_1 = __importDefault(require("lodash")); -var BlockWrapper_1 = __importDefault(require("./BlockWrapper")); -var React = __importStar(require("react")); -var blocks_1 = require("../widgets/blocks"); -var BlockPlaceholder_1 = __importDefault(require("../widgets/BlockPlaceholder")); +const lodash_1 = __importDefault(require("lodash")); +const BlockWrapper_1 = __importDefault(require("./BlockWrapper")); +const React = __importStar(require("react")); +const blocks_1 = require("../widgets/blocks"); +const BlockPlaceholder_1 = __importDefault(require("../widgets/BlockPlaceholder")); require("./WidgetDesigner.css"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var WidgetEditor_1 = require("./WidgetEditor"); -var PageStackDisplay_1 = require("../PageStackDisplay"); -var ErrorBoundary_1 = __importDefault(require("./ErrorBoundary")); -var VirtualDatabase_1 = __importDefault(require("../database/VirtualDatabase")); -var AddWizardPalette_1 = __importDefault(require("./AddWizardPalette")); -var ClipboardPalette_1 = __importDefault(require("./ClipboardPalette")); -var canonical_json_1 = __importDefault(require("canonical-json")); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const WidgetEditor_1 = require("./WidgetEditor"); +const PageStackDisplay_1 = require("../PageStackDisplay"); +const ErrorBoundary_1 = __importDefault(require("./ErrorBoundary")); +const VirtualDatabase_1 = __importDefault(require("../database/VirtualDatabase")); +const AddWizardPalette_1 = __importDefault(require("./AddWizardPalette")); +const ClipboardPalette_1 = __importDefault(require("./ClipboardPalette")); +const canonical_json_1 = __importDefault(require("canonical-json")); var Mode; (function (Mode) { Mode[Mode["Design"] = 0] = "Design"; Mode[Mode["Preview"] = 1] = "Preview"; })(Mode || (Mode = {})); /** Design mode for a single widget. Ensures that blockdefs are always canonical */ -var WidgetDesigner = /** @class */ (function (_super) { - __extends(WidgetDesigner, _super); - function WidgetDesigner(props) { - var _this = _super.call(this, props) || this; - _this.handleSelect = function (blockId) { - _this.setState({ selectedBlockId: blockId }); +class WidgetDesigner extends React.Component { + constructor(props) { + super(props); + this.handleSelect = (blockId) => { + this.setState({ selectedBlockId: blockId }); }; /** Handle change including undo stack */ - _this.handleWidgetDefChange = function (widgetDef) { - _this.setState({ undoStack: _this.state.undoStack.concat([_this.props.widgetDef]), redoStack: [] }); - _this.props.onWidgetDefChange(widgetDef); + this.handleWidgetDefChange = (widgetDef) => { + this.setState({ undoStack: this.state.undoStack.concat([this.props.widgetDef]), redoStack: [] }); + this.props.onWidgetDefChange(widgetDef); }; - _this.handleUndo = function () { - if (_this.state.undoStack.length === 0) { + this.handleUndo = () => { + if (this.state.undoStack.length === 0) { return; } - var undoValue = lodash_1.default.last(_this.state.undoStack); - _this.setState({ undoStack: lodash_1.default.initial(_this.state.undoStack), redoStack: _this.state.redoStack.concat([_this.props.widgetDef]) }); - _this.props.onWidgetDefChange(undoValue); + const undoValue = lodash_1.default.last(this.state.undoStack); + this.setState({ undoStack: lodash_1.default.initial(this.state.undoStack), redoStack: this.state.redoStack.concat([this.props.widgetDef]) }); + this.props.onWidgetDefChange(undoValue); }; - _this.handleRedo = function () { - if (_this.state.redoStack.length === 0) { + this.handleRedo = () => { + if (this.state.redoStack.length === 0) { return; } - var redoValue = lodash_1.default.last(_this.state.redoStack); - _this.setState({ redoStack: lodash_1.default.initial(_this.state.redoStack), undoStack: _this.state.undoStack.concat([_this.props.widgetDef]) }); - _this.props.onWidgetDefChange(redoValue); + const redoValue = lodash_1.default.last(this.state.redoStack); + this.setState({ redoStack: lodash_1.default.initial(this.state.redoStack), undoStack: this.state.undoStack.concat([this.props.widgetDef]) }); + this.props.onWidgetDefChange(redoValue); }; // Set the widget block - _this.handleBlockDefChange = function (blockDef) { + this.handleBlockDefChange = (blockDef) => { // Canonicalize so that saved version is always canonical - blockDef = _this.canonicalize(blockDef); - _this.handleWidgetDefChange(__assign(__assign({}, _this.props.widgetDef), { blockDef: blockDef })); + blockDef = this.canonicalize(blockDef); + this.handleWidgetDefChange(Object.assign(Object.assign({}, this.props.widgetDef), { blockDef })); }; - _this.handleUnselect = function () { _this.setState({ selectedBlockId: null }); }; - _this.handleRemoveBlock = function (blockId) { - var block = _this.props.baseCtx.createBlock(_this.props.widgetDef.blockDef); - _this.handleBlockDefChange(block.process(_this.props.baseCtx.createBlock, function (b) { return (b.id === blockId) ? null : b; })); + this.handleUnselect = () => { this.setState({ selectedBlockId: null }); }; + this.handleRemoveBlock = (blockId) => { + const block = this.props.baseCtx.createBlock(this.props.widgetDef.blockDef); + this.handleBlockDefChange(block.process(this.props.baseCtx.createBlock, (b) => (b.id === blockId) ? null : b)); }; - _this.handleSetMode = function (mode) { - if (!_this.props.widgetDef.blockDef) { + this.handleSetMode = (mode) => { + if (!this.props.widgetDef.blockDef) { return; } // Verify before allowing preview if (mode === Mode.Preview) { - var contextVars = (_this.props.baseCtx.globalContextVars || []) - .concat(_this.props.widgetDef.contextVars) - .concat(_this.props.widgetDef.privateContextVars || []); - for (var _i = 0, _a = blocks_1.getBlockTree(_this.props.widgetDef.blockDef, _this.props.baseCtx.createBlock, contextVars); _i < _a.length; _i++) { - var childBlock = _a[_i]; - var block = _this.props.baseCtx.createBlock(childBlock.blockDef); + const contextVars = (this.props.baseCtx.globalContextVars || []) + .concat(this.props.widgetDef.contextVars) + .concat(this.props.widgetDef.privateContextVars || []); + for (const childBlock of blocks_1.getBlockTree(this.props.widgetDef.blockDef, this.props.baseCtx.createBlock, contextVars)) { + const block = this.props.baseCtx.createBlock(childBlock.blockDef); // Use context vars for the block - var designCtx = __assign(__assign({}, _this.createDesignCtx()), { contextVars: childBlock.contextVars }); + const designCtx = Object.assign(Object.assign({}, this.createDesignCtx()), { contextVars: childBlock.contextVars }); if (block.validate(designCtx)) { alert("Correct errors first"); return; } } } - _this.setState({ mode: mode }); + this.setState({ mode }); }; - _this.state = { + this.state = { mode: Mode.Design, selectedBlockId: null, undoStack: [], redoStack: [] }; - return _this; } /** Canonicalize the widget's block and all children, returning the canonical version */ - WidgetDesigner.prototype.canonicalize = function (blockDef) { - var _this = this; + canonicalize(blockDef) { // Canonicalize if (blockDef) { // Processes entire tree, canonicalizing it - return this.props.baseCtx.createBlock(blockDef).process(this.props.baseCtx.createBlock, function (b) { - return _this.props.baseCtx.createBlock(b).canonicalize(); + return this.props.baseCtx.createBlock(blockDef).process(this.props.baseCtx.createBlock, (b) => { + return this.props.baseCtx.createBlock(b).canonicalize(); }); } return blockDef; - }; - WidgetDesigner.prototype.createBlockStore = function () { - var _this = this; - var alterBlock = function (blockId, action, removeBlockId) { - var newBlockDef; - var block = _this.props.baseCtx.createBlock(_this.props.widgetDef.blockDef); + } + createBlockStore() { + const alterBlock = (blockId, action, removeBlockId) => { + let newBlockDef; + const block = this.props.baseCtx.createBlock(this.props.widgetDef.blockDef); // Do not allow self-removal in drag - if (removeBlockId === _this.props.widgetDef.blockDef.id) { + if (removeBlockId === this.props.widgetDef.blockDef.id) { return; } // Remove source block if (removeBlockId) { - newBlockDef = block.process(_this.props.baseCtx.createBlock, function (b) { return (b.id === removeBlockId) ? null : b; }); + newBlockDef = block.process(this.props.baseCtx.createBlock, (b) => (b.id === removeBlockId) ? null : b); } else { newBlockDef = block.blockDef; } // If nothing left if (!newBlockDef) { - _this.handleBlockDefChange(null); + this.handleBlockDefChange(null); return; } - newBlockDef = _this.props.baseCtx.createBlock(newBlockDef).process(_this.props.baseCtx.createBlock, function (b) { return (b.id === blockId) ? action(b) : b; }); - _this.handleBlockDefChange(newBlockDef); + newBlockDef = this.props.baseCtx.createBlock(newBlockDef).process(this.props.baseCtx.createBlock, (b) => (b.id === blockId) ? action(b) : b); + this.handleBlockDefChange(newBlockDef); }; - var replaceBlock = function (blockDef) { - alterBlock(blockDef.id, function () { return blockDef; }); + const replaceBlock = (blockDef) => { + alterBlock(blockDef.id, () => blockDef); }; - return { alterBlock: alterBlock, replaceBlock: replaceBlock }; - }; - WidgetDesigner.prototype.createDesignCtx = function () { - var _this = this; + return { alterBlock, replaceBlock }; + } + createDesignCtx() { // Create block store - var store = this.createBlockStore(); - var widgetContextVars = (this.props.baseCtx.globalContextVars || []) + const store = this.createBlockStore(); + const widgetContextVars = (this.props.baseCtx.globalContextVars || []) .concat(this.props.widgetDef.contextVars) .concat(this.props.widgetDef.privateContextVars || []); - var designCtx = __assign(__assign({}, this.props.baseCtx), { dataSource: this.props.dataSource, selectedId: this.state.selectedBlockId, contextVars: widgetContextVars, store: store, blockPaletteEntries: this.props.blockPaletteEntries, + const designCtx = Object.assign(Object.assign({}, this.props.baseCtx), { dataSource: this.props.dataSource, selectedId: this.state.selectedBlockId, contextVars: widgetContextVars, store, blockPaletteEntries: this.props.blockPaletteEntries, // Will be set below renderChildBlock: {} }); // Create renderChildBlock - var renderChildBlock = function (childDesignCtx, childBlockDef, onSet) { + const renderChildBlock = (childDesignCtx, childBlockDef, onSet) => { if (childBlockDef) { - var childBlock = _this.props.baseCtx.createBlock(childBlockDef); - var validationError = childBlock.validate(childDesignCtx); + const childBlock = this.props.baseCtx.createBlock(childBlockDef); + const validationError = childBlock.validate(childDesignCtx); // Gets the label of the block which is displayed on hover - var label = childBlock.getLabel(); - return (React.createElement(BlockWrapper_1.default, { blockDef: childBlockDef, selectedBlockId: _this.state.selectedBlockId, onSelect: _this.handleSelect.bind(null, childBlockDef.id), onRemove: _this.handleRemoveBlock.bind(null, childBlockDef.id), store: store, validationError: validationError, label: label }, childBlock.renderDesign(childDesignCtx))); + const label = childBlock.getLabel(); + return (React.createElement(BlockWrapper_1.default, { blockDef: childBlockDef, selectedBlockId: this.state.selectedBlockId, onSelect: this.handleSelect.bind(null, childBlockDef.id), onRemove: this.handleRemoveBlock.bind(null, childBlockDef.id), store: store, validationError: validationError, label: label }, childBlock.renderDesign(childDesignCtx))); } else { return React.createElement(BlockPlaceholder_1.default, { onSet: onSet }); @@ -201,35 +171,35 @@ var WidgetDesigner = /** @class */ (function (_super) { }; designCtx.renderChildBlock = renderChildBlock; return designCtx; - }; - WidgetDesigner.prototype.renderDesignBlock = function () { + } + renderDesignBlock() { // If there is an existing block, render it if (this.props.widgetDef.blockDef) { - var block = this.props.baseCtx.createBlock(this.props.widgetDef.blockDef); - var designCtx = this.createDesignCtx(); + const block = this.props.baseCtx.createBlock(this.props.widgetDef.blockDef); + const designCtx = this.createDesignCtx(); return designCtx.renderChildBlock(designCtx, block.blockDef, this.handleBlockDefChange); } else { // Create placeholder return React.createElement(BlockPlaceholder_1.default, { onSet: this.handleBlockDefChange }); } - }; - WidgetDesigner.prototype.renderEditor = function () { + } + renderEditor() { if (this.props.widgetDef.blockDef && this.state.selectedBlockId) { // Find selected block ancestry - var contextVars = (this.props.baseCtx.globalContextVars || []) + const contextVars = (this.props.baseCtx.globalContextVars || []) .concat(this.props.widgetDef.contextVars) .concat(this.props.widgetDef.privateContextVars || []); - var selectedBlockAncestry = blocks_1.findBlockAncestry(this.props.widgetDef.blockDef, this.props.baseCtx.createBlock, contextVars, this.state.selectedBlockId); + const selectedBlockAncestry = blocks_1.findBlockAncestry(this.props.widgetDef.blockDef, this.props.baseCtx.createBlock, contextVars, this.state.selectedBlockId); // Create props if (selectedBlockAncestry) { - var selectedChildBlock = selectedBlockAncestry[selectedBlockAncestry.length - 1]; + const selectedChildBlock = selectedBlockAncestry[selectedBlockAncestry.length - 1]; // Create block - var selectedBlock = this.props.baseCtx.createBlock(selectedChildBlock.blockDef); + const selectedBlock = this.props.baseCtx.createBlock(selectedChildBlock.blockDef); // Use context variables for the block - var designCtx = __assign(__assign({}, this.createDesignCtx()), { contextVars: selectedChildBlock.contextVars }); + const designCtx = Object.assign(Object.assign({}, this.createDesignCtx()), { contextVars: selectedChildBlock.contextVars }); // Check for errors - var validationError = selectedBlock.validate(designCtx); + const validationError = selectedBlock.validate(designCtx); return (React.createElement("div", { key: "editor", className: "widget-designer-editor" }, validationError ? React.createElement("div", { className: "text-danger" }, @@ -242,48 +212,47 @@ var WidgetDesigner = /** @class */ (function (_super) { } return (React.createElement("div", { key: "editor", className: "widget-designer-editor" }, React.createElement(WidgetEditor_1.WidgetEditor, { widgetDef: this.props.widgetDef, onWidgetDefChange: this.handleWidgetDefChange, designCtx: this.createDesignCtx() }))); - }; - WidgetDesigner.prototype.renderDesign = function () { + } + renderDesign() { return [ (React.createElement("div", { key: "designer", className: "widget-designer-block", onClick: this.handleUnselect }, this.renderDesignBlock())), this.renderEditor() ]; - }; + } /** Render a preview of the widget in a page */ - WidgetDesigner.prototype.renderPreview = function () { + renderPreview() { if (!this.props.widgetDef.blockDef) { return null; } - var database = this.props.baseCtx.database; + let database = this.props.baseCtx.database; if (this.props.widgetDef.virtualizeDatabaseInPreview || this.props.widgetDef.virtualizeDatabaseInPreview == null) { // Make non-live TODO needed? Could make big queries for counts/sums if mutated database = new VirtualDatabase_1.default(database, this.props.baseCtx.schema, this.props.baseCtx.locale); } // Include global context values if present - var contextVarValues = this.props.widgetDef.contextVarPreviewValues; + const contextVarValues = this.props.widgetDef.contextVarPreviewValues; // Create normal page to display - var page = { + const page = { type: "normal", contextVarValues: contextVarValues, database: database, widgetId: this.props.widgetDef.id }; - var pageElem = React.createElement(PageStackDisplay_1.PageStackDisplay, { baseCtx: this.props.baseCtx, initialPage: page }); + const pageElem = React.createElement(PageStackDisplay_1.PageStackDisplay, { baseCtx: this.props.baseCtx, initialPage: page }); return [ (React.createElement("div", { key: "preview", className: "widget-preview-block" }, React.createElement(ErrorBoundary_1.default, null, pageElem))), (React.createElement("div", { key: "editor", className: "widget-designer-editor" })) ]; - }; - WidgetDesigner.prototype.render = function () { - var _this = this; + } + render() { // Check if canonical - var canonilizedBlockDef = this.canonicalize(this.props.widgetDef.blockDef); + const canonilizedBlockDef = this.canonicalize(this.props.widgetDef.blockDef); if (canonical_json_1.default(canonilizedBlockDef) != canonical_json_1.default(this.props.widgetDef.blockDef)) { // Is not canonical. Defer update (since we can't call directly in render) // and return null - setTimeout(function () { - _this.handleBlockDefChange(canonilizedBlockDef); + setTimeout(() => { + this.handleBlockDefChange(canonilizedBlockDef); }); return null; } @@ -303,7 +272,6 @@ var WidgetDesigner = /** @class */ (function (_super) { { value: Mode.Preview, label: [React.createElement("i", { key: "design", className: "fa fa-play" }), " Preview"] } ], onChange: this.handleSetMode, size: "sm" }))), this.state.mode === Mode.Design ? this.renderDesign() : this.renderPreview())); - }; - return WidgetDesigner; -}(React.Component)); + } +} exports.default = WidgetDesigner; diff --git a/lib/designer/WidgetEditor.js b/lib/designer/WidgetEditor.js index 0a44983c..0050ad5b 100644 --- a/lib/designer/WidgetEditor.js +++ b/lib/designer/WidgetEditor.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -44,36 +20,33 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WidgetEditor = void 0; -var React = __importStar(require("react")); -var uuid_1 = require("uuid"); -var propertyEditors_1 = require("../widgets/propertyEditors"); -var widgets_1 = require("../widgets/widgets"); -var localization_1 = require("../widgets/localization"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var ListEditorComponent_1 = require("react-library/lib/ListEditorComponent"); -var contextVarValues_1 = require("../contextVarValues"); +const React = __importStar(require("react")); +const uuid_1 = require("uuid"); +const propertyEditors_1 = require("../widgets/propertyEditors"); +const widgets_1 = require("../widgets/widgets"); +const localization_1 = require("../widgets/localization"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const ListEditorComponent_1 = require("react-library/lib/ListEditorComponent"); +const contextVarValues_1 = require("../contextVarValues"); /** Edits the overall properties of a widget */ -var WidgetEditor = /** @class */ (function (_super) { - __extends(WidgetEditor, _super); - function WidgetEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleContextVarsChange = function (contextVars) { - _this.props.onWidgetDefChange(__assign(__assign({}, _this.props.widgetDef), { contextVars: contextVars })); +class WidgetEditor extends React.Component { + constructor() { + super(...arguments); + this.handleContextVarsChange = (contextVars) => { + this.props.onWidgetDefChange(Object.assign(Object.assign({}, this.props.widgetDef), { contextVars })); }; - _this.handleContextVarPreviewValues = function (contextVarPreviewValues) { - _this.props.onWidgetDefChange(__assign(__assign({}, _this.props.widgetDef), { contextVarPreviewValues: contextVarPreviewValues })); + this.handleContextVarPreviewValues = (contextVarPreviewValues) => { + this.props.onWidgetDefChange(Object.assign(Object.assign({}, this.props.widgetDef), { contextVarPreviewValues })); }; - _this.handlePrivateContextVarValuesChange = function (privateContextVarValues) { - _this.props.onWidgetDefChange(__assign(__assign({}, _this.props.widgetDef), { privateContextVarValues: privateContextVarValues })); + this.handlePrivateContextVarValuesChange = (privateContextVarValues) => { + this.props.onWidgetDefChange(Object.assign(Object.assign({}, this.props.widgetDef), { privateContextVarValues })); }; - return _this; } - WidgetEditor.prototype.render = function () { - var _this = this; + render() { // Get list of all non-private context variables, including global - var allContextVars = (this.props.designCtx.globalContextVars || []) + const allContextVars = (this.props.designCtx.globalContextVars || []) .concat(this.props.widgetDef.contextVars); - var validationError = widgets_1.validateWidget(this.props.widgetDef, this.props.designCtx, false); + const validationError = widgets_1.validateWidget(this.props.widgetDef, this.props.designCtx, false); return (React.createElement("div", null, validationError ? React.createElement("div", { className: "text-danger" }, @@ -82,36 +55,34 @@ var WidgetEditor = /** @class */ (function (_super) { validationError) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Name" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "name" }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "name" }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Description" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "description" }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "description" }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Group", hint: "Optional grouping of this widget. Blank for none" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "group" }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value || "", onChange: function (val) { return onChange(val || undefined); } }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "group" }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value || "", onChange: val => onChange(val || undefined) }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Variables", hint: "Define data sources (rowsets or rows)" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "privateContextVars" }, function (value, onChange) { return React.createElement(ContextVarsEditor, { contextVars: value || [], onChange: onChange, contextVarValues: _this.props.widgetDef.privateContextVarValues || {}, onContextVarValuesChange: _this.handlePrivateContextVarValuesChange, schema: _this.props.designCtx.schema, dataSource: _this.props.designCtx.dataSource, availContextVars: allContextVars }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "privateContextVars" }, (value, onChange) => React.createElement(ContextVarsEditor, { contextVars: value || [], onChange: onChange, contextVarValues: this.props.widgetDef.privateContextVarValues || {}, onContextVarValuesChange: this.handlePrivateContextVarValuesChange, schema: this.props.designCtx.schema, dataSource: this.props.designCtx.dataSource, availContextVars: allContextVars }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "External Variables", hint: "These are passed in to the widget from its parent. Values for preview only" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "contextVars" }, function (value, onChange) { return React.createElement(ContextVarsEditor, { contextVars: value, onChange: onChange, contextVarValues: _this.props.widgetDef.contextVarPreviewValues, onContextVarValuesChange: _this.handleContextVarPreviewValues, schema: _this.props.designCtx.schema, dataSource: _this.props.designCtx.dataSource, availContextVars: allContextVars }); })), - React.createElement(propertyEditors_1.LabeledProperty, { label: "Global Variables", hint: "Values for preview only" }, (this.props.designCtx.globalContextVars || []).map(function (contextVar) { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "contextVars" }, (value, onChange) => React.createElement(ContextVarsEditor, { contextVars: value, onChange: onChange, contextVarValues: this.props.widgetDef.contextVarPreviewValues, onContextVarValuesChange: this.handleContextVarPreviewValues, schema: this.props.designCtx.schema, dataSource: this.props.designCtx.dataSource, availContextVars: allContextVars }))), + React.createElement(propertyEditors_1.LabeledProperty, { label: "Global Variables", hint: "Values for preview only" }, (this.props.designCtx.globalContextVars || []).map((contextVar) => { return React.createElement("div", { key: contextVar.id, style: { paddingBottom: 10 } }, React.createElement("div", null, contextVar.name, ":"), - React.createElement(contextVarValues_1.ContextVarValueEditor, { contextVar: contextVar, contextVarValue: _this.props.widgetDef.contextVarPreviewValues[contextVar.id], onContextVarValueChange: function (value) { - var _a; - _this.handleContextVarPreviewValues(__assign(__assign({}, _this.props.widgetDef.contextVarPreviewValues), (_a = {}, _a[contextVar.id] = value, _a))); - }, schema: _this.props.designCtx.schema, dataSource: _this.props.designCtx.dataSource, availContextVars: allContextVars })); + React.createElement(contextVarValues_1.ContextVarValueEditor, { contextVar: contextVar, contextVarValue: this.props.widgetDef.contextVarPreviewValues[contextVar.id], onContextVarValueChange: value => { + this.handleContextVarPreviewValues(Object.assign(Object.assign({}, this.props.widgetDef.contextVarPreviewValues), { [contextVar.id]: value })); + }, schema: this.props.designCtx.schema, dataSource: this.props.designCtx.dataSource, availContextVars: allContextVars })); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "virtualizeDatabaseInPreview" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value != null ? value : true, onChange: onChange }, "Prevent changes to database in Preview"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.props.widgetDef, onChange: this.props.onWidgetDefChange, property: "virtualizeDatabaseInPreview" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value != null ? value : true, onChange: onChange }, "Prevent changes to database in Preview")), React.createElement(propertyEditors_1.LabeledProperty, { label: "Widget ID", hint: "Advanced" }, - React.createElement("input", { type: "text", value: this.props.widgetDef.id, className: "form-control input-sm", onFocus: function (ev) { ev.target.select(); } })))); - }; - return WidgetEditor; -}(React.Component)); + React.createElement("input", { type: "text", value: this.props.widgetDef.id, className: "form-control input-sm", onFocus: ev => { ev.target.select(); } })))); + } +} exports.WidgetEditor = WidgetEditor; /** Edits a set of context variables and their values */ -var ContextVarsEditor = function (props) { - var renderItem = function (contextVar) { - var desc = contextVar.type; +const ContextVarsEditor = (props) => { + const renderItem = (contextVar) => { + let desc = contextVar.type; if (contextVar.table) { desc += " of "; desc += props.schema.getTable(contextVar.table) ? localization_1.localize(props.schema.getTable(contextVar.table).name, "en") : contextVar.table; @@ -123,15 +94,12 @@ var ContextVarsEditor = function (props) { React.createElement("span", { className: "text-muted" }, "- ", desc)), - React.createElement(contextVarValues_1.ContextVarValueEditor, { contextVar: contextVar, contextVarValue: props.contextVarValues[contextVar.id], onContextVarValueChange: function (value) { - var _a; - return props.onContextVarValuesChange(__assign(__assign({}, props.contextVarValues), (_a = {}, _a[contextVar.id] = value, _a))); - }, schema: props.schema, dataSource: props.dataSource, availContextVars: props.availContextVars })); + React.createElement(contextVarValues_1.ContextVarValueEditor, { contextVar: contextVar, contextVarValue: props.contextVarValues[contextVar.id], onContextVarValueChange: value => props.onContextVarValuesChange(Object.assign(Object.assign({}, props.contextVarValues), { [contextVar.id]: value })), schema: props.schema, dataSource: props.dataSource, availContextVars: props.availContextVars })); }; - var renderEditor = function (item, onItemChange) { + const renderEditor = (item, onItemChange) => { return React.createElement(ContextVarEditor, { contextVar: item, onContextVarChange: onItemChange, schema: props.schema, locale: "en" }); }; - var validateItem = function (contextVar) { + const validateItem = (contextVar) => { if (!contextVar.type) { alert("Type required"); return false; @@ -144,15 +112,15 @@ var ContextVarsEditor = function (props) { } return true; }; - return React.createElement(ListEditorComponent_1.ListEditorComponent, { items: props.contextVars, onItemsChange: props.onChange, renderItem: renderItem, addLabel: "Add Variable", createNew: function () { return ({ id: uuid_1.v4(), name: "Untitled", type: "rowset" }); }, renderEditor: renderEditor, validateItem: validateItem, deleteConfirmPrompt: "Delete variable?", editLink: true }); + return React.createElement(ListEditorComponent_1.ListEditorComponent, { items: props.contextVars, onItemsChange: props.onChange, renderItem: renderItem, addLabel: "Add Variable", createNew: () => ({ id: uuid_1.v4(), name: "Untitled", type: "rowset" }), renderEditor: renderEditor, validateItem: validateItem, deleteConfirmPrompt: "Delete variable?", editLink: true }); }; function ContextVarEditor(props) { - var mainTypeOptions = [ + const mainTypeOptions = [ { value: "row", label: "Single Row" }, { value: "rowset", label: "Multiple Rows" }, { value: "advanced", label: "Advanced..." } ]; - var advancedTypeOptions = [ + const advancedTypeOptions = [ { value: "text", label: "Text" }, { value: "number", label: "Number" }, { value: "boolean", label: "Boolean" }, @@ -165,31 +133,31 @@ function ContextVarEditor(props) { ]; return React.createElement("div", { style: { paddingBottom: 200 } }, React.createElement(propertyEditors_1.LabeledProperty, { label: "Name" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "name", onChange: props.onContextVarChange }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value || "", onChange: function (name) { return onChange(name || undefined); } }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "name", onChange: props.onContextVarChange }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value || "", onChange: name => onChange(name || undefined) }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Type" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "type", onChange: props.onContextVarChange }, function (value, onChange) { return (React.createElement("div", null, - React.createElement(bootstrap_1.Toggle, { value: value == "row" || value == "rowset" ? value : "advanced", onChange: function (v) { return onChange(v == "advanced" ? "text" : v); }, options: mainTypeOptions, size: "sm" }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "type", onChange: props.onContextVarChange }, (value, onChange) => (React.createElement("div", null, + React.createElement(bootstrap_1.Toggle, { value: value == "row" || value == "rowset" ? value : "advanced", onChange: v => onChange(v == "advanced" ? "text" : v), options: mainTypeOptions, size: "sm" }), value && value != "row" && value != "rowset" ? React.createElement("div", { style: { padding: 5 } }, React.createElement(bootstrap_1.Select, { value: value, onChange: onChange, options: advancedTypeOptions })) - : null)); })), + : null)))), props.contextVar.type == "enum" || props.contextVar.type == "enumset" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Enum Options" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "enumValues", onChange: props.onContextVarChange }, function (value, onChange) { return (React.createElement(EnumValuesEditor, { enumValues: value, onChange: onChange })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "enumValues", onChange: props.onContextVarChange }, (value, onChange) => (React.createElement(EnumValuesEditor, { enumValues: value, onChange: onChange })))) : null, props.contextVar.type == "id" || props.contextVar.type == "id[]" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Referenced Table" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "idTable", onChange: props.onContextVarChange }, function (value, onChange) { return React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, value: value || null, onChange: function (t) { return onChange(t || undefined); }, locale: props.locale }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "idTable", onChange: props.onContextVarChange }, (value, onChange) => React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, value: value || null, onChange: t => onChange(t || undefined), locale: props.locale }))) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Table", hint: props.contextVar.type != "row" && props.contextVar.type != "rowset" ? "Optional" : undefined }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "table", onChange: props.onContextVarChange }, function (value, onChange) { return React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, value: value || null, onChange: function (t) { return onChange(t || undefined); }, locale: props.locale }); }))); + React.createElement(propertyEditors_1.PropertyEditor, { obj: props.contextVar, property: "table", onChange: props.onContextVarChange }, (value, onChange) => React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, value: value || null, onChange: t => onChange(t || undefined), locale: props.locale })))); } /** Edits */ function EnumValuesEditor(props) { function renderItem(enumValue, index, onEnumValueChange) { return React.createElement("div", { style: { display: "grid", gridTemplateColumns: "1fr 2fr" } }, - React.createElement(bootstrap_1.TextInput, { value: enumValue.id, onChange: function (id) { onEnumValueChange(__assign(__assign({}, enumValue), { id: id || "" })); } }), - React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: enumValue.name, onChange: function (name) { onEnumValueChange(__assign(__assign({}, enumValue), { name: name })); }, locale: "en" })); + React.createElement(bootstrap_1.TextInput, { value: enumValue.id, onChange: id => { onEnumValueChange(Object.assign(Object.assign({}, enumValue), { id: id || "" })); } }), + React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: enumValue.name, onChange: name => { onEnumValueChange(Object.assign(Object.assign({}, enumValue), { name: name })); }, locale: "en" })); } - return React.createElement(ListEditorComponent_1.ListEditorComponent, { items: props.enumValues || [], onItemsChange: props.onChange, renderItem: renderItem, addLabel: "Add Enum Option", createNew: function () { return ({ id: "", name: { _base: "en", en: "" } }); } }); + return React.createElement(ListEditorComponent_1.ListEditorComponent, { items: props.enumValues || [], onItemsChange: props.onChange, renderItem: renderItem, addLabel: "Add Enum Option", createNew: () => ({ id: "", name: { _base: "en", en: "" } }) }); } diff --git a/lib/designer/blockPaletteEntries.js b/lib/designer/blockPaletteEntries.js index d353c5c9..c2815abf 100644 --- a/lib/designer/blockPaletteEntries.js +++ b/lib/designer/blockPaletteEntries.js @@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultBlockPaletteEntries = void 0; -var v4_1 = __importDefault(require("uuid/v4")); -var react_1 = __importDefault(require("react")); +const v4_1 = __importDefault(require("uuid/v4")); +const react_1 = __importDefault(require("react")); exports.defaultBlockPaletteEntries = [ { title: "Text", @@ -86,8 +86,8 @@ exports.defaultBlockPaletteEntries = [ }, { title: "Query Table", - blockDef: function (contextVars) { - var rowsetCV = contextVars.find(function (cv) { return cv.type == "rowset"; }); + blockDef: (contextVars) => { + const rowsetCV = contextVars.find(cv => cv.type == "rowset"); return { id: "", mode: "singleRow", diff --git a/lib/designer/widgetLibrary.js b/lib/designer/widgetLibrary.js index 611e0fcf..e9b9bca7 100644 --- a/lib/designer/widgetLibrary.js +++ b/lib/designer/widgetLibrary.js @@ -1,93 +1,78 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.WidgetLibraryDesigner = void 0; -var react_1 = __importDefault(require("react")); -var uuid_1 = require("uuid"); -var widgets_1 = require("../widgets/widgets"); -var WidgetDesigner_1 = __importDefault(require("./WidgetDesigner")); -var immer_1 = __importDefault(require("immer")); -var lodash_1 = __importDefault(require("lodash")); -var NewTab_1 = require("./NewTab"); +const react_1 = __importDefault(require("react")); +const uuid_1 = require("uuid"); +const widgets_1 = require("../widgets/widgets"); +const WidgetDesigner_1 = __importDefault(require("./WidgetDesigner")); +const immer_1 = __importDefault(require("immer")); +const lodash_1 = __importDefault(require("lodash")); +const NewTab_1 = require("./NewTab"); /** Design mode for a library of widgets */ -var WidgetLibraryDesigner = /** @class */ (function (_super) { - __extends(WidgetLibraryDesigner, _super); - function WidgetLibraryDesigner(props) { - var _this = _super.call(this, props) || this; - _this.handleTabChange = function (widgetId, widgetDef) { - _this.props.onWidgetLibraryChange(immer_1.default(_this.props.baseCtx.widgetLibrary, function (draft) { +class WidgetLibraryDesigner extends react_1.default.Component { + constructor(props) { + super(props); + this.handleTabChange = (widgetId, widgetDef) => { + this.props.onWidgetLibraryChange(immer_1.default(this.props.baseCtx.widgetLibrary, (draft) => { draft.widgets[widgetId] = widgetDef; })); }; - _this.handleSelectTab = function (index) { - _this.setState({ activeTabIndex: index }); + this.handleSelectTab = (index) => { + this.setState({ activeTabIndex: index }); }; - _this.handleAddWidget = function (widgetDef) { - var widgetLibrary = immer_1.default(_this.props.baseCtx.widgetLibrary, function (draft) { + this.handleAddWidget = (widgetDef) => { + const widgetLibrary = immer_1.default(this.props.baseCtx.widgetLibrary, (draft) => { draft.widgets[widgetDef.id] = widgetDef; }); - _this.props.onWidgetLibraryChange(widgetLibrary); - _this.props.onOpenTabsChange(_this.props.openTabs.concat(widgetDef.id)); + this.props.onWidgetLibraryChange(widgetLibrary); + this.props.onOpenTabsChange(this.props.openTabs.concat(widgetDef.id)); }; - _this.handleDuplicateWidget = function (widgetDef) { - var newId = uuid_1.v4(); - var widgetLibrary = immer_1.default(_this.props.baseCtx.widgetLibrary, function (draft) { - var newDef = lodash_1.default.cloneDeep(widgetDef); + this.handleDuplicateWidget = (widgetDef) => { + const newId = uuid_1.v4(); + const widgetLibrary = immer_1.default(this.props.baseCtx.widgetLibrary, (draft) => { + const newDef = lodash_1.default.cloneDeep(widgetDef); newDef.id = newId; newDef.name = newDef.name + " (duplicate)"; newDef.description = newDef.description; newDef.group = newDef.group; draft.widgets[newId] = newDef; }); - _this.props.onWidgetLibraryChange(widgetLibrary); + this.props.onWidgetLibraryChange(widgetLibrary); }; - _this.handleCloseTab = function (index, ev) { + this.handleCloseTab = (index, ev) => { ev.stopPropagation(); - var openTabs = _this.props.openTabs.slice(); + const openTabs = this.props.openTabs.slice(); openTabs.splice(index, 1); - _this.props.onOpenTabsChange(openTabs); + this.props.onOpenTabsChange(openTabs); }; - _this.handleOpenWidget = function (widgetId) { - _this.props.onOpenTabsChange(_this.props.openTabs.concat(widgetId)); + this.handleOpenWidget = (widgetId) => { + this.props.onOpenTabsChange(this.props.openTabs.concat(widgetId)); }; - _this.handleRemoveWidget = function (widgetId) { - var widget = _this.props.baseCtx.widgetLibrary.widgets[widgetId]; - if (!confirm("Permanently delete " + widget.name + " widget?")) { + this.handleRemoveWidget = (widgetId) => { + const widget = this.props.baseCtx.widgetLibrary.widgets[widgetId]; + if (!confirm(`Permanently delete ${widget.name} widget?`)) { return; } - var widgetLibrary = immer_1.default(_this.props.baseCtx.widgetLibrary, function (draft) { + const widgetLibrary = immer_1.default(this.props.baseCtx.widgetLibrary, (draft) => { delete draft.widgets[widgetId]; }); - _this.props.onOpenTabsChange(lodash_1.default.without(_this.props.openTabs, widgetId)); - _this.props.onWidgetLibraryChange(widgetLibrary); + this.props.onOpenTabsChange(lodash_1.default.without(this.props.openTabs, widgetId)); + this.props.onWidgetLibraryChange(widgetLibrary); }; /** Validate a single widget */ - _this.validateSingleWidget = function (widgetDef) { - return widgets_1.validateWidget(widgetDef, _this.props.baseCtx, true); + this.validateSingleWidget = (widgetDef) => { + return widgets_1.validateWidget(widgetDef, this.props.baseCtx, true); }; - _this.state = { + this.state = { activeTabIndex: 0 }; - return _this; } - WidgetLibraryDesigner.prototype.renderTab = function (index) { - var activeTabId = this.props.openTabs[index]; - var widgetDef = this.props.baseCtx.widgetLibrary.widgets[activeTabId]; + renderTab(index) { + const activeTabId = this.props.openTabs[index]; + const widgetDef = this.props.baseCtx.widgetLibrary.widgets[activeTabId]; // For immediately deleted tabs if (!widgetDef) { return null; @@ -97,11 +82,11 @@ var WidgetLibraryDesigner = /** @class */ (function (_super) { widgetDef.name, "\u00A0", react_1.default.createElement("i", { onClick: this.handleCloseTab.bind(null, index), className: "fa fa-remove text-muted" })))); - }; - WidgetLibraryDesigner.prototype.renderActiveTabContents = function () { + } + renderActiveTabContents() { if (this.state.activeTabIndex < this.props.openTabs.length) { - var activeTabId = this.props.openTabs[this.state.activeTabIndex]; - var widgetDef = this.props.baseCtx.widgetLibrary.widgets[activeTabId]; + const activeTabId = this.props.openTabs[this.state.activeTabIndex]; + const widgetDef = this.props.baseCtx.widgetLibrary.widgets[activeTabId]; // For immediately deleted tabs if (!widgetDef) { return null; @@ -111,17 +96,15 @@ var WidgetLibraryDesigner = /** @class */ (function (_super) { else { return react_1.default.createElement(NewTab_1.NewTab, { widgetLibrary: this.props.baseCtx.widgetLibrary, onAddWidget: this.handleAddWidget, onOpenWidget: this.handleOpenWidget, onRemoveWidget: this.handleRemoveWidget, onDuplicateWidget: this.handleDuplicateWidget, validateWidget: this.validateSingleWidget }); } - }; - WidgetLibraryDesigner.prototype.render = function () { - var _this = this; + } + render() { return (react_1.default.createElement("div", { style: { height: "100%", display: "grid", gridTemplateRows: "auto 1fr" } }, react_1.default.createElement("ul", { className: "nav nav-tabs", style: { marginBottom: 5 } }, - this.props.openTabs.map(function (tab, index) { return _this.renderTab(index); }), + this.props.openTabs.map((tab, index) => this.renderTab(index)), react_1.default.createElement("li", { className: (this.state.activeTabIndex >= this.props.openTabs.length) ? "active" : "", key: "new" }, react_1.default.createElement("a", { onClick: this.handleSelectTab.bind(null, this.props.openTabs.length) }, react_1.default.createElement("i", { className: "fa fa-plus" })))), this.renderActiveTabContents())); - }; - return WidgetLibraryDesigner; -}(react_1.default.Component)); + } +} exports.WidgetLibraryDesigner = WidgetLibraryDesigner; diff --git a/lib/embeddedExprs.d.ts b/lib/embeddedExprs.d.ts index 128c2e86..ae673b69 100644 --- a/lib/embeddedExprs.d.ts +++ b/lib/embeddedExprs.d.ts @@ -1,6 +1,5 @@ import { Expr, Schema } from "mwater-expressions"; import { ContextVar } from "./widgets/blocks"; -import * as d3Format from 'd3-format'; import { FormatLocaleObject } from "d3-format"; /** Expression which is embedded in the text string */ export interface EmbeddedExpr { @@ -22,7 +21,7 @@ export declare const formatEmbeddedExprString: (options: { schema: Schema; contextVars: ContextVar[]; locale: string; - formatLocale?: d3Format.FormatLocaleObject | undefined; + formatLocale?: FormatLocaleObject; }) => string; /** Validate embedded expressions, returning null if ok, message otherwise */ export declare const validateEmbeddedExprs: (options: { diff --git a/lib/embeddedExprs.js b/lib/embeddedExprs.js index b6580573..e24e2c6e 100644 --- a/lib/embeddedExprs.js +++ b/lib/embeddedExprs.js @@ -23,21 +23,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateEmbeddedExprs = exports.formatEmbeddedExprString = void 0; -var mwater_expressions_1 = require("mwater-expressions"); -var blocks_1 = require("./widgets/blocks"); -var d3Format = __importStar(require("d3-format")); -var moment_1 = __importDefault(require("moment")); +const mwater_expressions_1 = require("mwater-expressions"); +const blocks_1 = require("./widgets/blocks"); +const d3Format = __importStar(require("d3-format")); +const moment_1 = __importDefault(require("moment")); /** Format an embedded string which is a string with {0}, {1}, etc. to be replaced by expressions */ -exports.formatEmbeddedExprString = function (options) { - var text = options.text; - var formatLocale = options.formatLocale || d3Format; +exports.formatEmbeddedExprString = (options) => { + let text = options.text; + const formatLocale = options.formatLocale || d3Format; // Format and replace - for (var i = 0; i < options.exprValues.length; i++) { - var str = void 0; - var expr = options.embeddedExprs[i].expr; - var exprType = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)).getExprType(expr); - var format = options.embeddedExprs[i].format; - var value = options.exprValues[i]; + for (let i = 0; i < options.exprValues.length; i++) { + let str; + const expr = options.embeddedExprs[i].expr; + const exprType = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)).getExprType(expr); + const format = options.embeddedExprs[i].format; + const value = options.exprValues[i]; if (value == null) { str = ""; } @@ -61,15 +61,14 @@ exports.formatEmbeddedExprString = function (options) { str = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)).stringifyExprLiteral(expr, value, options.locale); } } - text = text.replace("{" + i + "}", str); + text = text.replace(`{${i}}`, str); } return text; }; /** Validate embedded expressions, returning null if ok, message otherwise */ -exports.validateEmbeddedExprs = function (options) { - for (var _i = 0, _a = options.embeddedExprs; _i < _a.length; _i++) { - var embeddedExpr = _a[_i]; - var error = blocks_1.validateContextVarExpr({ +exports.validateEmbeddedExprs = (options) => { + for (const embeddedExpr of options.embeddedExprs) { + const error = blocks_1.validateContextVarExpr({ contextVars: options.contextVars, schema: options.schema, contextVarId: embeddedExpr.contextVarId, diff --git a/lib/setupTests.js b/lib/setupTests.js index d6b7cf3b..199b6991 100644 --- a/lib/setupTests.js +++ b/lib/setupTests.js @@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var enzyme_1 = require("enzyme"); -var enzyme_adapter_react_16_1 = __importDefault(require("enzyme-adapter-react-16")); +const enzyme_1 = require("enzyme"); +const enzyme_adapter_react_16_1 = __importDefault(require("enzyme-adapter-react-16")); // React 16 Enzyme adapter enzyme_1.configure({ adapter: new enzyme_adapter_react_16_1.default() }); diff --git a/lib/widgets/ActionLibrary.js b/lib/widgets/ActionLibrary.js index afd78f04..c93fa34f 100644 --- a/lib/widgets/ActionLibrary.js +++ b/lib/widgets/ActionLibrary.js @@ -1,21 +1,21 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ActionLibrary = void 0; -var openPage_1 = require("./actions/openPage"); -var addRow_1 = require("./actions/addRow"); -var gotoUrl_1 = require("./actions/gotoUrl"); -var removeRow_1 = require("./actions/removeRow"); -var browserBack_1 = require("./actions/browserBack"); +const openPage_1 = require("./actions/openPage"); +const addRow_1 = require("./actions/addRow"); +const gotoUrl_1 = require("./actions/gotoUrl"); +const removeRow_1 = require("./actions/removeRow"); +const browserBack_1 = require("./actions/browserBack"); /** Library of actions */ -var ActionLibrary = /** @class */ (function () { - function ActionLibrary() { +class ActionLibrary { + constructor() { this.customActions = []; } - ActionLibrary.prototype.registerCustomAction = function (type, name, actionDefFactory, actionFactory) { - this.customActions.push({ type: type, name: name, actionDefFactory: actionDefFactory, actionFactory: actionFactory }); - }; + registerCustomAction(type, name, actionDefFactory, actionFactory) { + this.customActions.push({ type, name, actionDefFactory, actionFactory }); + } /** Creates an action from an action def */ - ActionLibrary.prototype.createAction = function (actionDef) { + createAction(actionDef) { switch (actionDef.type) { case "openPage": return new openPage_1.OpenPageAction(actionDef); @@ -28,16 +28,15 @@ var ActionLibrary = /** @class */ (function () { case "browserBack": return new browserBack_1.BrowserBackAction(actionDef); } - for (var _i = 0, _a = this.customActions; _i < _a.length; _i++) { - var customAction = _a[_i]; + for (const customAction of this.customActions) { if (customAction.type == actionDef.type) { return customAction.actionFactory(actionDef); } } throw new Error("Unknown action type"); - }; + } /** Create a new action def with defaults set of the specified type */ - ActionLibrary.prototype.createNewActionDef = function (type) { + createNewActionDef(type) { switch (type) { case "openPage": return { @@ -67,29 +66,26 @@ var ActionLibrary = /** @class */ (function () { type: "browserBack" }; } - for (var _i = 0, _a = this.customActions; _i < _a.length; _i++) { - var customAction = _a[_i]; + for (const customAction of this.customActions) { if (customAction.type == type) { return customAction.actionDefFactory(type); } } throw new Error("Unknown action type"); - }; + } /** Get a list of all known action types */ - ActionLibrary.prototype.getActionTypes = function () { - var list = [ + getActionTypes() { + const list = [ { type: "openPage", name: "Open Page" }, { type: "addRow", name: "Add Row" }, { type: "removeRow", name: "Remove Row" }, { type: "gotoUrl", name: "Goto URL" }, { type: "browserBack", name: "Browser Back" } ]; - for (var _i = 0, _a = this.customActions; _i < _a.length; _i++) { - var customAction = _a[_i]; + for (const customAction of this.customActions) { list.push({ type: customAction.type, name: customAction.name }); } return list; - }; - return ActionLibrary; -}()); + } +} exports.ActionLibrary = ActionLibrary; diff --git a/lib/widgets/BlockFactory.js b/lib/widgets/BlockFactory.js index 020ff5a4..06a283d0 100644 --- a/lib/widgets/BlockFactory.js +++ b/lib/widgets/BlockFactory.js @@ -1,47 +1,46 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var horizontal_1 = require("./blocks/horizontal"); -var vertical_1 = require("./blocks/vertical"); -var widget_1 = require("./blocks/widget"); -var text_1 = require("./blocks/text"); -var labeled_1 = require("./blocks/labeled"); -var collapsible_1 = require("./blocks/collapsible"); -var expression_1 = require("./blocks/expression"); -var queryTable_1 = require("./blocks/queryTable/queryTable"); -var search_1 = require("./blocks/search/search"); -var button_1 = require("./blocks/button"); -var textbox_1 = require("./blocks/controls/textbox"); -var saveCancel_1 = require("./blocks/saveCancel"); -var dropdown_1 = require("./blocks/controls/dropdown"); -var dropdownFilter_1 = require("./blocks/dropdownFilter/dropdownFilter"); -var rowset_1 = require("./blocks/rowset"); -var tabbed_1 = require("./blocks/tabbed/tabbed"); -var image_1 = require("./blocks/image"); -var addRow_1 = require("./blocks/addRow"); -var datefield_1 = require("./blocks/controls/datefield"); -var conditional_1 = require("./blocks/conditional"); -var fixedTable_1 = require("./blocks/fixedTable"); -var addWizard_1 = require("./blocks/addWizard"); -var numberbox_1 = require("./blocks/controls/numberbox"); -var header_1 = require("./blocks/header"); -var toc_1 = require("./blocks/toc/toc"); -var validation_1 = require("./blocks/validation"); -var float_1 = require("./blocks/float"); -var spacer_1 = require("./blocks/spacer"); -var print_1 = require("./blocks/print"); -var queryRepeat_1 = require("./blocks/queryRepeat/queryRepeat"); -var row_1 = require("./blocks/row"); -var panel_1 = require("./blocks/panel"); -var alert_1 = require("./blocks/alert"); -var dateInject_1 = require("./blocks/dateInject"); -var toggle_1 = require("./blocks/controls/toggle"); -var GanttChart_1 = require("./blocks/ganttChart/GanttChart"); -var toggleFilter_1 = require("./blocks/toggleFilter"); -var tagsEditor_1 = require("./blocks/controls/tagsEditor"); -var BlockFactory = /** @class */ (function () { - function BlockFactory() { - var _this = this; - this.createBlock = function (blockDef) { +const horizontal_1 = require("./blocks/horizontal"); +const vertical_1 = require("./blocks/vertical"); +const widget_1 = require("./blocks/widget"); +const text_1 = require("./blocks/text"); +const labeled_1 = require("./blocks/labeled"); +const collapsible_1 = require("./blocks/collapsible"); +const expression_1 = require("./blocks/expression"); +const queryTable_1 = require("./blocks/queryTable/queryTable"); +const search_1 = require("./blocks/search/search"); +const button_1 = require("./blocks/button"); +const textbox_1 = require("./blocks/controls/textbox"); +const saveCancel_1 = require("./blocks/saveCancel"); +const dropdown_1 = require("./blocks/controls/dropdown"); +const dropdownFilter_1 = require("./blocks/dropdownFilter/dropdownFilter"); +const rowset_1 = require("./blocks/rowset"); +const tabbed_1 = require("./blocks/tabbed/tabbed"); +const image_1 = require("./blocks/image"); +const addRow_1 = require("./blocks/addRow"); +const datefield_1 = require("./blocks/controls/datefield"); +const conditional_1 = require("./blocks/conditional"); +const fixedTable_1 = require("./blocks/fixedTable"); +const addWizard_1 = require("./blocks/addWizard"); +const numberbox_1 = require("./blocks/controls/numberbox"); +const header_1 = require("./blocks/header"); +const toc_1 = require("./blocks/toc/toc"); +const validation_1 = require("./blocks/validation"); +const float_1 = require("./blocks/float"); +const spacer_1 = require("./blocks/spacer"); +const print_1 = require("./blocks/print"); +const queryRepeat_1 = require("./blocks/queryRepeat/queryRepeat"); +const row_1 = require("./blocks/row"); +const panel_1 = require("./blocks/panel"); +const alert_1 = require("./blocks/alert"); +const dateInject_1 = require("./blocks/dateInject"); +const toggle_1 = require("./blocks/controls/toggle"); +const GanttChart_1 = require("./blocks/ganttChart/GanttChart"); +const toggleFilter_1 = require("./blocks/toggleFilter"); +const tagsEditor_1 = require("./blocks/controls/tagsEditor"); +class BlockFactory { + constructor() { + this.createBlock = (blockDef) => { switch (blockDef.type) { case "addWizard": return new addWizard_1.AddWizardBlock(blockDef); @@ -121,16 +120,15 @@ var BlockFactory = /** @class */ (function () { return new tagsEditor_1.TagsEditorBlock(blockDef); } // Use custom blocks - if (_this.customBlocks[blockDef.type]) { - return _this.customBlocks[blockDef.type](blockDef); + if (this.customBlocks[blockDef.type]) { + return this.customBlocks[blockDef.type](blockDef); } - throw new Error("Type " + blockDef.type + " not found"); + throw new Error(`Type ${blockDef.type} not found`); }; this.customBlocks = {}; } - BlockFactory.prototype.registerCustomBlock = function (type, factory) { + registerCustomBlock(type, factory) { this.customBlocks[type] = factory; - }; - return BlockFactory; -}()); + } +} exports.default = BlockFactory; diff --git a/lib/widgets/BlockPlaceholder.js b/lib/widgets/BlockPlaceholder.js index 14b45956..4bcdb207 100644 --- a/lib/widgets/BlockPlaceholder.js +++ b/lib/widgets/BlockPlaceholder.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -32,21 +19,21 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var react_dnd_1 = require("react-dnd"); +const React = __importStar(require("react")); +const react_dnd_1 = require("react-dnd"); require("./BlockPlaceholder.css"); -var uuid = require("uuid"); -var blockTargetSpec = { - canDrop: function (props, monitor) { +const uuid = require("uuid"); +const blockTargetSpec = { + canDrop(props, monitor) { return true; }, - drop: function (props, monitor, component) { + drop(props, monitor, component) { if (monitor.didDrop()) { return; } // Defer to next cycle to prevent drop error - var sourceBlockDef = monitor.getItem().blockDef; - setTimeout(function () { + const sourceBlockDef = monitor.getItem().blockDef; + setTimeout(() => { if (props.onSet) { props.onSet(sourceBlockDef); } @@ -54,26 +41,23 @@ var blockTargetSpec = { } }; /** Empty space with a dashed border that blocks can be dragged into */ -var BlockPlaceholder = /** @class */ (function (_super) { - __extends(BlockPlaceholder, _super); - function BlockPlaceholder() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleNew = function () { - if (_this.props.onSet) { - _this.props.onSet({ id: uuid(), type: "addWizard" }); +class BlockPlaceholder extends React.Component { + constructor() { + super(...arguments); + this.handleNew = () => { + if (this.props.onSet) { + this.props.onSet({ id: uuid(), type: "addWizard" }); } }; - return _this; } - BlockPlaceholder.prototype.render = function () { + render() { return this.props.connectDropTarget(React.createElement("div", { className: this.props.isOver ? "block-placeholder drop" : "block-placeholder" }, React.createElement("a", { onClick: this.handleNew }, React.createElement("i", { className: "fa fa-plus" })))); - }; - return BlockPlaceholder; -}(React.Component)); -exports.default = react_dnd_1.DropTarget("ui-builder-block", blockTargetSpec, function (connect, monitor) { return ({ + } +} +exports.default = react_dnd_1.DropTarget("ui-builder-block", blockTargetSpec, (connect, monitor) => ({ connectDropTarget: connect.dropTarget(), isOver: monitor.isOver({ shallow: true }), canDrop: monitor.canDrop() -}); })(BlockPlaceholder); +}))(BlockPlaceholder); diff --git a/lib/widgets/ContextVarInjector.js b/lib/widgets/ContextVarInjector.js index 4f7e9fd6..915f8474 100644 --- a/lib/widgets/ContextVarInjector.js +++ b/lib/widgets/ContextVarInjector.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -51,70 +27,41 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var blocks_1 = require("./blocks"); -var React = __importStar(require("react")); -var mwater_expressions_1 = require("mwater-expressions"); -var canonical_json_1 = __importDefault(require("canonical-json")); -var lodash_1 = __importDefault(require("lodash")); -var contexts_1 = require("../contexts"); +const blocks_1 = require("./blocks"); +const React = __importStar(require("react")); +const mwater_expressions_1 = require("mwater-expressions"); +const canonical_json_1 = __importDefault(require("canonical-json")); +const lodash_1 = __importDefault(require("lodash")); +const contexts_1 = require("../contexts"); /** Injects one context variable into the inner render instance props. * Holds state of the filters that are applied to rowset-type context vars * Computes values of expressions for row and rowset types */ -var ContextVarInjector = /** @class */ (function (_super) { - __extends(ContextVarInjector, _super); - function ContextVarInjector(props) { - var _this = _super.call(this, props) || this; - _this.handleDatabaseChange = function () { - _this.performQueries(); +class ContextVarInjector extends React.Component { + constructor(props) { + super(props); + this.handleDatabaseChange = () => { + this.performQueries(); }; - _this.state = { + this.state = { filters: props.initialFilters || [], loading: true, refreshing: false, exprValues: {}, filteredContextVarValues: contexts_1.getFilteredContextVarValues(props.instanceCtx) }; - _this.unmounted = false; - return _this; + this.unmounted = false; } - ContextVarInjector.prototype.componentDidMount = function () { + componentDidMount() { this.performQueries(); // Listen for changes to database this.props.instanceCtx.database.addChangeListener(this.handleDatabaseChange); - }; - ContextVarInjector.prototype.componentDidUpdate = function (prevProps, prevState) { + } + componentDidUpdate(prevProps, prevState) { // If value change, filters change, or any context var values changes, refresh // TODO context var value changes are only relevant if referenced as a variable. Could be optimized if (!lodash_1.default.isEqual(prevProps.value, this.props.value) @@ -122,13 +69,13 @@ var ContextVarInjector = /** @class */ (function (_super) { || !lodash_1.default.isEqual(contexts_1.getFilteredContextVarValues(this.createInnerProps()), this.state.filteredContextVarValues)) { this.performQueries(); } - }; - ContextVarInjector.prototype.componentWillUnmount = function () { + } + componentWillUnmount() { this.unmounted = true; this.props.instanceCtx.database.removeChangeListener(this.handleDatabaseChange); - }; - ContextVarInjector.prototype.createRowQueryOptions = function (table) { - var queryOptions = { + } + createRowQueryOptions(table) { + const queryOptions = { select: {}, from: table, where: { @@ -139,24 +86,24 @@ var ContextVarInjector = /** @class */ (function (_super) { } }; // Add expressions as selects - for (var i = 0; i < this.props.contextVarExprs.length; i++) { + for (let i = 0; i < this.props.contextVarExprs.length; i++) { queryOptions.select["e" + i] = this.props.contextVarExprs[i]; } return queryOptions; - }; + } /** Create query options for aggregate and literal expressions */ - ContextVarInjector.prototype.createRowsetAggrQueryOptions = function (table, variables) { - var queryOptions = { + createRowsetAggrQueryOptions(table, variables) { + const queryOptions = { select: {}, from: table, where: this.props.value, limit: 1 }; // Add expressions as selects (only if aggregate for rowset) - var exprUtils = new mwater_expressions_1.ExprUtils(this.props.instanceCtx.schema, variables); - var aggrExpressions = this.props.contextVarExprs.filter(function (expr) { return exprUtils.getExprAggrStatus(expr) === "aggregate" || exprUtils.getExprAggrStatus(expr) === "literal"; }); + const exprUtils = new mwater_expressions_1.ExprUtils(this.props.instanceCtx.schema, variables); + const aggrExpressions = this.props.contextVarExprs.filter(expr => exprUtils.getExprAggrStatus(expr) === "aggregate" || exprUtils.getExprAggrStatus(expr) === "literal"); // Add expressions as selects - for (var i = 0; i < aggrExpressions.length; i++) { + for (let i = 0; i < aggrExpressions.length; i++) { queryOptions.select["e" + i] = aggrExpressions[i]; } // Add filters @@ -165,17 +112,17 @@ var ContextVarInjector = /** @class */ (function (_super) { type: "op", table: table, op: "and", - exprs: lodash_1.default.compact([queryOptions.where || null].concat(lodash_1.default.compact(this.state.filters.map(function (f) { return f.expr; })))) + exprs: lodash_1.default.compact([queryOptions.where || null].concat(lodash_1.default.compact(this.state.filters.map(f => f.expr)))) }; if (queryOptions.where.exprs.length === 0) { queryOptions.where = null; } } return queryOptions; - }; + } /** Create query options for individual expressions */ - ContextVarInjector.prototype.createRowsetIndividualQueryOptions = function (table, variables, expr) { - var queryOptions = { + createRowsetIndividualQueryOptions(table, variables, expr) { + const queryOptions = { select: { value: expr }, @@ -190,157 +137,135 @@ var ContextVarInjector = /** @class */ (function (_super) { type: "op", table: table, op: "and", - exprs: lodash_1.default.compact([queryOptions.where || null].concat(lodash_1.default.compact(this.state.filters.map(function (f) { return f.expr; })))) + exprs: lodash_1.default.compact([queryOptions.where || null].concat(lodash_1.default.compact(this.state.filters.map(f => f.expr)))) }; if (queryOptions.where.exprs.length === 0) { queryOptions.where = null; } } return queryOptions; - }; - ContextVarInjector.prototype.performQueries = function () { - return __awaiter(this, void 0, void 0, function () { - var innerProps, variables, variableValues, table, queryOptions, rows, exprValues, i, error_1, table, queryAggrOptions, exprUtils_1, aggrExpressions, individualExpressions, exprValues, aggrRows, i, i, _i, individualExpressions_1, individualExpression, queryIndividualOptions, individualRows, error_2; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - // No need to perform queries if no context var exprs - if (!this.props.contextVarExprs || this.props.contextVarExprs.length == 0) { - if (this.state.loading || this.state.refreshing) { - this.setState({ loading: false, refreshing: false }); - } - return [2 /*return*/]; - } - innerProps = this.createInnerProps(); - variables = blocks_1.createExprVariables(innerProps.contextVars); - variableValues = contexts_1.getFilteredContextVarValues(innerProps); - this.setState({ refreshing: true, filteredContextVarValues: variableValues }); - if (!(this.props.injectedContextVar.type === "row")) return [3 /*break*/, 4]; - // Special case of null row value - if (this.props.value == null) { - this.setState({ exprValues: {}, loading: false, refreshing: false, filteredContextVarValues: variableValues }); - return [2 /*return*/]; - } - this.setState({ refreshing: true }); - table = this.props.injectedContextVar.table; - queryOptions = this.createRowQueryOptions(table); - _a.label = 1; - case 1: - _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, this.props.instanceCtx.database.query(queryOptions, innerProps.contextVars, variableValues) - // Ignore if query options out of date - ]; - case 2: - rows = _a.sent(); - // Ignore if query options out of date - if (!lodash_1.default.isEqual(queryOptions, this.createRowQueryOptions(table))) { - return [2 /*return*/]; - } - // Ignore if variable values out of date - if (!lodash_1.default.isEqual(variableValues, contexts_1.getFilteredContextVarValues(this.createInnerProps()))) { - return [2 /*return*/]; - } - // Ignore if unmounted - if (this.unmounted) { - return [2 /*return*/]; - } - if (rows.length === 0) { - this.setState({ exprValues: {} }); - } - else { - exprValues = {}; - for (i = 0; i < this.props.contextVarExprs.length; i++) { - exprValues[canonical_json_1.default(this.props.contextVarExprs[i])] = rows[0]["e" + i]; - } - this.setState({ exprValues: exprValues }); + } + performQueries() { + return __awaiter(this, void 0, void 0, function* () { + // No need to perform queries if no context var exprs + if (!this.props.contextVarExprs || this.props.contextVarExprs.length == 0) { + if (this.state.loading || this.state.refreshing) { + this.setState({ loading: false, refreshing: false }); + } + return; + } + const innerProps = this.createInnerProps(); + // Determine variables and values for expressions + const variables = blocks_1.createExprVariables(innerProps.contextVars); + const variableValues = contexts_1.getFilteredContextVarValues(innerProps); + this.setState({ refreshing: true, filteredContextVarValues: variableValues }); + // Query database if row + if (this.props.injectedContextVar.type === "row") { + // Special case of null row value + if (this.props.value == null) { + this.setState({ exprValues: {}, loading: false, refreshing: false, filteredContextVarValues: variableValues }); + return; + } + this.setState({ refreshing: true }); + const table = this.props.injectedContextVar.table; + // Perform query + const queryOptions = this.createRowQueryOptions(table); + try { + const rows = yield this.props.instanceCtx.database.query(queryOptions, innerProps.contextVars, variableValues); + // Ignore if query options out of date + if (!lodash_1.default.isEqual(queryOptions, this.createRowQueryOptions(table))) { + return; + } + // Ignore if variable values out of date + if (!lodash_1.default.isEqual(variableValues, contexts_1.getFilteredContextVarValues(this.createInnerProps()))) { + return; + } + // Ignore if unmounted + if (this.unmounted) { + return; + } + if (rows.length === 0) { + this.setState({ exprValues: {} }); + } + else { + const exprValues = {}; + for (let i = 0; i < this.props.contextVarExprs.length; i++) { + exprValues[canonical_json_1.default(this.props.contextVarExprs[i])] = rows[0]["e" + i]; } - return [3 /*break*/, 4]; - case 3: - error_1 = _a.sent(); - this.setState({ error: error_1 }); - return [2 /*return*/]; - case 4: - if (!(this.props.injectedContextVar.type === "rowset")) return [3 /*break*/, 12]; - this.setState({ refreshing: true }); - table = this.props.injectedContextVar.table; - queryAggrOptions = this.createRowsetAggrQueryOptions(table, variables); - _a.label = 5; - case 5: - _a.trys.push([5, 11, , 12]); - exprUtils_1 = new mwater_expressions_1.ExprUtils(this.props.instanceCtx.schema, variables); - aggrExpressions = this.props.contextVarExprs.filter(function (expr) { return exprUtils_1.getExprAggrStatus(expr) === "aggregate" || exprUtils_1.getExprAggrStatus(expr) === "literal"; }); - individualExpressions = this.props.contextVarExprs.filter(function (expr) { return exprUtils_1.getExprAggrStatus(expr) === "individual"; }); - exprValues = {}; - return [4 /*yield*/, this.props.instanceCtx.database.query(queryAggrOptions, innerProps.contextVars, contexts_1.getFilteredContextVarValues(innerProps))]; - case 6: - aggrRows = _a.sent(); - if (aggrRows.length > 0) { - for (i = 0; i < aggrExpressions.length; i++) { - exprValues[canonical_json_1.default(aggrExpressions[i])] = aggrRows[0]["e" + i]; - } + this.setState({ exprValues }); + } + } + catch (error) { + this.setState({ error }); + return; + } + } + // Query database if rowset + if (this.props.injectedContextVar.type === "rowset") { + this.setState({ refreshing: true }); + const table = this.props.injectedContextVar.table; + // Perform query + const queryAggrOptions = this.createRowsetAggrQueryOptions(table, variables); + try { + const exprUtils = new mwater_expressions_1.ExprUtils(this.props.instanceCtx.schema, variables); + const aggrExpressions = this.props.contextVarExprs.filter(expr => exprUtils.getExprAggrStatus(expr) === "aggregate" || exprUtils.getExprAggrStatus(expr) === "literal"); + const individualExpressions = this.props.contextVarExprs.filter(expr => exprUtils.getExprAggrStatus(expr) === "individual"); + const exprValues = {}; + // Perform one big query for all non-individual + const aggrRows = yield this.props.instanceCtx.database.query(queryAggrOptions, innerProps.contextVars, contexts_1.getFilteredContextVarValues(innerProps)); + if (aggrRows.length > 0) { + for (let i = 0; i < aggrExpressions.length; i++) { + exprValues[canonical_json_1.default(aggrExpressions[i])] = aggrRows[0]["e" + i]; } - else { - for (i = 0; i < aggrExpressions.length; i++) { - exprValues[canonical_json_1.default(aggrExpressions[i])] = null; - } + } + else { + for (let i = 0; i < aggrExpressions.length; i++) { + exprValues[canonical_json_1.default(aggrExpressions[i])] = null; } - _i = 0, individualExpressions_1 = individualExpressions; - _a.label = 7; - case 7: - if (!(_i < individualExpressions_1.length)) return [3 /*break*/, 10]; - individualExpression = individualExpressions_1[_i]; - queryIndividualOptions = this.createRowsetIndividualQueryOptions(table, variables, individualExpression); - return [4 /*yield*/, this.props.instanceCtx.database.query(queryIndividualOptions, innerProps.contextVars, contexts_1.getFilteredContextVarValues(innerProps))]; - case 8: - individualRows = _a.sent(); + } + // Perform individual queries for individual expressions + for (const individualExpression of individualExpressions) { + const queryIndividualOptions = this.createRowsetIndividualQueryOptions(table, variables, individualExpression); + const individualRows = yield this.props.instanceCtx.database.query(queryIndividualOptions, innerProps.contextVars, contexts_1.getFilteredContextVarValues(innerProps)); if (individualRows.length == 1) { exprValues[canonical_json_1.default(individualExpression)] = individualRows[0].value; } else { exprValues[canonical_json_1.default(individualExpression)] = null; } - _a.label = 9; - case 9: - _i++; - return [3 /*break*/, 7]; - case 10: - // Ignore if query options out of date - if (!lodash_1.default.isEqual(queryAggrOptions, this.createRowsetAggrQueryOptions(table, variables))) { - return [2 /*return*/]; - } - // Ignore if variable values out of date - if (!lodash_1.default.isEqual(variableValues, contexts_1.getFilteredContextVarValues(this.createInnerProps()))) { - return [2 /*return*/]; - } - // Ignore if unmounted - if (this.unmounted) { - return [2 /*return*/]; - } - // Save values - this.setState({ exprValues: exprValues }); - return [3 /*break*/, 12]; - case 11: - error_2 = _a.sent(); - this.setState({ error: error_2 }); - return [2 /*return*/]; - case 12: - this.setState({ refreshing: false, loading: false }); - return [2 /*return*/]; + } + // Ignore if query options out of date + if (!lodash_1.default.isEqual(queryAggrOptions, this.createRowsetAggrQueryOptions(table, variables))) { + return; + } + // Ignore if variable values out of date + if (!lodash_1.default.isEqual(variableValues, contexts_1.getFilteredContextVarValues(this.createInnerProps()))) { + return; + } + // Ignore if unmounted + if (this.unmounted) { + return; + } + // Save values + this.setState({ exprValues }); + } + catch (error) { + this.setState({ error }); + return; } - }); + } + this.setState({ refreshing: false, loading: false }); }); - }; + } /** Create props needed by inner component */ - ContextVarInjector.prototype.createInnerProps = function () { - var _a; - var _this = this; - var outer = this.props.instanceCtx; + createInnerProps() { + const outer = this.props.instanceCtx; // Get injected context variable value - var value = this.props.value; - var contextVars = outer.contextVars.concat(this.props.injectedContextVar); - var contextVarValues = __assign(__assign({}, outer.contextVarValues), (_a = {}, _a[this.props.injectedContextVar.id] = value, _a)); + let value = this.props.value; + const contextVars = outer.contextVars.concat(this.props.injectedContextVar); + const contextVarValues = Object.assign(Object.assign({}, outer.contextVarValues), { [this.props.injectedContextVar.id]: value }); // Create inner props - var innerProps = __assign(__assign({}, outer), { database: this.props.instanceCtx.database, contextVars: contextVars, contextVarValues: contextVarValues, getContextVarExprValue: function (contextVarId, expr) { + const innerProps = Object.assign(Object.assign({}, outer), { database: this.props.instanceCtx.database, contextVars: contextVars, contextVarValues: contextVarValues, getContextVarExprValue: (contextVarId, expr) => { // Null expression has null value if (!expr) { return null; @@ -354,39 +279,38 @@ var ContextVarInjector = /** @class */ (function (_super) { variableValues: blocks_1.createExprVariableValues(contextVars, contextVarValues) }).evaluateSync(expr); } - if (contextVarId === _this.props.injectedContextVar.id) { - return _this.state.exprValues[canonical_json_1.default(expr)]; + if (contextVarId === this.props.injectedContextVar.id) { + return this.state.exprValues[canonical_json_1.default(expr)]; } else { return outer.getContextVarExprValue(contextVarId, expr); } - }, setFilter: function (contextVarId, filter) { - if (contextVarId === _this.props.injectedContextVar.id) { + }, setFilter: (contextVarId, filter) => { + if (contextVarId === this.props.injectedContextVar.id) { // Remove existing with same id - var filters = _this.state.filters.filter(function (f) { return f.id !== filter.id; }); + const filters = this.state.filters.filter(f => f.id !== filter.id); filters.push(filter); - return _this.setState({ filters: filters }); + return this.setState({ filters }); } else { return outer.setFilter(contextVarId, filter); } - }, getFilters: function (contextVarId) { - if (contextVarId === _this.props.injectedContextVar.id) { - return _this.state.filters; + }, getFilters: (contextVarId) => { + if (contextVarId === this.props.injectedContextVar.id) { + return this.state.filters; } else { return outer.getFilters(contextVarId); } } }); return innerProps; - }; - ContextVarInjector.prototype.render = function () { + } + render() { if (this.state.error) { // TODO localize return React.createElement("div", { className: "alert alert-danger" }, "Error loading data"); } return this.props.children(this.createInnerProps(), this.state.loading, this.state.refreshing); - }; - return ContextVarInjector; -}(React.Component)); + } +} exports.default = ContextVarInjector; diff --git a/lib/widgets/ContextVarInjector.test.js b/lib/widgets/ContextVarInjector.test.js index f1c9081d..bb7e5a8d 100644 --- a/lib/widgets/ContextVarInjector.test.js +++ b/lib/widgets/ContextVarInjector.test.js @@ -22,17 +22,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var ContextVarInjector_1 = __importDefault(require("./ContextVarInjector")); -var enzyme_1 = require("enzyme"); -var React = __importStar(require("react")); -var mockDatabase_1 = __importDefault(require("../__fixtures__/mockDatabase")); -var schema_1 = __importDefault(require("../__fixtures__/schema")); -var database; -var outerRenderProps; -var schema = schema_1.default(); -beforeEach(function () { - var db = mockDatabase_1.default(); - db.query = jest.fn(function () { return Promise.resolve([{ e0: "abc" }]); }); +const ContextVarInjector_1 = __importDefault(require("./ContextVarInjector")); +const enzyme_1 = require("enzyme"); +const React = __importStar(require("react")); +const mockDatabase_1 = __importDefault(require("../__fixtures__/mockDatabase")); +const schema_1 = __importDefault(require("../__fixtures__/schema")); +let database; +let outerRenderProps; +const schema = schema_1.default(); +beforeEach(() => { + const db = mockDatabase_1.default(); + db.query = jest.fn(() => Promise.resolve([{ e0: "abc" }])); database = db; outerRenderProps = { locale: "en", @@ -50,38 +50,38 @@ beforeEach(function () { getFilters: jest.fn(), renderChildBlock: jest.fn(), createBlock: jest.fn(), - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => () => { }, + T: (str) => str }; }); -test("inner contains extra context vars", function () { - var contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; - var value = "1234"; - var contextVarExprs = [ +test("inner contains extra context vars", () => { + const contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; + const value = "1234"; + const contextVarExprs = [ { type: "field", table: "t1", column: "c1" } ]; - var innerRenderProps; - var x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, function (instanceCtx) { + let innerRenderProps; + const x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, (instanceCtx) => { innerRenderProps = instanceCtx; return React.createElement("div", null); }))); // Inner props should have new context variable expect(innerRenderProps.contextVars).toEqual([contextVar]); }); -test("exprs are computed for row variables", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; - var value = "1234"; - var contextVarExprs = [ +test("exprs are computed for row variables", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; + const value = "1234"; + const contextVarExprs = [ { type: "field", table: "t1", column: "c1" } ]; - var innerRenderProps; - var x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, function (instanceCtx) { + let innerRenderProps; + const x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, (instanceCtx) => { innerRenderProps = instanceCtx; return React.createElement("div", null); }))); // Query should have been made - var queryOptions = database.query.mock.calls[0][0]; - var expectedQueryOptions = { + const queryOptions = database.query.mock.calls[0][0]; + const expectedQueryOptions = { select: { e0: contextVarExprs[0] }, @@ -93,7 +93,7 @@ test("exprs are computed for row variables", function (done) { exprs: [{ type: "id", table: "t1" }, { type: "literal", valueType: "id", idTable: "t1", value: "1234" }] } }; - setImmediate(function () { + setImmediate(() => { // Should perform the query expect(queryOptions).toEqual(expectedQueryOptions); // Should get the value @@ -101,18 +101,18 @@ test("exprs are computed for row variables", function (done) { done(); }); }); -test("exprs are null for null row variables", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; - var value = null; - var contextVarExprs = [ +test("exprs are null for null row variables", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; + const value = null; + const contextVarExprs = [ { type: "field", table: "t1", column: "c1" } ]; - var innerRenderProps; - var x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, function (instanceCtx) { + let innerRenderProps; + const x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, (instanceCtx) => { innerRenderProps = instanceCtx; return React.createElement("div", null); }))); - setImmediate(function () { + setImmediate(() => { // Query should not have been made expect(database.query.mock.calls.length).toBe(0); // Should get the value as undefined @@ -120,21 +120,21 @@ test("exprs are null for null row variables", function (done) { done(); }); }); -test("exprs are computed for rowset variables, excluding non-aggregates", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; - var value = { type: "literal", valueType: "boolean", value: false }; - var contextVarExprs = [ +test("exprs are computed for rowset variables, excluding non-aggregates", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; + const value = { type: "literal", valueType: "boolean", value: false }; + const contextVarExprs = [ { type: "field", table: "t1", column: "text" }, { type: "op", table: "t1", op: "count", exprs: [] } ]; - var innerRenderProps; - var x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, function (instanceCtx) { + let innerRenderProps; + const x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, (instanceCtx) => { innerRenderProps = instanceCtx; return React.createElement("div", null); }))); // Query should have been made - var queryOptions = database.query.mock.calls[0][0]; - var expectedQueryOptions = { + const queryOptions = database.query.mock.calls[0][0]; + const expectedQueryOptions = { select: { e0: contextVarExprs[1] }, @@ -142,7 +142,7 @@ test("exprs are computed for rowset variables, excluding non-aggregates", functi where: value, limit: 1 }; - setImmediate(function () { + setImmediate(() => { // Should perform the query expect(queryOptions).toEqual(expectedQueryOptions); // Should get the value @@ -150,26 +150,26 @@ test("exprs are computed for rowset variables, excluding non-aggregates", functi done(); }); }); -test("filters are applied for rowset variables", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; - var value = { type: "literal", valueType: "boolean", value: false }; - var contextVarExprs = [ +test("filters are applied for rowset variables", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; + const value = { type: "literal", valueType: "boolean", value: false }; + const contextVarExprs = [ { type: "op", table: "t1", op: "count", exprs: [] } ]; - var initialFilters = [ + const initialFilters = [ { id: "f1", expr: { type: "field", table: "t1", column: "c2" } } ]; - var innerRenderProps; - var innerIsLoading = false; + let innerRenderProps; + let innerIsLoading = false; // Need mount as shallow rendering fails to call lifecycle componentDidUpdate - var x = enzyme_1.mount((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs, initialFilters: initialFilters }, function (instanceCtx, isLoading) { + const x = enzyme_1.mount((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs, initialFilters: initialFilters }, (instanceCtx, isLoading) => { innerRenderProps = instanceCtx; innerIsLoading = isLoading; return React.createElement("div", null); }))); // Query should have been made - var queryOptions = database.query.mock.calls[0][0]; - var expectedQueryOptions = { + const queryOptions = database.query.mock.calls[0][0]; + const expectedQueryOptions = { select: { e0: contextVarExprs[0] }, @@ -179,15 +179,15 @@ test("filters are applied for rowset variables", function (done) { }; // TODO test properly isLoading // expect(innerIsLoading).toBe(true) - setImmediate(function () { + setImmediate(() => { // Should perform the query expect(queryOptions).toEqual(expectedQueryOptions); expect(innerRenderProps.getFilters("cv1")).toEqual(initialFilters); // Should set filter (replacing with same id) - var newFilter = { id: "f1", expr: { type: "field", table: "t1", column: "c3" } }; + const newFilter = { id: "f1", expr: { type: "field", table: "t1", column: "c3" } }; innerRenderProps.setFilter("cv1", newFilter); - setTimeout(function () { - var expectedQueryOptions2 = { + setTimeout(() => { + const expectedQueryOptions2 = { select: { e0: contextVarExprs[0] }, @@ -197,32 +197,32 @@ test("filters are applied for rowset variables", function (done) { }; // Should perform the query expect(innerRenderProps.getFilters("cv1")).toEqual([newFilter]); - var queryOptions2 = database.query.mock.calls[1][0]; + const queryOptions2 = database.query.mock.calls[1][0]; expect(queryOptions2).toEqual(expectedQueryOptions2); done(); }, 10); }); }); -test("null filters are ignored for rowset variables", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; - var value = { type: "literal", valueType: "boolean", value: false }; - var contextVarExprs = [ +test("null filters are ignored for rowset variables", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; + const value = { type: "literal", valueType: "boolean", value: false }; + const contextVarExprs = [ { type: "op", table: "t1", op: "count", exprs: [] } ]; - var initialFilters = [ + const initialFilters = [ { id: "f1", expr: null } ]; - var innerRenderProps; - var innerIsLoading = false; + let innerRenderProps; + let innerIsLoading = false; // Need mount as shallow rendering fails to call lifecycle componentDidUpdate - var x = enzyme_1.mount((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs, initialFilters: initialFilters }, function (instanceCtx, isLoading) { + const x = enzyme_1.mount((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs, initialFilters: initialFilters }, (instanceCtx, isLoading) => { innerRenderProps = instanceCtx; innerIsLoading = isLoading; return React.createElement("div", null); }))); // Query should have been made - var queryOptions = database.query.mock.calls[0][0]; - var expectedQueryOptions = { + const queryOptions = database.query.mock.calls[0][0]; + const expectedQueryOptions = { select: { e0: contextVarExprs[0] }, @@ -232,15 +232,15 @@ test("null filters are ignored for rowset variables", function (done) { }; // TODO test properly isLoading // expect(innerIsLoading).toBe(true) - setImmediate(function () { + setImmediate(() => { // Should perform the query expect(queryOptions).toEqual(expectedQueryOptions); expect(innerRenderProps.getFilters("cv1")).toEqual(initialFilters); // Should set filter (replacing with same id) - var newFilter = { id: "f1", expr: { type: "field", table: "t1", column: "c3" } }; + const newFilter = { id: "f1", expr: { type: "field", table: "t1", column: "c3" } }; innerRenderProps.setFilter("cv1", newFilter); - setTimeout(function () { - var expectedQueryOptions2 = { + setTimeout(() => { + const expectedQueryOptions2 = { select: { e0: contextVarExprs[0] }, @@ -250,46 +250,46 @@ test("null filters are ignored for rowset variables", function (done) { }; // Should perform the query expect(innerRenderProps.getFilters("cv1")).toEqual([newFilter]); - var queryOptions2 = database.query.mock.calls[1][0]; + const queryOptions2 = database.query.mock.calls[1][0]; expect(queryOptions2).toEqual(expectedQueryOptions2); done(); }, 10); }); }); -test("filters are not applied for rowset variables to variable value", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; - var value = { type: "literal", valueType: "boolean", value: false }; - var contextVarExprs = [ +test("filters are not applied for rowset variables to variable value", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; + const value = { type: "literal", valueType: "boolean", value: false }; + const contextVarExprs = [ { type: "op", table: "t1", op: "count", exprs: [] } ]; - var initialFilters = [ + const initialFilters = [ { id: "f1", expr: { type: "field", table: "t1", column: "c2" } } ]; - var innerRenderProps; - var innerIsLoading = false; + let innerRenderProps; + let innerIsLoading = false; // Need mount as shallow rendering fails to call lifecycle componentDidUpdate - var x = enzyme_1.mount((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs, initialFilters: initialFilters }, function (instanceCtx, isLoading) { + const x = enzyme_1.mount((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs, initialFilters: initialFilters }, (instanceCtx, isLoading) => { innerRenderProps = instanceCtx; innerIsLoading = isLoading; return React.createElement("div", null); }))); - setImmediate(function () { + setImmediate(() => { expect(innerRenderProps.contextVarValues.cv1).toEqual(value); done(); }); }); -test("exprs are computed for null variable with variable-based expression", function (done) { - var contextVar = { id: "cv1", name: "cv1", type: "number" }; - var value = { type: "literal", valueType: "number", value: 1234 }; - var contextVarExprs = [ +test("exprs are computed for null variable with variable-based expression", (done) => { + const contextVar = { id: "cv1", name: "cv1", type: "number" }; + const value = { type: "literal", valueType: "number", value: 1234 }; + const contextVarExprs = [ { type: "op", op: "+", exprs: [{ type: "variable", variableId: "cv1" }, { type: "literal", valueType: "number", value: 1 }] } ]; - var innerRenderProps; - var x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, function (instanceCtx) { + let innerRenderProps; + const x = enzyme_1.shallow((React.createElement(ContextVarInjector_1.default, { instanceCtx: outerRenderProps, injectedContextVar: contextVar, value: value, contextVarExprs: contextVarExprs }, (instanceCtx) => { innerRenderProps = instanceCtx; return React.createElement("div", null); }))); - setImmediate(function () { + setImmediate(() => { // Should get the value expect(innerRenderProps.getContextVarExprValue(null, contextVarExprs[0])).toBe(1235); done(); diff --git a/lib/widgets/ContextVarsInjector.js b/lib/widgets/ContextVarsInjector.js index dcf1d280..c9892c65 100644 --- a/lib/widgets/ContextVarsInjector.js +++ b/lib/widgets/ContextVarsInjector.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -46,39 +22,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var ContextVarInjector_1 = __importDefault(require("./ContextVarInjector")); +const React = __importStar(require("react")); +const ContextVarInjector_1 = __importDefault(require("./ContextVarInjector")); /** Injects one or more context variables into the inner render instance props. * Holds state of the filters that are applied to rowset. * Computes values of expressions */ -var ContextVarsInjector = /** @class */ (function (_super) { - __extends(ContextVarsInjector, _super); - function ContextVarsInjector() { - return _super !== null && _super.apply(this, arguments) || this; - } - ContextVarsInjector.prototype.render = function () { - var _this = this; +class ContextVarsInjector extends React.Component { + render() { // Wrap once per child - var elem = this.props.children; - var allContextVars = this.props.instanceCtx.contextVars.concat(this.props.injectedContextVars); + let elem = this.props.children; + const allContextVars = this.props.instanceCtx.contextVars.concat(this.props.injectedContextVars); // Do in reverse order, as the inner most one is done first - var reverseInjectedContextVars = this.props.injectedContextVars.slice().reverse(); - var _loop_1 = function (contextVar) { - var innerBlock = this_1.props.innerBlock ? this_1.props.instanceCtx.createBlock(this_1.props.innerBlock) : null; + const reverseInjectedContextVars = this.props.injectedContextVars.slice().reverse(); + for (const contextVar of reverseInjectedContextVars) { + const innerBlock = this.props.innerBlock ? this.props.instanceCtx.createBlock(this.props.innerBlock) : null; // Get context var exprs - var contextVarExprs = innerBlock ? innerBlock.getSubtreeContextVarExprs(contextVar, __assign(__assign({}, this_1.props.instanceCtx), { contextVars: allContextVars })) : []; - var initialFilters = innerBlock ? innerBlock.getSubtreeInitialFilters(contextVar.id, __assign(__assign({}, this_1.props.instanceCtx), { contextVars: allContextVars })) : []; - var currentElem = elem; - elem = function (outerInstanceCtx, loading, refreshing) { return (React.createElement(ContextVarInjector_1.default, { injectedContextVar: contextVar, value: _this.props.injectedContextVarValues[contextVar.id], instanceCtx: outerInstanceCtx, initialFilters: initialFilters, contextVarExprs: contextVarExprs }, function (renderProps, innerLoading, innerRefreshing) { return currentElem(renderProps, innerLoading || loading, innerRefreshing || refreshing); })); }; - }; - var this_1 = this; - for (var _i = 0, reverseInjectedContextVars_1 = reverseInjectedContextVars; _i < reverseInjectedContextVars_1.length; _i++) { - var contextVar = reverseInjectedContextVars_1[_i]; - _loop_1(contextVar); + const contextVarExprs = innerBlock ? innerBlock.getSubtreeContextVarExprs(contextVar, Object.assign(Object.assign({}, this.props.instanceCtx), { contextVars: allContextVars })) : []; + const initialFilters = innerBlock ? innerBlock.getSubtreeInitialFilters(contextVar.id, Object.assign(Object.assign({}, this.props.instanceCtx), { contextVars: allContextVars })) : []; + const currentElem = elem; + elem = (outerInstanceCtx, loading, refreshing) => (React.createElement(ContextVarInjector_1.default, { injectedContextVar: contextVar, value: this.props.injectedContextVarValues[contextVar.id], instanceCtx: outerInstanceCtx, initialFilters: initialFilters, contextVarExprs: contextVarExprs }, (renderProps, innerLoading, innerRefreshing) => currentElem(renderProps, innerLoading || loading, innerRefreshing || refreshing))); } return elem(this.props.instanceCtx, false, false); - }; - return ContextVarsInjector; -}(React.Component)); + } +} exports.default = ContextVarsInjector; diff --git a/lib/widgets/LeafBlock.js b/lib/widgets/LeafBlock.js index f85537d0..9316bf36 100644 --- a/lib/widgets/LeafBlock.js +++ b/lib/widgets/LeafBlock.js @@ -1,27 +1,9 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); Object.defineProperty(exports, "__esModule", { value: true }); -var blocks_1 = require("./blocks"); +const blocks_1 = require("./blocks"); // Block which doesn't contain any other blocks -var LeafBlock = /** @class */ (function (_super) { - __extends(LeafBlock, _super); - function LeafBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - LeafBlock.prototype.getChildren = function () { return []; }; - LeafBlock.prototype.processChildren = function (action) { return this.blockDef; }; - return LeafBlock; -}(blocks_1.Block)); +class LeafBlock extends blocks_1.Block { + getChildren() { return []; } + processChildren(action) { return this.blockDef; } +} exports.default = LeafBlock; diff --git a/lib/widgets/ListEditor.js b/lib/widgets/ListEditor.js index 5d35beac..841e00f0 100644 --- a/lib/widgets/ListEditor.js +++ b/lib/widgets/ListEditor.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -32,34 +19,30 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); +const React = __importStar(require("react")); /** Allows editing of a list and removing of items */ -var ListEditor = /** @class */ (function (_super) { - __extends(ListEditor, _super); - function ListEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleRemove = function (index) { - var items = _this.props.items.slice(); +class ListEditor extends React.Component { + constructor() { + super(...arguments); + this.handleRemove = (index) => { + const items = this.props.items.slice(); items.splice(index, 1); - _this.props.onItemsChange(items); + this.props.onItemsChange(items); }; - _this.handleItemChange = function (index, item) { - var items = _this.props.items.slice(); + this.handleItemChange = (index, item) => { + const items = this.props.items.slice(); items[index] = item; - _this.props.onItemsChange(items); + this.props.onItemsChange(items); }; - return _this; } - ListEditor.prototype.renderItem = function (item, index) { + renderItem(item, index) { return (React.createElement("li", { className: "list-group-item", key: index }, React.createElement("span", { style: { float: "right" }, onClick: this.handleRemove.bind(null, index) }, React.createElement("i", { className: "fa fa-remove" })), this.props.children(item, this.handleItemChange.bind(null, index), index))); - }; - ListEditor.prototype.render = function () { - var _this = this; - return (React.createElement("ul", { className: "list-group" }, this.props.items.map(function (item, index) { return _this.renderItem(item, index); }))); - }; - return ListEditor; -}(React.Component)); + } + render() { + return (React.createElement("ul", { className: "list-group" }, this.props.items.map((item, index) => this.renderItem(item, index)))); + } +} exports.default = ListEditor; diff --git a/lib/widgets/actions.js b/lib/widgets/actions.js index f4305ba0..87172c2c 100644 --- a/lib/widgets/actions.js +++ b/lib/widgets/actions.js @@ -7,12 +7,11 @@ exports.Action = void 0; * them as needed using evalContextVarExpr themselves. * */ -var Action = /** @class */ (function () { - function Action(actionDef) { +class Action { + constructor(actionDef) { this.actionDef = actionDef; } /** Render an optional property editor for the action. This may use bootstrap */ - Action.prototype.renderEditor = function (props) { return null; }; - return Action; -}()); + renderEditor(props) { return null; } +} exports.Action = Action; diff --git a/lib/widgets/actions/addRow.js b/lib/widgets/actions/addRow.js index d21f5505..c7f0521b 100644 --- a/lib/widgets/actions/addRow.js +++ b/lib/widgets/actions/addRow.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -40,129 +27,62 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 }; - } -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.AddRowAction = void 0; -var React = __importStar(require("react")); -var actions_1 = require("../actions"); -var mwater_expressions_1 = require("mwater-expressions"); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var columnValues_1 = require("../columnValues"); -var evalContextVarExpr_1 = require("../evalContextVarExpr"); -var AddRowAction = /** @class */ (function (_super) { - __extends(AddRowAction, _super); - function AddRowAction() { - return _super !== null && _super.apply(this, arguments) || this; - } - AddRowAction.prototype.performAction = function (instanceCtx) { - return __awaiter(this, void 0, void 0, function () { - var row, _loop_1, this_1, _i, _a, columnId, txn; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - row = {}; - _loop_1 = function (columnId) { - var contextVarExpr, contextVar, _a, _b; - return __generator(this, function (_c) { - switch (_c.label) { - case 0: - contextVarExpr = this_1.actionDef.columnValues[columnId]; - contextVar = contextVarExpr.contextVarId ? instanceCtx.contextVars.find(function (cv) { return cv.id == contextVarExpr.contextVarId; }) : null; - _a = row; - _b = columnId; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, - ctx: instanceCtx, - expr: contextVarExpr.expr - })]; - case 1: - _a[_b] = _c.sent(); - return [2 /*return*/]; - } - }); - }; - this_1 = this; - _i = 0, _a = Object.keys(this.actionDef.columnValues); - _b.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 4]; - columnId = _a[_i]; - return [5 /*yield**/, _loop_1(columnId)]; - case 2: - _b.sent(); - _b.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: - txn = instanceCtx.database.transaction(); - return [4 /*yield*/, txn.addRow(this.actionDef.table, row)]; - case 5: - _b.sent(); - return [4 /*yield*/, txn.commit()]; - case 6: - _b.sent(); - return [2 /*return*/]; - } - }); +const React = __importStar(require("react")); +const actions_1 = require("../actions"); +const mwater_expressions_1 = require("mwater-expressions"); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const columnValues_1 = require("../columnValues"); +const evalContextVarExpr_1 = require("../evalContextVarExpr"); +class AddRowAction extends actions_1.Action { + performAction(instanceCtx) { + return __awaiter(this, void 0, void 0, function* () { + // Create row to insert + const row = {}; + for (const columnId of Object.keys(this.actionDef.columnValues)) { + const contextVarExpr = this.actionDef.columnValues[columnId]; + const contextVar = contextVarExpr.contextVarId ? instanceCtx.contextVars.find(cv => cv.id == contextVarExpr.contextVarId) : null; + row[columnId] = yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar, + contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, + ctx: instanceCtx, + expr: contextVarExpr.expr + }); + } + const txn = instanceCtx.database.transaction(); + yield txn.addRow(this.actionDef.table, row); + yield txn.commit(); }); - }; - AddRowAction.prototype.validate = function (designCtx) { + } + validate(designCtx) { // Check that table is present if (!this.actionDef.table || !designCtx.schema.getTable(this.actionDef.table)) { return "Table required"; } // Check each column value - for (var _i = 0, _a = Object.keys(this.actionDef.columnValues); _i < _a.length; _i++) { - var columnId = _a[_i]; - var error = this.validateColumnValue(designCtx, columnId); + for (const columnId of Object.keys(this.actionDef.columnValues)) { + const error = this.validateColumnValue(designCtx, columnId); if (error) { return error; } } return null; - }; - AddRowAction.prototype.validateColumnValue = function (designCtx, columnId) { + } + validateColumnValue(designCtx, columnId) { // Check that column exists - var column = designCtx.schema.getColumn(this.actionDef.table, columnId); + const column = designCtx.schema.getColumn(this.actionDef.table, columnId); if (!column) { return "Column not found"; } - var exprValidator = new mwater_expressions_1.ExprValidator(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); - var exprUtils = new mwater_expressions_1.ExprUtils(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); + const exprValidator = new mwater_expressions_1.ExprValidator(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); + const exprUtils = new mwater_expressions_1.ExprUtils(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); // Check context var - var contextVarExpr = this.actionDef.columnValues[columnId]; - var contextVar; + const contextVarExpr = this.actionDef.columnValues[columnId]; + let contextVar; if (contextVarExpr.contextVarId) { - contextVar = designCtx.contextVars.find(function (cv) { return cv.id === contextVarExpr.contextVarId; }); + contextVar = designCtx.contextVars.find(cv => cv.id === contextVarExpr.contextVarId); if (!contextVar || !contextVar.table) { return "Context variable not found"; } @@ -170,16 +90,16 @@ var AddRowAction = /** @class */ (function (_super) { else { contextVar = undefined; // Must be literal - var aggrStatus = exprUtils.getExprAggrStatus(contextVarExpr.expr); + const aggrStatus = exprUtils.getExprAggrStatus(contextVarExpr.expr); if (aggrStatus && aggrStatus !== "literal") { return "Literal value required"; } } // Override for special case of allowing to set joins - var idTable = column.type == "join" ? column.join.toTable : column.idTable; - var type = column.type == "join" ? "id" : column.type; + const idTable = column.type == "join" ? column.join.toTable : column.idTable; + const type = column.type == "join" ? "id" : column.type; // Validate expr - var error; + let error; error = exprValidator.validateExpr(contextVarExpr.expr, { table: contextVar ? contextVar.table : undefined, types: [type], @@ -190,22 +110,16 @@ var AddRowAction = /** @class */ (function (_super) { return error; } return null; - }; - AddRowAction.prototype.renderEditor = function (props) { - var _this = this; - var onChange = props.onChange; + } + renderEditor(props) { + const onChange = props.onChange; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Table" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "table" }, function (value, onChange) { - return React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, locale: props.locale, value: value, onChange: onChange }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "table" }, (value, onChange) => React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, locale: props.locale, value: value, onChange: onChange }))), this.actionDef.table ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Column Values" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "columnValues" }, function (value, onChange) { - return React.createElement(columnValues_1.ColumnValuesEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: _this.actionDef.table, contextVars: props.contextVars, locale: props.locale }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "columnValues" }, (value, onChange) => React.createElement(columnValues_1.ColumnValuesEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: this.actionDef.table, contextVars: props.contextVars, locale: props.locale }))) : null)); - }; - return AddRowAction; -}(actions_1.Action)); + } +} exports.AddRowAction = AddRowAction; diff --git a/lib/widgets/actions/addRow.test.js b/lib/widgets/actions/addRow.test.js index fa4511f3..ec2787e0 100644 --- a/lib/widgets/actions/addRow.test.js +++ b/lib/widgets/actions/addRow.test.js @@ -1,15 +1,4 @@ "use strict"; -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) { @@ -19,99 +8,54 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var addRow_1 = require("./addRow"); -var VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); -var Database_1 = require("../../database/Database"); -var schema_1 = __importDefault(require("../../__fixtures__/schema")); -var mockInstanceCtx_1 = __importDefault(require("../../__fixtures__/mockInstanceCtx")); -test("performs non-literal action", function () { return __awaiter(void 0, void 0, void 0, function () { - var ad, schema, database, action, instanceCtx; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - ad = { - type: "addRow", - table: "t1", - columnValues: { - "number": { - contextVarId: null, - expr: { type: "literal", valueType: "number", value: 123 } - } - } - }; - schema = schema_1.default(); - database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); - action = new addRow_1.AddRowAction(ad); - instanceCtx = __assign(__assign({}, mockInstanceCtx_1.default()), { database: database, contextVars: [{ id: "cv1", table: "t2", name: "Cv1", type: "row" }], contextVarValues: { cv1: "123" }, getContextVarExprValue: function () { throw new Error("Not implemented"); } }); - return [4 /*yield*/, action.performAction(instanceCtx)]; - case 1: - _a.sent(); - expect(database.mutations.length).toBe(1); - expect(database.mutations[0].values).toEqual({ - number: 123 - }); - return [2 /*return*/]; +const addRow_1 = require("./addRow"); +const VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); +const Database_1 = require("../../database/Database"); +const schema_1 = __importDefault(require("../../__fixtures__/schema")); +const mockInstanceCtx_1 = __importDefault(require("../../__fixtures__/mockInstanceCtx")); +test("performs non-literal action", () => __awaiter(void 0, void 0, void 0, function* () { + const ad = { + type: "addRow", + table: "t1", + columnValues: { + "number": { + contextVarId: null, + expr: { type: "literal", valueType: "number", value: 123 } + } } + }; + const schema = schema_1.default(); + const database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); + const action = new addRow_1.AddRowAction(ad); + const instanceCtx = Object.assign(Object.assign({}, mockInstanceCtx_1.default()), { database: database, contextVars: [{ id: "cv1", table: "t2", name: "Cv1", type: "row" }], contextVarValues: { cv1: "123" }, getContextVarExprValue: () => { throw new Error("Not implemented"); } }); + yield action.performAction(instanceCtx); + expect(database.mutations.length).toBe(1); + expect(database.mutations[0].values).toEqual({ + number: 123 }); -}); }); -test("performs literal action", function () { return __awaiter(void 0, void 0, void 0, function () { - var ad, schema, database, instanceCtx, action; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - ad = { - type: "addRow", - table: "t1", - columnValues: { - "number": { - contextVarId: null, - expr: { type: "literal", valueType: "number", value: 123 } - } - } - }; - schema = schema_1.default(); - database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); - instanceCtx = __assign(__assign({}, mockInstanceCtx_1.default()), { database: database, contextVars: [{ id: "cv1", table: "t2", name: "Cv1", type: "row" }], contextVarValues: { cv1: "123" }, getContextVarExprValue: function () { throw new Error("Not implemented"); }, getFilters: function () { return []; } }); - action = new addRow_1.AddRowAction(ad); - return [4 /*yield*/, action.performAction(instanceCtx)]; - case 1: - _a.sent(); - expect(database.mutations.length).toBe(1); - expect(database.mutations[0].values).toEqual({ - number: 123 - }); - return [2 /*return*/]; +})); +test("performs literal action", () => __awaiter(void 0, void 0, void 0, function* () { + const ad = { + type: "addRow", + table: "t1", + columnValues: { + "number": { + contextVarId: null, + expr: { type: "literal", valueType: "number", value: 123 } + } } + }; + const schema = schema_1.default(); + const database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); + const instanceCtx = Object.assign(Object.assign({}, mockInstanceCtx_1.default()), { database: database, contextVars: [{ id: "cv1", table: "t2", name: "Cv1", type: "row" }], contextVarValues: { cv1: "123" }, getContextVarExprValue: () => { throw new Error("Not implemented"); }, getFilters: () => [] }); + const action = new addRow_1.AddRowAction(ad); + yield action.performAction(instanceCtx); + expect(database.mutations.length).toBe(1); + expect(database.mutations[0].values).toEqual({ + number: 123 }); -}); }); +})); diff --git a/lib/widgets/actions/browserBack.js b/lib/widgets/actions/browserBack.js index ac64294d..1fbf6739 100644 --- a/lib/widgets/actions/browserBack.js +++ b/lib/widgets/actions/browserBack.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); 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) { @@ -21,53 +8,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 }; - } -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.BrowserBackAction = void 0; -var actions_1 = require("../actions"); +const actions_1 = require("../actions"); /** Goes back in browser history */ -var BrowserBackAction = /** @class */ (function (_super) { - __extends(BrowserBackAction, _super); - function BrowserBackAction() { - return _super !== null && _super.apply(this, arguments) || this; - } - BrowserBackAction.prototype.validate = function (designCtx) { +class BrowserBackAction extends actions_1.Action { + validate(designCtx) { return null; - }; - BrowserBackAction.prototype.performAction = function (instanceCtx) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - window.history.back(); - return [2 /*return*/]; - }); + } + performAction(instanceCtx) { + return __awaiter(this, void 0, void 0, function* () { + window.history.back(); }); - }; - return BrowserBackAction; -}(actions_1.Action)); + } +} exports.BrowserBackAction = BrowserBackAction; diff --git a/lib/widgets/actions/gotoUrl.js b/lib/widgets/actions/gotoUrl.js index 280dc8cb..947c83df 100644 --- a/lib/widgets/actions/gotoUrl.js +++ b/lib/widgets/actions/gotoUrl.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); 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) { @@ -21,57 +8,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GotoUrlAction = void 0; -var react_1 = __importDefault(require("react")); -var actions_1 = require("../actions"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var embeddedExprs_1 = require("../../embeddedExprs"); -var evalContextVarExpr_1 = require("../evalContextVarExpr"); +const react_1 = __importDefault(require("react")); +const actions_1 = require("../actions"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const embeddedExprs_1 = require("../../embeddedExprs"); +const evalContextVarExpr_1 = require("../evalContextVarExpr"); /** Opens a URL optionally in a new tab */ -var GotoUrlAction = /** @class */ (function (_super) { - __extends(GotoUrlAction, _super); - function GotoUrlAction() { - return _super !== null && _super.apply(this, arguments) || this; - } - GotoUrlAction.prototype.validate = function (designCtx) { +class GotoUrlAction extends actions_1.Action { + validate(designCtx) { // Check that url is present if (!this.actionDef.url) { return "URL required"; } // Validate expressions - var err = embeddedExprs_1.validateEmbeddedExprs({ + const err = embeddedExprs_1.validateEmbeddedExprs({ embeddedExprs: this.actionDef.urlEmbeddedExprs || [], schema: designCtx.schema, contextVars: designCtx.contextVars @@ -80,74 +36,42 @@ var GotoUrlAction = /** @class */ (function (_super) { return err; } return null; - }; - GotoUrlAction.prototype.renderEditor = function (props) { - var onChange = props.onChange; + } + renderEditor(props) { + const onChange = props.onChange; return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "URL" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "url" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "url" }, (value, onChange) => react_1.default.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "URL embedded expressions", help: "Reference in text as {0}, {1}, etc." }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "urlEmbeddedExprs" }, function (value, onChange) { return (react_1.default.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })); })), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "newTab" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Open in new tab"); }))); - }; - GotoUrlAction.prototype.performAction = function (instanceCtx) { - return __awaiter(this, void 0, void 0, function () { - var url, exprValues, _loop_1, _i, _a, ee; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - url = this.actionDef.url; - exprValues = []; - _loop_1 = function (ee) { - var contextVar, _a, _b; - return __generator(this, function (_c) { - switch (_c.label) { - case 0: - contextVar = ee.contextVarId ? instanceCtx.contextVars.find(function (cv) { return cv.id == ee.contextVarId; }) : null; - _b = (_a = exprValues).push; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, - ctx: instanceCtx, - expr: ee.expr - })]; - case 1: - _b.apply(_a, [_c.sent()]); - return [2 /*return*/]; - } - }); - }; - _i = 0, _a = this.actionDef.urlEmbeddedExprs || []; - _b.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 4]; - ee = _a[_i]; - return [5 /*yield**/, _loop_1(ee)]; - case 2: - _b.sent(); - _b.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: - // Format and replace - url = embeddedExprs_1.formatEmbeddedExprString({ - text: url, - embeddedExprs: this.actionDef.urlEmbeddedExprs || [], - exprValues: exprValues, - schema: instanceCtx.schema, - contextVars: instanceCtx.contextVars, - locale: instanceCtx.locale, - formatLocale: instanceCtx.formatLocale - }); - window.open(url, this.actionDef.newTab ? "_blank" : "_self"); - return [2 /*return*/]; - } + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "urlEmbeddedExprs" }, (value, onChange) => (react_1.default.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })))), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "newTab" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Open in new tab")))); + } + performAction(instanceCtx) { + return __awaiter(this, void 0, void 0, function* () { + let url = this.actionDef.url; + // Get any embedded expression values + const exprValues = []; + for (const ee of this.actionDef.urlEmbeddedExprs || []) { + const contextVar = ee.contextVarId ? instanceCtx.contextVars.find(cv => cv.id == ee.contextVarId) : null; + exprValues.push(yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar, + contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, + ctx: instanceCtx, + expr: ee.expr + })); + } + // Format and replace + url = embeddedExprs_1.formatEmbeddedExprString({ + text: url, + embeddedExprs: this.actionDef.urlEmbeddedExprs || [], + exprValues: exprValues, + schema: instanceCtx.schema, + contextVars: instanceCtx.contextVars, + locale: instanceCtx.locale, + formatLocale: instanceCtx.formatLocale }); + window.open(url, this.actionDef.newTab ? "_blank" : "_self"); }); - }; - return GotoUrlAction; -}(actions_1.Action)); + } +} exports.GotoUrlAction = GotoUrlAction; diff --git a/lib/widgets/actions/openPage.js b/lib/widgets/actions/openPage.js index a6ddc93d..9dee400e 100644 --- a/lib/widgets/actions/openPage.js +++ b/lib/widgets/actions/openPage.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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) { @@ -32,90 +8,60 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenPageAction = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importDefault(require("react")); -var actions_1 = require("../actions"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var immer_1 = __importDefault(require("immer")); -var mwater_expressions_1 = require("mwater-expressions"); -var embeddedExprs_1 = require("../../embeddedExprs"); -var blocks_1 = require("../blocks"); -var localization_1 = require("../localization"); -var evalContextVarExpr_1 = require("../evalContextVarExpr"); -var contextVarValues_1 = require("../../contextVarValues"); -var OpenPageAction = /** @class */ (function (_super) { - __extends(OpenPageAction, _super); - function OpenPageAction() { - return _super !== null && _super.apply(this, arguments) || this; - } - OpenPageAction.prototype.validate = function (designCtx) { +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importDefault(require("react")); +const actions_1 = require("../actions"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const immer_1 = __importDefault(require("immer")); +const mwater_expressions_1 = require("mwater-expressions"); +const embeddedExprs_1 = require("../../embeddedExprs"); +const blocks_1 = require("../blocks"); +const localization_1 = require("../localization"); +const evalContextVarExpr_1 = require("../evalContextVarExpr"); +const contextVarValues_1 = require("../../contextVarValues"); +class OpenPageAction extends actions_1.Action { + validate(designCtx) { // Find widget if (!this.actionDef.widgetId) { return "Widget required"; } // Ensure that widget exists - var widget = designCtx.widgetLibrary.widgets[this.actionDef.widgetId]; + const widget = designCtx.widgetLibrary.widgets[this.actionDef.widgetId]; if (!widget) { return "Invalid widget"; } - var _loop_1 = function (widgetCV) { + // Ensure that all context variables are correctly mapped + for (const widgetCV of widget.contextVars) { // Don't allow unmapped variables - if (!this_1.actionDef.contextVarValues[widgetCV.id]) { - return { value: "Missing variable mapping" }; + if (!this.actionDef.contextVarValues[widgetCV.id]) { + return "Missing variable mapping"; } // Ensure that mapping is to available context var - var contextVarValue = this_1.actionDef.contextVarValues[widgetCV.id]; + const contextVarValue = this.actionDef.contextVarValues[widgetCV.id]; if (contextVarValue.type == "ref") { - var srcCV = designCtx.contextVars.find(function (cv) { return cv.id === contextVarValue.contextVarId; }); + const srcCV = designCtx.contextVars.find(cv => cv.id === contextVarValue.contextVarId); if (!srcCV || !areContextVarCompatible(srcCV, widgetCV)) { - return { value: "Invalid context variable" }; + return "Invalid context variable"; } } else if (contextVarValue.type == "literal") { - var error = contextVarValues_1.validateContextVarValue(designCtx.schema, widgetCV, designCtx.contextVars, contextVarValue.value); + const error = contextVarValues_1.validateContextVarValue(designCtx.schema, widgetCV, designCtx.contextVars, contextVarValue.value); if (error) { - return { value: error }; + return error; } } else if (contextVarValue.type == "contextVarExpr") { // Not for rowset type if (widgetCV.type == "rowset") { - return { value: "Not available for rowsets" }; + return "Not available for rowsets"; } - var error = blocks_1.validateContextVarExpr({ + const error = blocks_1.validateContextVarExpr({ contextVarId: contextVarValue.contextVarId, contextVars: designCtx.contextVars, expr: contextVarValue.expr, @@ -124,20 +70,12 @@ var OpenPageAction = /** @class */ (function (_super) { types: widgetCV.type == "row" ? ["id"] : [widgetCV.type] }); if (error) { - return { value: error }; + return error; } } - }; - var this_1 = this; - // Ensure that all context variables are correctly mapped - for (var _i = 0, _a = widget.contextVars; _i < _a.length; _i++) { - var widgetCV = _a[_i]; - var state_1 = _loop_1(widgetCV); - if (typeof state_1 === "object") - return state_1.value; } // Validate expressions - var err = embeddedExprs_1.validateEmbeddedExprs({ + const err = embeddedExprs_1.validateEmbeddedExprs({ embeddedExprs: this.actionDef.titleEmbeddedExprs || [], schema: designCtx.schema, contextVars: designCtx.contextVars @@ -146,171 +84,118 @@ var OpenPageAction = /** @class */ (function (_super) { return err; } return null; - }; - OpenPageAction.prototype.performAction = function (instanceCtx) { - return __awaiter(this, void 0, void 0, function () { - var contextVarValues, widget, _loop_2, this_2, _i, _a, pageCV, _b, _c, globalContextVar, title, exprValues, _loop_3, _d, _e, ee, page; - return __generator(this, function (_f) { - switch (_f.label) { - case 0: - contextVarValues = {}; - widget = instanceCtx.widgetLibrary.widgets[this.actionDef.widgetId]; - _loop_2 = function (pageCV) { - var pageCVId, contextVarValue, outerCV, outerCVValue, widgetCV, contextVar, value; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - pageCVId = pageCV.id; - contextVarValue = this_2.actionDef.contextVarValues[pageCVId]; - if (!(contextVarValue.type == "ref")) return [3 /*break*/, 1]; - outerCV = instanceCtx.contextVars.find(function (cv) { return cv.id == contextVarValue.contextVarId; }); - if (!outerCV) { - throw new Error("Outer context variable not found"); - } - outerCVValue = instanceCtx.contextVarValues[outerCV.id]; - // Add filters if rowset - if (outerCV.type == "rowset") { - outerCVValue = { - type: "op", - op: "and", - table: outerCV.table, - exprs: lodash_1.default.compact([outerCVValue].concat(lodash_1.default.map(instanceCtx.getFilters(outerCV.id), function (f) { return f.expr; }))) - }; - } - // Inline variables used in rowsets as they may depend on context variables that aren't present in new page - if (outerCV.type == "rowset") { - outerCVValue = new mwater_expressions_1.ExprUtils(instanceCtx.schema, blocks_1.createExprVariables(instanceCtx.contextVars)).inlineVariableValues(outerCVValue, blocks_1.createExprVariableValues(instanceCtx.contextVars, instanceCtx.contextVarValues)); - } - contextVarValues[pageCVId] = outerCVValue; - return [3 /*break*/, 5]; - case 1: - if (!(contextVarValue.type == "null")) return [3 /*break*/, 2]; - contextVarValues[pageCVId] = null; - return [3 /*break*/, 5]; - case 2: - if (!(contextVarValue.type == "literal")) return [3 /*break*/, 3]; - contextVarValues[pageCVId] = contextVarValue.value; - return [3 /*break*/, 5]; - case 3: - if (!(contextVarValue.type == "contextVarExpr")) return [3 /*break*/, 5]; - widgetCV = widget.contextVars.find(function (cv) { return cv.id == pageCVId; }); - contextVar = instanceCtx.contextVars.find(function (cv) { return cv.id == contextVarValue.contextVarId; }); - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, - ctx: instanceCtx, - expr: contextVarValue.expr - }) - // Wrap in literal expression if not row - ]; - case 4: - value = _a.sent(); - // Wrap in literal expression if not row - contextVarValues[pageCVId] = widgetCV.type == "row" ? value : { type: "literal", valueType: widgetCV.type, idTable: widgetCV.idTable, value: value }; - _a.label = 5; - case 5: return [2 /*return*/]; - } - }); - }; - this_2 = this; - _i = 0, _a = widget.contextVars; - _f.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 4]; - pageCV = _a[_i]; - return [5 /*yield**/, _loop_2(pageCV)]; - case 2: - _f.sent(); - _f.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: - // Include global context variables - for (_b = 0, _c = instanceCtx.globalContextVars || []; _b < _c.length; _b++) { - globalContextVar = _c[_b]; - contextVarValues[globalContextVar.id] = instanceCtx.contextVarValues[globalContextVar.id]; - } - title = localization_1.localize(this.actionDef.title, instanceCtx.locale); - if (!title) return [3 /*break*/, 9]; - exprValues = []; - _loop_3 = function (ee) { - var contextVar, _a, _b; - return __generator(this, function (_c) { - switch (_c.label) { - case 0: - contextVar = ee.contextVarId ? instanceCtx.contextVars.find(function (cv) { return cv.id == ee.contextVarId; }) : null; - _b = (_a = exprValues).push; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, - ctx: instanceCtx, - expr: ee.expr - })]; - case 1: - _b.apply(_a, [_c.sent()]); - return [2 /*return*/]; - } - }); - }; - _d = 0, _e = this.actionDef.titleEmbeddedExprs || []; - _f.label = 5; - case 5: - if (!(_d < _e.length)) return [3 /*break*/, 8]; - ee = _e[_d]; - return [5 /*yield**/, _loop_3(ee)]; - case 6: - _f.sent(); - _f.label = 7; - case 7: - _d++; - return [3 /*break*/, 5]; - case 8: - // Format and replace - title = embeddedExprs_1.formatEmbeddedExprString({ - text: title, - embeddedExprs: this.actionDef.titleEmbeddedExprs || [], - exprValues: exprValues, - schema: instanceCtx.schema, - contextVars: instanceCtx.contextVars, - locale: instanceCtx.locale, - formatLocale: instanceCtx.formatLocale - }); - _f.label = 9; - case 9: - page = { - type: this.actionDef.pageType, - modalSize: this.actionDef.modalSize || "large", - database: instanceCtx.database, - widgetId: this.actionDef.widgetId, - contextVarValues: contextVarValues, - title: title + } + performAction(instanceCtx) { + return __awaiter(this, void 0, void 0, function* () { + const contextVarValues = {}; + const widget = instanceCtx.widgetLibrary.widgets[this.actionDef.widgetId]; + // Perform mappings of context vars + for (const pageCV of widget.contextVars) { + const pageCVId = pageCV.id; + const contextVarValue = this.actionDef.contextVarValues[pageCVId]; + if (contextVarValue.type == "ref") { + // Look up outer context variable + const outerCV = instanceCtx.contextVars.find(cv => cv.id == contextVarValue.contextVarId); + if (!outerCV) { + throw new Error("Outer context variable not found"); + } + // Get value + let outerCVValue = instanceCtx.contextVarValues[outerCV.id]; + // Add filters if rowset + if (outerCV.type == "rowset") { + outerCVValue = { + type: "op", + op: "and", + table: outerCV.table, + exprs: lodash_1.default.compact([outerCVValue].concat(lodash_1.default.map(instanceCtx.getFilters(outerCV.id), f => f.expr))) }; - if (this.actionDef.replacePage) { - instanceCtx.pageStack.replacePage(page); - } - else { - instanceCtx.pageStack.openPage(page); - } - return [2 /*return*/]; + } + // Inline variables used in rowsets as they may depend on context variables that aren't present in new page + if (outerCV.type == "rowset") { + outerCVValue = new mwater_expressions_1.ExprUtils(instanceCtx.schema, blocks_1.createExprVariables(instanceCtx.contextVars)).inlineVariableValues(outerCVValue, blocks_1.createExprVariableValues(instanceCtx.contextVars, instanceCtx.contextVarValues)); + } + contextVarValues[pageCVId] = outerCVValue; } - }); + else if (contextVarValue.type == "null") { + contextVarValues[pageCVId] = null; + } + else if (contextVarValue.type == "literal") { + contextVarValues[pageCVId] = contextVarValue.value; + } + else if (contextVarValue.type == "contextVarExpr") { + // Get widget context variable + const widgetCV = widget.contextVars.find(cv => cv.id == pageCVId); + // Evaluate value + const contextVar = instanceCtx.contextVars.find(cv => cv.id == contextVarValue.contextVarId); + const value = yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar: contextVar, + contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, + ctx: instanceCtx, + expr: contextVarValue.expr + }); + // Wrap in literal expression if not row + contextVarValues[pageCVId] = widgetCV.type == "row" ? value : { type: "literal", valueType: widgetCV.type, idTable: widgetCV.idTable, value }; + } + } + // Include global context variables + for (const globalContextVar of instanceCtx.globalContextVars || []) { + contextVarValues[globalContextVar.id] = instanceCtx.contextVarValues[globalContextVar.id]; + } + // Get title + let title = localization_1.localize(this.actionDef.title, instanceCtx.locale); + if (title) { + // Get any embedded expression values + const exprValues = []; + for (const ee of this.actionDef.titleEmbeddedExprs || []) { + const contextVar = ee.contextVarId ? instanceCtx.contextVars.find(cv => cv.id == ee.contextVarId) : null; + exprValues.push(yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar, + contextVarValue: contextVar ? instanceCtx.contextVarValues[contextVar.id] : null, + ctx: instanceCtx, + expr: ee.expr + })); + } + // Format and replace + title = embeddedExprs_1.formatEmbeddedExprString({ + text: title, + embeddedExprs: this.actionDef.titleEmbeddedExprs || [], + exprValues: exprValues, + schema: instanceCtx.schema, + contextVars: instanceCtx.contextVars, + locale: instanceCtx.locale, + formatLocale: instanceCtx.formatLocale + }); + } + const page = { + type: this.actionDef.pageType, + modalSize: this.actionDef.modalSize || "large", + database: instanceCtx.database, + widgetId: this.actionDef.widgetId, + contextVarValues: contextVarValues, + title: title + }; + if (this.actionDef.replacePage) { + instanceCtx.pageStack.replacePage(page); + } + else { + instanceCtx.pageStack.openPage(page); + } }); - }; + } /** Render an optional property editor for the action. This may use bootstrap */ - OpenPageAction.prototype.renderEditor = function (props) { + renderEditor(props) { // Create widget options - var widgetOptions = lodash_1.default.sortByAll(Object.values(props.widgetLibrary.widgets), "group", "name").map(function (w) { return ({ label: (w.group ? w.group + ": " : "") + w.name, value: w.id }); }); - var actionDef = this.actionDef; - var onChange = props.onChange; - var handleWidgetIdChange = function (widgetId) { - onChange(__assign(__assign({}, actionDef), { widgetId: widgetId, contextVarValues: {} })); + const widgetOptions = lodash_1.default.sortByAll(Object.values(props.widgetLibrary.widgets), "group", "name").map(w => ({ label: (w.group ? `${w.group}: ` : "") + w.name, value: w.id })); + const actionDef = this.actionDef; + const onChange = props.onChange; + const handleWidgetIdChange = (widgetId) => { + onChange(Object.assign(Object.assign({}, actionDef), { widgetId: widgetId, contextVarValues: {} })); }; - var widgetDef = actionDef.widgetId ? props.widgetLibrary.widgets[actionDef.widgetId] : null; - var renderContextVarValue = function (contextVar) { - var cvv = actionDef.contextVarValues[contextVar.id]; - var handleCVVTypeSelect = function (cvvType) { - props.onChange(immer_1.default(actionDef, function (draft) { + const widgetDef = actionDef.widgetId ? props.widgetLibrary.widgets[actionDef.widgetId] : null; + const renderContextVarValue = (contextVar) => { + const cvv = actionDef.contextVarValues[contextVar.id]; + const handleCVVTypeSelect = (cvvType) => { + props.onChange(immer_1.default(actionDef, (draft) => { if (cvvType == "null") { draft.contextVarValues[contextVar.id] = { type: "null" }; } @@ -325,13 +210,13 @@ var OpenPageAction = /** @class */ (function (_super) { } })); }; - var handleCVVChange = function (newCVV) { - props.onChange(immer_1.default(actionDef, function (draft) { + const handleCVVChange = (newCVV) => { + props.onChange(immer_1.default(actionDef, (draft) => { draft.contextVarValues[contextVar.id] = newCVV; })); }; // Create options list - var options = [ + const options = [ { value: "null", label: "No Value" }, { value: "ref", label: "Existing Variable" }, ]; @@ -349,16 +234,16 @@ var OpenPageAction = /** @class */ (function (_super) { } if (cvv.type == "literal") { // Do not allow referencing context variables, as they will not be available in the other page - return react_1.default.createElement(contextVarValues_1.ContextVarValueEditor, { schema: props.schema, dataSource: props.dataSource, contextVar: contextVar, contextVarValue: cvv.value, availContextVars: [], onContextVarValueChange: function (value) { handleCVVChange(__assign(__assign({}, cvv), { value: value })); } }); + return react_1.default.createElement(contextVarValues_1.ContextVarValueEditor, { schema: props.schema, dataSource: props.dataSource, contextVar: contextVar, contextVarValue: cvv.value, availContextVars: [], onContextVarValueChange: value => { handleCVVChange(Object.assign(Object.assign({}, cvv), { value })); } }); } if (cvv.type == "ref") { - var refOptions = props.contextVars - .filter(function (cv) { return areContextVarCompatible(cv, contextVar); }) - .map(function (cv) { return ({ value: cv.id, label: cv.name }); }); - return react_1.default.createElement(bootstrap_1.Select, { options: refOptions, value: cvv.contextVarId, onChange: function (value) { handleCVVChange(__assign(__assign({}, cvv), { contextVarId: value })); }, nullLabel: "Select Variable..." }); + const refOptions = props.contextVars + .filter(cv => areContextVarCompatible(cv, contextVar)) + .map(cv => ({ value: cv.id, label: cv.name })); + return react_1.default.createElement(bootstrap_1.Select, { options: refOptions, value: cvv.contextVarId, onChange: value => { handleCVVChange(Object.assign(Object.assign({}, cvv), { contextVarId: value })); }, nullLabel: "Select Variable..." }); } if (cvv.type == "contextVarExpr") { - return react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVarId: cvv.contextVarId, contextVars: props.contextVars, dataSource: props.dataSource, expr: cvv.expr, schema: props.schema, types: [contextVar.type == "row" ? "id" : contextVar.type], idTable: contextVar.type == "row" ? contextVar.table : contextVar.idTable, onChange: function (contextVarId, expr) { handleCVVChange(__assign(__assign({}, cvv), { expr: expr, contextVarId: contextVarId })); } }); + return react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVarId: cvv.contextVarId, contextVars: props.contextVars, dataSource: props.dataSource, expr: cvv.expr, schema: props.schema, types: [contextVar.type == "row" ? "id" : contextVar.type], idTable: contextVar.type == "row" ? contextVar.table : contextVar.idTable, onChange: (contextVarId, expr) => { handleCVVChange(Object.assign(Object.assign({}, cvv), { expr, contextVarId })); } }); } return "Not supported"; } @@ -369,7 +254,7 @@ var OpenPageAction = /** @class */ (function (_super) { !cvv ? react_1.default.createElement("span", { className: "text-warning" }, "Value not set") : null, renderContextVarValueEditor()))); }; - var renderContextVarValues = function () { + const renderContextVarValues = () => { if (!widgetDef) { return null; } @@ -378,31 +263,26 @@ var OpenPageAction = /** @class */ (function (_super) { }; return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Page Type" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "pageType" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [{ value: "normal", label: "Normal" }, { value: "modal", label: "Modal" }] }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "pageType" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [{ value: "normal", label: "Normal" }, { value: "modal", label: "Modal" }] }))), this.actionDef.pageType == "modal" ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Modal Size" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "modalSize" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value || "large", onChange: onChange, options: [ - { value: "small", label: "Small" }, - { value: "normal", label: "Normal" }, - { value: "large", label: "Large" }, - { value: "full", label: "Full-screen" } - ] }); - })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "modalSize" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value || "large", onChange: onChange, options: [ + { value: "small", label: "Small" }, + { value: "normal", label: "Normal" }, + { value: "large", label: "Large" }, + { value: "full", label: "Full-screen" } + ] }))) : null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Page Widget" }, react_1.default.createElement(bootstrap_1.Select, { value: actionDef.widgetId, onChange: handleWidgetIdChange, options: widgetOptions, nullLabel: "Select Widget" })), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "replacePage" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Replace current page"); }), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "replacePage" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Replace current page")), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Variables" }, renderContextVarValues()), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Page Title" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "title" }, function (value, onChange) { - return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "title" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Page Title embedded expressions", help: "Reference in text as {0}, {1}, etc." }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "titleEmbeddedExprs" }, function (value, onChange) { return (react_1.default.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })); })))); - }; - return OpenPageAction; -}(actions_1.Action)); + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "titleEmbeddedExprs" }, (value, onChange) => (react_1.default.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })))))); + } +} exports.OpenPageAction = OpenPageAction; /** * Determine if context variables are compatible to be passed in. @@ -424,7 +304,7 @@ function areContextVarCompatible(cv1, cv2) { return false; } if (cv1.enumValues && cv2.enumValues) { - if (!lodash_1.default.isEqual(cv1.enumValues.map(function (ev) { return ev.id; }), cv2.enumValues.map(function (ev) { return ev.id; }))) { + if (!lodash_1.default.isEqual(cv1.enumValues.map(ev => ev.id), cv2.enumValues.map(ev => ev.id))) { return false; } } diff --git a/lib/widgets/actions/openPage.test.js b/lib/widgets/actions/openPage.test.js index 44a7fd06..4d5e90a8 100644 --- a/lib/widgets/actions/openPage.test.js +++ b/lib/widgets/actions/openPage.test.js @@ -1,15 +1,4 @@ "use strict"; -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) { @@ -19,87 +8,51 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); -var Database_1 = require("../../database/Database"); -var schema_1 = __importDefault(require("../../__fixtures__/schema")); -var openPage_1 = require("./openPage"); -var mockInstanceCtx_1 = __importDefault(require("../../__fixtures__/mockInstanceCtx")); -test("performs action", function () { return __awaiter(void 0, void 0, void 0, function () { - var ad, schema, database, openPage, pageStack, instanceCtx, action, page; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - ad = { - type: "openPage", - pageType: "normal", - widgetId: "innerPage", - contextVarValues: { - "innercv1": { - type: "ref", - contextVarId: "outercv1" - } - } - }; - schema = schema_1.default(); - database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); - openPage = jest.fn(); - pageStack = { - openPage: openPage - }; - instanceCtx = __assign(__assign({}, mockInstanceCtx_1.default()), { database: database, schema: schema, pageStack: pageStack, contextVars: [{ id: "outercv1", table: "t2", name: "Cv1", type: "rowset" }], contextVarValues: { outercv1: { type: "literal", valueType: "boolean", value: true } }, getContextVarExprValue: function () { throw new Error("Not implemented"); }, getFilters: function (cvid) { - return cvid == "outercv1" ? [{ id: "f1", expr: { type: "literal", valueType: "boolean", value: false } }] : []; - }, widgetLibrary: { widgets: { - "innerPage": { - contextVars: [{ id: "innercv1", type: "boolean" }] - } - } } }); - action = new openPage_1.OpenPageAction(ad); - return [4 /*yield*/, action.performAction(instanceCtx)]; - case 1: - _a.sent(); - page = openPage.mock.calls[0][0]; - // Should include filters in rowset - expect(page.contextVarValues["innercv1"]).toEqual({ - type: "op", - table: "t2", - op: "and", - exprs: [ - { type: "literal", valueType: "boolean", value: true }, - { type: "literal", valueType: "boolean", value: false } - ] - }); - return [2 /*return*/]; +const VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); +const Database_1 = require("../../database/Database"); +const schema_1 = __importDefault(require("../../__fixtures__/schema")); +const openPage_1 = require("./openPage"); +const mockInstanceCtx_1 = __importDefault(require("../../__fixtures__/mockInstanceCtx")); +test("performs action", () => __awaiter(void 0, void 0, void 0, function* () { + const ad = { + type: "openPage", + pageType: "normal", + widgetId: "innerPage", + contextVarValues: { + "innercv1": { + type: "ref", + contextVarId: "outercv1" + } } + }; + const schema = schema_1.default(); + const database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); + const openPage = jest.fn(); + const pageStack = { + openPage: openPage + }; + const instanceCtx = Object.assign(Object.assign({}, mockInstanceCtx_1.default()), { database: database, schema: schema, pageStack: pageStack, contextVars: [{ id: "outercv1", table: "t2", name: "Cv1", type: "rowset" }], contextVarValues: { outercv1: { type: "literal", valueType: "boolean", value: true } }, getContextVarExprValue: () => { throw new Error("Not implemented"); }, getFilters: (cvid) => { + return cvid == "outercv1" ? [{ id: "f1", expr: { type: "literal", valueType: "boolean", value: false } }] : []; + }, widgetLibrary: { widgets: { + "innerPage": { + contextVars: [{ id: "innercv1", type: "boolean" }] + } + } } }); + const action = new openPage_1.OpenPageAction(ad); + yield action.performAction(instanceCtx); + const page = openPage.mock.calls[0][0]; + // Should include filters in rowset + expect(page.contextVarValues["innercv1"]).toEqual({ + type: "op", + table: "t2", + op: "and", + exprs: [ + { type: "literal", valueType: "boolean", value: true }, + { type: "literal", valueType: "boolean", value: false } + ] }); -}); }); +})); diff --git a/lib/widgets/actions/removeRow.js b/lib/widgets/actions/removeRow.js index 824c9303..5921e26d 100644 --- a/lib/widgets/actions/removeRow.js +++ b/lib/widgets/actions/removeRow.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -40,85 +27,41 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 }; - } -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.RemoveRowAction = void 0; -var React = __importStar(require("react")); -var actions_1 = require("../actions"); -var propertyEditors_1 = require("../propertyEditors"); +const React = __importStar(require("react")); +const actions_1 = require("../actions"); +const propertyEditors_1 = require("../propertyEditors"); /** Remove a single row specified by a context variable */ -var RemoveRowAction = /** @class */ (function (_super) { - __extends(RemoveRowAction, _super); - function RemoveRowAction() { - return _super !== null && _super.apply(this, arguments) || this; - } - RemoveRowAction.prototype.performAction = function (instanceCtx) { - return __awaiter(this, void 0, void 0, function () { - var contextVar, table, id, txn; - var _this = this; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = instanceCtx.contextVars.find(function (cv) { return cv.id === _this.actionDef.contextVarId; }); - table = contextVar.table; - id = instanceCtx.contextVarValues[this.actionDef.contextVarId]; - // Do nothing if no row - if (!id) { - return [2 /*return*/]; - } - txn = instanceCtx.database.transaction(); - return [4 /*yield*/, txn.removeRow(table, id)]; - case 1: - _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 2: - _a.sent(); - return [2 /*return*/]; - } - }); +class RemoveRowAction extends actions_1.Action { + performAction(instanceCtx) { + return __awaiter(this, void 0, void 0, function* () { + const contextVar = instanceCtx.contextVars.find(cv => cv.id === this.actionDef.contextVarId); + // Remove row + const table = contextVar.table; + const id = instanceCtx.contextVarValues[this.actionDef.contextVarId]; + // Do nothing if no row + if (!id) { + return; + } + const txn = instanceCtx.database.transaction(); + yield txn.removeRow(table, id); + yield txn.commit(); }); - }; - RemoveRowAction.prototype.validate = function (designCtx) { - var _this = this; + } + validate(designCtx) { // Validate cv - var contextVar = designCtx.contextVars.find(function (cv) { return cv.id === _this.actionDef.contextVarId && cv.type === "row"; }); + const contextVar = designCtx.contextVars.find(cv => cv.id === this.actionDef.contextVarId && cv.type === "row"); if (!contextVar) { return "Context variable required"; } return null; - }; - RemoveRowAction.prototype.renderEditor = function (props) { - var onChange = props.onChange; + } + renderEditor(props) { + const onChange = props.onChange; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Row Variable to delete" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "contextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["row"] }); })))); - }; - return RemoveRowAction; -}(actions_1.Action)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.actionDef, onChange: onChange, property: "contextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["row"] }))))); + } +} exports.RemoveRowAction = RemoveRowAction; diff --git a/lib/widgets/blocks.js b/lib/widgets/blocks.js index 622e76e8..26035b53 100644 --- a/lib/widgets/blocks.js +++ b/lib/widgets/blocks.js @@ -1,23 +1,12 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateContextVarExpr = exports.duplicateBlockDef = exports.createExprVariableValues = exports.createExprVariables = exports.getBlockTree = exports.findBlockAncestry = exports.dropBlock = exports.Block = exports.NullBlockStore = exports.DropSide = void 0; -var lodash_1 = __importDefault(require("lodash")); -var uuid_1 = require("uuid"); -var mwater_expressions_1 = require("mwater-expressions"); +const lodash_1 = __importDefault(require("lodash")); +const uuid_1 = require("uuid"); +const mwater_expressions_1 = require("mwater-expressions"); require("./blocks.css"); /** Side on which another block is dropped on a block */ var DropSide; @@ -28,54 +17,46 @@ var DropSide; DropSide["right"] = "Right"; })(DropSide = exports.DropSide || (exports.DropSide = {})); /** Store which throws on any operation */ -var NullBlockStore = /** @class */ (function () { - function NullBlockStore() { - } - NullBlockStore.prototype.alterBlock = function (blockId, action) { +class NullBlockStore { + alterBlock(blockId, action) { throw new Error("Not allowed"); - }; - NullBlockStore.prototype.replaceBlock = function (blockDef) { + } + replaceBlock(blockDef) { throw new Error("Not allowed"); - }; - return NullBlockStore; -}()); + } +} exports.NullBlockStore = NullBlockStore; /** Block class. Ephemeral class that is created for a block def and * contains the logic and display for a block type. * Note: Designer (renderDesign and renderEditor) can assume that the block def is canonical. * Instance, however, cannot assume that. */ -var Block = /** @class */ (function () { - function Block(blockDef) { +class Block { + constructor(blockDef) { this.blockDef = blockDef; } - Object.defineProperty(Block.prototype, "id", { - get: function () { return this.blockDef.id; }, - enumerable: false, - configurable: true - }); + get id() { return this.blockDef.id; } /** Render an optional property editor for the block. This may use bootstrap */ - Block.prototype.renderEditor = function (designCtx) { return null; }; + renderEditor(designCtx) { return null; } /** Get any context variables expressions that this block needs (not including child blocks) */ - Block.prototype.getContextVarExprs = function (contextVar, ctx) { return []; }; + getContextVarExprs(contextVar, ctx) { return []; } /** Get any context variables expressions that this block needs *including* child blocks. Can be overridden */ - Block.prototype.getSubtreeContextVarExprs = function (contextVar, ctx) { + getSubtreeContextVarExprs(contextVar, ctx) { // Get own exprs - var ownExprs = this.getContextVarExprs(contextVar, ctx); + let ownExprs = this.getContextVarExprs(contextVar, ctx); // Append child ones - for (var _i = 0, _a = this.getChildren(ctx.contextVars); _i < _a.length; _i++) { - var childBlock = _a[_i]; - var block = ctx.createBlock(childBlock.blockDef); + for (const childBlock of this.getChildren(ctx.contextVars)) { + const block = ctx.createBlock(childBlock.blockDef); ownExprs = ownExprs.concat(block.getSubtreeContextVarExprs(contextVar, ctx)); } return ownExprs; - }; + } /** * Processes entire tree, starting at bottom. Allows * easy mutation of the tree */ - Block.prototype.process = function (createBlock, action) { - var blockDef = this.processChildren(function (childBlockDef) { + process(createBlock, action) { + const blockDef = this.processChildren((childBlockDef) => { // Recursively process, starting at bottom if (childBlockDef != null) { return createBlock(childBlockDef).process(createBlock, action); @@ -85,33 +66,31 @@ var Block = /** @class */ (function () { } }); return action(blockDef); - }; + } /** Get initial filters generated by this block. Does not include child blocks */ - Block.prototype.getInitialFilters = function (contextVarId, instanceCtx) { return []; }; + getInitialFilters(contextVarId, instanceCtx) { return []; } /** Get initial filters generated by this block and any children */ - Block.prototype.getSubtreeInitialFilters = function (contextVarId, instanceCtx) { + getSubtreeInitialFilters(contextVarId, instanceCtx) { // Get own filters - var ownFilters = this.getInitialFilters(contextVarId, instanceCtx); + let ownFilters = this.getInitialFilters(contextVarId, instanceCtx); // Append child ones - for (var _i = 0, _a = this.getChildren(instanceCtx.contextVars); _i < _a.length; _i++) { - var childBlock = _a[_i]; - var block = instanceCtx.createBlock(childBlock.blockDef); + for (const childBlock of this.getChildren(instanceCtx.contextVars)) { + const block = instanceCtx.createBlock(childBlock.blockDef); ownFilters = ownFilters.concat(block.getSubtreeInitialFilters(contextVarId, instanceCtx)); } return ownFilters; - }; + } /** Canonicalize the block definition. Should be done after operations on the block are completed. Only alter self, not children. * Can also be used to upgrade blocks */ - Block.prototype.canonicalize = function () { + canonicalize() { return this.blockDef; - }; + } /** Get label to display in designer */ - Block.prototype.getLabel = function () { + getLabel() { return this.blockDef.type; - }; - return Block; -}()); + } +} exports.Block = Block; // Handles logic of a simple dropping of a block on another function dropBlock(droppedBlockDef, targetBlockDef, dropSide) { @@ -155,16 +134,15 @@ exports.dropBlock = dropBlock; * @returns array of child blocks, each with information about which context variables were injected by their parent */ function findBlockAncestry(rootBlockDef, createBlock, contextVars, blockId) { - var rootBlock = createBlock(rootBlockDef); + const rootBlock = createBlock(rootBlockDef); // Return self if true if (rootBlock.id === blockId) { return [{ blockDef: rootBlockDef, contextVars: contextVars }]; } // For each child - for (var _i = 0, _a = rootBlock.getChildren(contextVars); _i < _a.length; _i++) { - var childBlock = _a[_i]; + for (const childBlock of rootBlock.getChildren(contextVars)) { if (childBlock.blockDef) { - var childAncestry = findBlockAncestry(childBlock.blockDef, createBlock, childBlock.contextVars, blockId); + const childAncestry = findBlockAncestry(childBlock.blockDef, createBlock, childBlock.contextVars, blockId); if (childAncestry) { return [{ blockDef: rootBlockDef, contextVars: contextVars }].concat(childAncestry); } @@ -175,14 +153,13 @@ function findBlockAncestry(rootBlockDef, createBlock, contextVars, blockId) { exports.findBlockAncestry = findBlockAncestry; /** Get the entire tree of blocks from a root, including context variables for each */ function getBlockTree(rootBlockDef, createBlock, contextVars) { - var rootChildBlock = { blockDef: rootBlockDef, contextVars: contextVars }; + const rootChildBlock = { blockDef: rootBlockDef, contextVars: contextVars }; // Create list including children - var list = [rootChildBlock]; + let list = [rootChildBlock]; // For each child - for (var _i = 0, _a = createBlock(rootBlockDef).getChildren(contextVars); _i < _a.length; _i++) { - var childBlock = _a[_i]; + for (const childBlock of createBlock(rootBlockDef).getChildren(contextVars)) { if (childBlock.blockDef) { - var childTree = getBlockTree(childBlock.blockDef, createBlock, childBlock.contextVars); + const childTree = getBlockTree(childBlock.blockDef, createBlock, childBlock.contextVars); list = list.concat(childTree); } } @@ -191,7 +168,7 @@ function getBlockTree(rootBlockDef, createBlock, contextVars) { exports.getBlockTree = getBlockTree; /** Create the variables as needed by mwater-expressions */ function createExprVariables(contextVar) { - return contextVar.map(function (cv) { + return contextVar.map(cv => { switch (cv.type) { case "row": return { id: cv.id, type: "id", name: { _base: "en", en: cv.name }, idTable: cv.table }; @@ -211,11 +188,11 @@ function createExprVariables(contextVar) { exports.createExprVariables = createExprVariables; /** Create the variable values as needed by mwater-expressions */ function createExprVariableValues(contextVars, contextVarValues) { - return lodash_1.default.mapValues(contextVarValues, function (value, contextVarId) { - var cv = contextVars.find(function (cv) { return cv.id == contextVarId; }); + return lodash_1.default.mapValues(contextVarValues, (value, contextVarId) => { + const cv = contextVars.find(cv => cv.id == contextVarId); // TODO: For some reason, there can be values with no corresponding context var. Warn for now to unbreak. if (!cv) { - console.warn("createExprVariableValues: Context variable " + contextVarId + " not found"); + console.warn(`createExprVariableValues: Context variable ${contextVarId} not found`); return null; } if (cv.type == "row") { @@ -227,27 +204,27 @@ function createExprVariableValues(contextVars, contextVarValues) { exports.createExprVariableValues = createExprVariableValues; /** Make a duplicate of a block */ function duplicateBlockDef(blockDef, createBlock) { - return createBlock(blockDef).process(createBlock, function (bd) { return bd ? (__assign(__assign({}, bd), { id: uuid_1.v4() })) : null; }); + return createBlock(blockDef).process(createBlock, (bd) => bd ? (Object.assign(Object.assign({}, bd), { id: uuid_1.v4() })) : null); } exports.duplicateBlockDef = duplicateBlockDef; /** Validates a context variable/expr combo. Null if ok */ function validateContextVarExpr(options) { - var error; + let error; // Validate cv - var contextVar = undefined; + let contextVar = undefined; if (options.contextVarId) { - contextVar = options.contextVars.find(function (cv) { return cv.id === options.contextVarId && (cv.type === "rowset" || cv.type === "row"); }); + contextVar = options.contextVars.find(cv => cv.id === options.contextVarId && (cv.type === "rowset" || cv.type === "row")); if (!contextVar) { return "Context variable not found"; } } // Only include context variables before up to an including one referenced, or all context variables if null // This is because an outer context var expr cannot reference an inner context variable - var cvIndex = options.contextVars.findIndex(function (cv) { return cv.id === options.contextVarId; }); - var availContextVars = cvIndex >= 0 ? lodash_1.default.take(options.contextVars, cvIndex + 1) : options.contextVars; - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, createExprVariables(availContextVars)); + const cvIndex = options.contextVars.findIndex(cv => cv.id === options.contextVarId); + const availContextVars = cvIndex >= 0 ? lodash_1.default.take(options.contextVars, cvIndex + 1) : options.contextVars; + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, createExprVariables(availContextVars)); // Only allow aggregate status of literal and individual for rows - var aggrStatuses = options.aggrStatuses || ((contextVar && contextVar.type == "row") ? ["individual", "literal"] : ['aggregate', 'individual', 'literal']); + const aggrStatuses = options.aggrStatuses || ((contextVar && contextVar.type == "row") ? ["individual", "literal"] : ['aggregate', 'individual', 'literal']); // Validate expr error = exprValidator.validateExpr(options.expr, { table: contextVar ? contextVar.table : undefined, diff --git a/lib/widgets/blocks.test.js b/lib/widgets/blocks.test.js index 05815af3..e2c24c28 100644 --- a/lib/widgets/blocks.test.js +++ b/lib/widgets/blocks.test.js @@ -22,20 +22,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var blocks = __importStar(require("./blocks")); -var BlockFactory_1 = __importDefault(require("./BlockFactory")); -test("drops left", function () { - var source = { id: "a", type: "dummy" }; - var target = { id: "b", type: "dummy" }; - var result = blocks.dropBlock(source, target, blocks.DropSide.left); +const blocks = __importStar(require("./blocks")); +const BlockFactory_1 = __importDefault(require("./BlockFactory")); +test("drops left", () => { + const source = { id: "a", type: "dummy" }; + const target = { id: "b", type: "dummy" }; + const result = blocks.dropBlock(source, target, blocks.DropSide.left); expect(result.type).toBe("horizontal"); expect(result.items[0]).toBe(source); expect(result.items[1]).toBe(target); }); -test("findBlockAncestry", function () { - var createBlock = new BlockFactory_1.default().createBlock; +test("findBlockAncestry", () => { + const createBlock = new BlockFactory_1.default().createBlock; // Create simple tree - var blockDef = { + const blockDef = { id: "a1", type: "horizontal", align: "justify", @@ -48,19 +48,19 @@ test("findBlockAncestry", function () { } ] }; - expect(blocks.findBlockAncestry(blockDef, createBlock, [], "a1").map(function (b) { return b.blockDef.id; })).toEqual(["a1"]); - expect(blocks.findBlockAncestry(blockDef, createBlock, [], "b1").map(function (b) { return b.blockDef.id; })).toEqual(["a1", "b1"]); - expect(blocks.findBlockAncestry(blockDef, createBlock, [], "c1").map(function (b) { return b.blockDef.id; })).toEqual(["a1", "b1", "c1"]); + expect(blocks.findBlockAncestry(blockDef, createBlock, [], "a1").map(b => b.blockDef.id)).toEqual(["a1"]); + expect(blocks.findBlockAncestry(blockDef, createBlock, [], "b1").map(b => b.blockDef.id)).toEqual(["a1", "b1"]); + expect(blocks.findBlockAncestry(blockDef, createBlock, [], "c1").map(b => b.blockDef.id)).toEqual(["a1", "b1", "c1"]); expect(blocks.findBlockAncestry(blockDef, createBlock, [], "x")).toBeNull(); }); -test("findBlockAncestry with queryTable", function () { - var createBlock = new BlockFactory_1.default().createBlock; +test("findBlockAncestry with queryTable", () => { + const createBlock = new BlockFactory_1.default().createBlock; // Root cv - var rootContextVars = [ + const rootContextVars = [ { id: "cv1", type: "rowset", table: "t1", name: "CV1" } ]; // Create simple tree - var blockDef = { + const blockDef = { id: "qt1", type: "queryTable", rowsetContextVarId: "cv1", @@ -70,16 +70,16 @@ test("findBlockAncestry with queryTable", function () { { id: "c1", type: "horizontal", items: [] } ] }; - var ancestry = blocks.findBlockAncestry(blockDef, createBlock, rootContextVars, "c1"); + const ancestry = blocks.findBlockAncestry(blockDef, createBlock, rootContextVars, "c1"); expect(ancestry).toEqual([ { blockDef: blockDef, contextVars: rootContextVars }, { blockDef: blockDef.contents[0], contextVars: rootContextVars.concat({ id: "qt1_row", name: "Table row of CV1", type: "row", table: "t1" }) }, ]); }); -test("getBlockTree", function () { - var createBlock = new BlockFactory_1.default().createBlock; +test("getBlockTree", () => { + const createBlock = new BlockFactory_1.default().createBlock; // Create simple tree - var blockDef = { + const blockDef = { id: "a1", type: "horizontal", items: [ @@ -91,9 +91,9 @@ test("getBlockTree", function () { } ] }; - expect(blocks.getBlockTree(blockDef, createBlock, []).map(function (b) { return b.blockDef.id; })).toEqual(["a1", "b1", "c1"]); + expect(blocks.getBlockTree(blockDef, createBlock, []).map(b => b.blockDef.id)).toEqual(["a1", "b1", "c1"]); }); -test("createExprVariables", function () { +test("createExprVariables", () => { expect(blocks.createExprVariables([{ id: "cv1", type: "row", name: "Cv1", table: "t1" }])).toEqual([ { id: "cv1", type: "id", name: { _base: "en", en: "Cv1" }, idTable: "t1" } ]); @@ -104,14 +104,14 @@ test("createExprVariables", function () { { id: "cv1", type: "boolean", name: { _base: "en", en: "Cv1" }, table: "t1" } ]); }); -test("duplicateBlockDef with queryTable", function () { - var createBlock = new BlockFactory_1.default().createBlock; +test("duplicateBlockDef with queryTable", () => { + const createBlock = new BlockFactory_1.default().createBlock; // Root cv - var rootContextVars = [ + const rootContextVars = [ { id: "cv1", type: "rowset", table: "t1", name: "CV1" } ]; // Create simple tree - var blockDef = { + const blockDef = { id: "qt1", type: "queryTable", rowsetContextVarId: "cv1", @@ -121,7 +121,7 @@ test("duplicateBlockDef with queryTable", function () { { id: "c1", type: "horizontal", items: [] } ] }; - var duplicate = blocks.duplicateBlockDef(blockDef, createBlock); + const duplicate = blocks.duplicateBlockDef(blockDef, createBlock); expect(duplicate.id).not.toBe(blockDef.id); expect(duplicate.contents[0].id).not.toBe(blockDef.contents[0].id); }); diff --git a/lib/widgets/blocks/addRow.js b/lib/widgets/blocks/addRow.js index 78683d8d..6864a334 100644 --- a/lib/widgets/blocks/addRow.js +++ b/lib/widgets/blocks/addRow.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -51,75 +27,43 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AddRowBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var propertyEditors_1 = require("../propertyEditors"); -var columnValues_1 = require("../columnValues"); -var AddRowBlock = /** @class */ (function (_super) { - __extends(AddRowBlock, _super); - function AddRowBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - AddRowBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const propertyEditors_1 = require("../propertyEditors"); +const columnValues_1 = require("../columnValues"); +class AddRowBlock extends blocks_1.Block { + getChildren(contextVars) { if (this.blockDef.content) { - var contextVar = this.createContextVar(); + const contextVar = this.createContextVar(); return [{ blockDef: this.blockDef.content, contextVars: contextVar ? contextVars.concat([contextVar]) : contextVars }]; } return []; - }; - AddRowBlock.prototype.createContextVar = function () { + } + createContextVar() { // Don't create new context variable if reusing existing if (this.blockDef.table && !this.blockDef.existingContextVarId) { return { type: "row", id: this.blockDef.id, name: this.blockDef.name || "Added row", table: this.blockDef.table }; } return null; - }; - AddRowBlock.prototype.validate = function (options) { - var _this = this; - var error; + } + validate(options) { + let error; // Check that table is present if (!this.blockDef.table || !options.schema.getTable(this.blockDef.table)) { return "Table required"; } // Check that existing context variable from same table if (this.blockDef.table && this.blockDef.existingContextVarId) { - var cv = options.contextVars.find(function (cv) { return cv.id == _this.blockDef.existingContextVarId; }); + const cv = options.contextVars.find(cv => cv.id == this.blockDef.existingContextVarId); if (!cv) { return "Existing context variable not found"; } @@ -128,28 +72,27 @@ var AddRowBlock = /** @class */ (function (_super) { } } // Check each column value - for (var _i = 0, _a = Object.keys(this.blockDef.columnValues); _i < _a.length; _i++) { - var columnId = _a[_i]; + for (const columnId of Object.keys(this.blockDef.columnValues)) { error = this.validateColumnValue(options, columnId); if (error) { return error; } } return null; - }; - AddRowBlock.prototype.validateColumnValue = function (options, columnId) { + } + validateColumnValue(options, columnId) { // Check that column exists - var column = options.schema.getColumn(this.blockDef.table, columnId); + const column = options.schema.getColumn(this.blockDef.table, columnId); if (!column) { return "Column not found"; } - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - var exprUtils = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)); + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + const exprUtils = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)); // Check context var - var contextVarExpr = this.blockDef.columnValues[columnId]; - var contextVar; + const contextVarExpr = this.blockDef.columnValues[columnId]; + let contextVar; if (contextVarExpr.contextVarId) { - contextVar = options.contextVars.find(function (cv) { return cv.id === contextVarExpr.contextVarId; }); + contextVar = options.contextVars.find(cv => cv.id === contextVarExpr.contextVarId); if (!contextVar || !contextVar.table) { return "Context variable not found"; } @@ -157,16 +100,16 @@ var AddRowBlock = /** @class */ (function (_super) { else { contextVar = undefined; // Must be literal - var aggrStatus = exprUtils.getExprAggrStatus(contextVarExpr.expr); + const aggrStatus = exprUtils.getExprAggrStatus(contextVarExpr.expr); if (aggrStatus && aggrStatus !== "literal") { return "Literal value required"; } } // Override for special case of allowing to set joins - var idTable = column.type == "join" ? column.join.toTable : column.idTable; - var type = column.type == "join" ? "id" : column.type; + const idTable = column.type == "join" ? column.join.toTable : column.idTable; + const type = column.type == "join" ? "id" : column.type; // Validate expr - var error; + let error; error = exprValidator.validateExpr(contextVarExpr.expr, { table: contextVar ? contextVar.table : undefined, types: [type], @@ -177,130 +120,103 @@ var AddRowBlock = /** @class */ (function (_super) { return error; } return null; - }; - AddRowBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; + } /** Get context variable expressions needed to add */ - AddRowBlock.prototype.getContextVarExprs = function (contextVar) { + getContextVarExprs(contextVar) { // Get ones for the specified context var - return Object.values(this.blockDef.columnValues).filter(function (cve) { return cve.contextVarId === contextVar.id; }).map(function (cve) { return cve.expr; }); - }; - AddRowBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSetContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + return Object.values(this.blockDef.columnValues).filter(cve => cve.contextVarId === contextVar.id).map(cve => cve.expr); + } + renderDesign(props) { + const handleSetContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = blockDef; return b; }), blockDef.id); }; // Create props for child - var contextVar = this.createContextVar(); - var contentProps = props; + const contextVar = this.createContextVar(); + let contentProps = props; // Add context variable if knowable if (contextVar) { - contentProps = __assign(__assign({}, contentProps), { contextVars: props.contextVars.concat([contextVar]) }); + contentProps = Object.assign(Object.assign({}, contentProps), { contextVars: props.contextVars.concat([contextVar]) }); } - var contentNode = props.renderChildBlock(contentProps, this.blockDef.content, handleSetContent); + const contentNode = props.renderChildBlock(contentProps, this.blockDef.content, handleSetContent); return (React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5, border: "dashed 1px #CCC" } }, contentNode)); - }; - AddRowBlock.prototype.renderInstance = function (props) { - var _this = this; - var contextVar = this.createContextVar() || props.contextVars.find(function (cv) { return cv.id == _this.blockDef.existingContextVarId; }); + } + renderInstance(props) { + const contextVar = this.createContextVar() || props.contextVars.find(cv => cv.id == this.blockDef.existingContextVarId); return React.createElement(AddRowInstance, { blockDef: this.blockDef, contextVar: contextVar, instanceCtx: props }); - }; - AddRowBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { return (React.createElement("div", null, React.createElement("h3", null, "Add Row"), React.createElement(propertyEditors_1.LabeledProperty, { label: "Table" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "table" }, function (value, onChange) { - return React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, locale: props.locale, value: value, onChange: function (t) { return onChange(t); } }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "table" }, (value, onChange) => React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, locale: props.locale, value: value, onChange: t => onChange(t) }))), this.blockDef.table ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Mode" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "existingContextVarId" }, function (value, onChange) { - return React.createElement("div", null, - React.createElement(bootstrap_1.Radio, { key: "null", radioValue: null, value: value || null, onChange: onChange }, "Always add new row"), - props.contextVars.filter(function (cv) { return cv.table == _this.blockDef.table && cv.type == "row"; }).map(function (cv) { return (React.createElement(bootstrap_1.Radio, { key: cv.id, radioValue: cv.id, value: value, onChange: onChange }, - "Use ", - React.createElement("i", null, cv.name), - " if it has a value")); })); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "existingContextVarId" }, (value, onChange) => React.createElement("div", null, + React.createElement(bootstrap_1.Radio, { key: "null", radioValue: null, value: value || null, onChange: onChange }, "Always add new row"), + props.contextVars.filter(cv => cv.table == this.blockDef.table && cv.type == "row").map(cv => (React.createElement(bootstrap_1.Radio, { key: cv.id, radioValue: cv.id, value: value, onChange: onChange }, + "Use ", + React.createElement("i", null, cv.name), + " if it has a value")))))) : null, !this.blockDef.existingContextVarId ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Variable Name" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "name" }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange, placeholder: "Unnamed" }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "name" }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange, placeholder: "Unnamed" }))) : null, this.blockDef.table ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Column Values" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columnValues" }, function (value, onChange) { - return React.createElement(columnValues_1.ColumnValuesEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: _this.blockDef.table, contextVars: props.contextVars, locale: props.locale }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columnValues" }, (value, onChange) => React.createElement(columnValues_1.ColumnValuesEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: this.blockDef.table, contextVars: props.contextVars, locale: props.locale }))) : null)); - }; - return AddRowBlock; -}(blocks_1.Block)); + } +} exports.AddRowBlock = AddRowBlock; /** Instance which adds a row and then injects as context variable */ -var AddRowInstance = /** @class */ (function (_super) { - __extends(AddRowInstance, _super); - function AddRowInstance(props) { - var _this = _super.call(this, props) || this; - _this.state = { +class AddRowInstance extends React.Component { + constructor(props) { + super(props); + this.state = { addedRowId: null }; - return _this; } - AddRowInstance.prototype.componentDidMount = function () { + componentDidMount() { // Only perform add if not reusing if (this.doesNeedAdd()) { this.performAdd(); } - }; - AddRowInstance.prototype.doesNeedAdd = function () { + } + doesNeedAdd() { return !this.props.blockDef.existingContextVarId || !this.props.instanceCtx.contextVarValues[this.props.blockDef.existingContextVarId]; - }; - AddRowInstance.prototype.performAdd = function () { - return __awaiter(this, void 0, void 0, function () { - var row, _i, _a, columnId, contextVarExpr, txn, addedRowId, err_1; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - row = {}; - for (_i = 0, _a = Object.keys(this.props.blockDef.columnValues); _i < _a.length; _i++) { - columnId = _a[_i]; - contextVarExpr = this.props.blockDef.columnValues[columnId]; - row[columnId] = this.props.instanceCtx.getContextVarExprValue(contextVarExpr.contextVarId, contextVarExpr.expr); - } - _b.label = 1; - case 1: - _b.trys.push([1, 4, , 5]); - txn = this.props.instanceCtx.database.transaction(); - return [4 /*yield*/, txn.addRow(this.props.blockDef.table, row)]; - case 2: - addedRowId = _b.sent(); - return [4 /*yield*/, txn.commit()]; - case 3: - _b.sent(); - this.setState({ addedRowId: addedRowId }); - return [3 /*break*/, 5]; - case 4: - err_1 = _b.sent(); - // TODO localize - alert("Unable to add row: " + err_1.message); - return [2 /*return*/]; - case 5: return [2 /*return*/]; - } - }); + } + performAdd() { + return __awaiter(this, void 0, void 0, function* () { + // Create row to insert + const row = {}; + for (const columnId of Object.keys(this.props.blockDef.columnValues)) { + const contextVarExpr = this.props.blockDef.columnValues[columnId]; + row[columnId] = this.props.instanceCtx.getContextVarExprValue(contextVarExpr.contextVarId, contextVarExpr.expr); + } + try { + const txn = this.props.instanceCtx.database.transaction(); + const addedRowId = yield txn.addRow(this.props.blockDef.table, row); + yield txn.commit(); + this.setState({ addedRowId }); + } + catch (err) { + // TODO localize + alert("Unable to add row: " + err.message); + return; + } }); - }; - AddRowInstance.prototype.render = function () { - var _a; - var _this = this; + } + render() { if (this.doesNeedAdd()) { // Render wait while adding if (!this.state.addedRowId) { @@ -310,29 +226,28 @@ var AddRowInstance = /** @class */ (function (_super) { // Re-inject all context variables if reusing, as a variable value will have changed (if the row was added) // which means that all other context variables that depend on that value may compute wrong // if evaluated by the injectors outside of this block - var injectedContextVars = []; - var injectedContextVarValues = {}; + let injectedContextVars = []; + let injectedContextVarValues = {}; if (this.props.blockDef.existingContextVarId) { injectedContextVars = this.props.instanceCtx.contextVars; - injectedContextVarValues = __assign(__assign({}, this.props.instanceCtx.contextVarValues), (_a = {}, _a[this.props.contextVar.id] = this.state.addedRowId, _a)); + injectedContextVarValues = Object.assign(Object.assign({}, this.props.instanceCtx.contextVarValues), { [this.props.contextVar.id]: this.state.addedRowId }); } else { injectedContextVars.push(this.props.contextVar); injectedContextVarValues[this.props.contextVar.id] = this.state.addedRowId; } // Inject context variable - return React.createElement(ContextVarsInjector_1.default, { injectedContextVars: injectedContextVars, injectedContextVarValues: injectedContextVarValues, innerBlock: this.props.blockDef.content, instanceCtx: this.props.instanceCtx }, function (instanceCtx, loading, refreshing) { + return React.createElement(ContextVarsInjector_1.default, { injectedContextVars: injectedContextVars, injectedContextVarValues: injectedContextVarValues, innerBlock: this.props.blockDef.content, instanceCtx: this.props.instanceCtx }, (instanceCtx, loading, refreshing) => { if (loading) { return React.createElement("div", { style: { color: "#AAA", textAlign: "center" } }, React.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); } - return (React.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, _this.props.instanceCtx.renderChildBlock(instanceCtx, _this.props.blockDef.content))); + return (React.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, this.props.instanceCtx.renderChildBlock(instanceCtx, this.props.blockDef.content))); }); } else { // Just render if add not needed return this.props.instanceCtx.renderChildBlock(this.props.instanceCtx, this.props.blockDef.content); } - }; - return AddRowInstance; -}(React.Component)); + } +} diff --git a/lib/widgets/blocks/addRow.test.js b/lib/widgets/blocks/addRow.test.js index 9b429257..fd9b9a1a 100644 --- a/lib/widgets/blocks/addRow.test.js +++ b/lib/widgets/blocks/addRow.test.js @@ -1,15 +1,4 @@ "use strict"; -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) { @@ -19,50 +8,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var schema_1 = __importDefault(require("../../__fixtures__/schema")); -var enzyme_1 = require("enzyme"); -var react_1 = __importDefault(require("react")); -var VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); -var Database_1 = require("../../database/Database"); -var BlockFactory_1 = __importDefault(require("../BlockFactory")); -var addRow_1 = require("./addRow"); +const schema_1 = __importDefault(require("../../__fixtures__/schema")); +const enzyme_1 = require("enzyme"); +const react_1 = __importDefault(require("react")); +const VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); +const Database_1 = require("../../database/Database"); +const BlockFactory_1 = __importDefault(require("../BlockFactory")); +const addRow_1 = require("./addRow"); // Outer context vars -var schema = schema_1.default(); -var createBlock = new BlockFactory_1.default().createBlock; -var rips; -var database; -beforeEach(function () { +const schema = schema_1.default(); +const createBlock = new BlockFactory_1.default().createBlock; +let rips; +let database; +beforeEach(() => { database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); // Create render instance props rips = { @@ -79,21 +41,21 @@ beforeEach(function () { onSelectContextVar: jest.fn(), schema: schema, dataSource: {}, - renderChildBlock: function (props, childBlockDef) { + renderChildBlock: (props, childBlockDef) => { if (childBlockDef) { - var childBlock = createBlock(childBlockDef); + const childBlock = createBlock(childBlockDef); return childBlock.renderInstance(props); } return react_1.default.createElement("div", null); }, widgetLibrary: { widgets: {} }, - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => { return () => { }; }, + T: (str) => str }; }); -var pause = function () { return new Promise(function (resolve) { return setImmediate(resolve); }); }; +const pause = () => new Promise((resolve) => setImmediate(resolve)); // Create add row block with textbox of added value -var addRowBlockDef = { +const addRowBlockDef = { id: "ar1", type: "addRow", table: "t1", @@ -108,76 +70,46 @@ var addRowBlockDef = { required: false } }; -test("save writes to database", function () { return __awaiter(void 0, void 0, void 0, function () { - var addRowBlock, inst; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - rips.getContextVarExprValue.mockReturnValue("abc"); - addRowBlock = new addRow_1.AddRowBlock(addRowBlockDef); - inst = enzyme_1.mount(addRowBlock.renderInstance(rips)); - // Wait for load - return [4 /*yield*/, pause()]; - case 1: - // Wait for load - _a.sent(); - inst.update(); - // Expect added row - expect(database.mutations[0].type).toBe("add"); - expect(inst.find("input").prop("value")).toBe("abc"); - return [2 /*return*/]; - } - }); -}); }); -test("reuses existing", function () { return __awaiter(void 0, void 0, void 0, function () { - var rips2, addRowBlock, inst; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - rips2 = __assign(__assign({}, rips), { contextVars: [{ id: "existing", type: "row", table: "t1", name: "Existing" }], contextVarValues: { existing: "123" } }); - addRowBlock = new addRow_1.AddRowBlock(__assign(__assign({}, addRowBlockDef), { existingContextVarId: "existing", content: { - type: "textbox", - id: "tb1", - rowContextVarId: "existing", - column: "text", - required: false - } })); - inst = enzyme_1.mount(addRowBlock.renderInstance(rips2)); - // Wait for load - return [4 /*yield*/, pause()]; - case 1: - // Wait for load - _a.sent(); - inst.update(); - // Expect no added row - expect(database.mutations.length).toBe(0); - return [2 /*return*/]; - } - }); -}); }); -test("does not reuse non-existing existing", function () { return __awaiter(void 0, void 0, void 0, function () { - var rips2, addRowBlock, inst; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - rips2 = __assign(__assign({}, rips), { contextVars: [{ id: "existing", type: "row", table: "t1", name: "Existing" }], contextVarValues: { existing: null } }); - addRowBlock = new addRow_1.AddRowBlock(__assign(__assign({}, addRowBlockDef), { existingContextVarId: "existing", content: { - type: "textbox", - id: "tb1", - rowContextVarId: "existing", - column: "text", - required: false - } })); - inst = enzyme_1.mount(addRowBlock.renderInstance(rips2)); - // Wait for load - return [4 /*yield*/, pause()]; - case 1: - // Wait for load - _a.sent(); - inst.update(); - // Expect added row - expect(database.mutations[0].type).toBe("add"); - return [2 /*return*/]; - } - }); -}); }); +test("save writes to database", () => __awaiter(void 0, void 0, void 0, function* () { + rips.getContextVarExprValue.mockReturnValue("abc"); + const addRowBlock = new addRow_1.AddRowBlock(addRowBlockDef); + const inst = enzyme_1.mount(addRowBlock.renderInstance(rips)); + // Wait for load + yield pause(); + inst.update(); + // Expect added row + expect(database.mutations[0].type).toBe("add"); + expect(inst.find("input").prop("value")).toBe("abc"); +})); +test("reuses existing", () => __awaiter(void 0, void 0, void 0, function* () { + const rips2 = Object.assign(Object.assign({}, rips), { contextVars: [{ id: "existing", type: "row", table: "t1", name: "Existing" }], contextVarValues: { existing: "123" } }); + const addRowBlock = new addRow_1.AddRowBlock(Object.assign(Object.assign({}, addRowBlockDef), { existingContextVarId: "existing", content: { + type: "textbox", + id: "tb1", + rowContextVarId: "existing", + column: "text", + required: false + } })); + const inst = enzyme_1.mount(addRowBlock.renderInstance(rips2)); + // Wait for load + yield pause(); + inst.update(); + // Expect no added row + expect(database.mutations.length).toBe(0); +})); +test("does not reuse non-existing existing", () => __awaiter(void 0, void 0, void 0, function* () { + const rips2 = Object.assign(Object.assign({}, rips), { contextVars: [{ id: "existing", type: "row", table: "t1", name: "Existing" }], contextVarValues: { existing: null } }); + const addRowBlock = new addRow_1.AddRowBlock(Object.assign(Object.assign({}, addRowBlockDef), { existingContextVarId: "existing", content: { + type: "textbox", + id: "tb1", + rowContextVarId: "existing", + column: "text", + required: false + } })); + const inst = enzyme_1.mount(addRowBlock.renderInstance(rips2)); + // Wait for load + yield pause(); + inst.update(); + // Expect added row + expect(database.mutations[0].type).toBe("add"); +})); diff --git a/lib/widgets/blocks/addWizard.js b/lib/widgets/blocks/addWizard.js index 5baeacf9..dfbc1cee 100644 --- a/lib/widgets/blocks/addWizard.js +++ b/lib/widgets/blocks/addWizard.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,48 +23,45 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AddWizardBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var React = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var blocks_1 = require("../blocks"); -var ModalWindowComponent_1 = __importDefault(require("react-library/lib/ModalWindowComponent")); -var BlockPlaceholder_1 = __importDefault(require("../BlockPlaceholder")); -var react_1 = require("react"); -var SearchBlockInstance_1 = require("./search/SearchBlockInstance"); -var TabbedComponent_1 = __importDefault(require("react-library/lib/TabbedComponent")); -var localization_1 = require("../localization"); -var uuid = require("uuid"); -var bootstrap_1 = require("react-library/lib/bootstrap"); +const lodash_1 = __importDefault(require("lodash")); +const React = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const blocks_1 = require("../blocks"); +const ModalWindowComponent_1 = __importDefault(require("react-library/lib/ModalWindowComponent")); +const BlockPlaceholder_1 = __importDefault(require("../BlockPlaceholder")); +const react_1 = require("react"); +const SearchBlockInstance_1 = require("./search/SearchBlockInstance"); +const TabbedComponent_1 = __importDefault(require("react-library/lib/TabbedComponent")); +const localization_1 = require("../localization"); +const uuid = require("uuid"); +const bootstrap_1 = require("react-library/lib/bootstrap"); /** Displays a popup and transforms into any other kind of block */ -var AddWizardBlock = /** @class */ (function (_super) { - __extends(AddWizardBlock, _super); - function AddWizardBlock(blockDef) { - return _super.call(this, blockDef) || this; +class AddWizardBlock extends LeafBlock_1.default { + constructor(blockDef) { + super(blockDef); } - AddWizardBlock.prototype.validate = function (options) { + validate(options) { return null; - }; - AddWizardBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSet = function (newBlockDef) { + } + renderDesign(props) { + const handleSet = (newBlockDef) => { if (newBlockDef) { // Duplicate but keep top level id so that selected - var duplicatedBlockDef_1 = blocks_1.duplicateBlockDef(newBlockDef, props.createBlock); - duplicatedBlockDef_1.id = _this.blockDef.id; - props.store.alterBlock(_this.blockDef.id, function (bd) { return duplicatedBlockDef_1; }); + const duplicatedBlockDef = blocks_1.duplicateBlockDef(newBlockDef, props.createBlock); + duplicatedBlockDef.id = this.blockDef.id; + props.store.alterBlock(this.blockDef.id, (bd) => duplicatedBlockDef); } else { - props.store.alterBlock(_this.blockDef.id, function (bd) { return null; }); + props.store.alterBlock(this.blockDef.id, (bd) => null); } }; - return (React.createElement(ModalWindowComponent_1.default, { isOpen: true, onRequestClose: function () { return handleSet(null); } }, + return (React.createElement(ModalWindowComponent_1.default, { isOpen: true, onRequestClose: () => handleSet(null) }, React.createElement(AddWizardPane, { designCtx: props, onSelect: handleSet, contextVars: props.contextVars }))); - }; - AddWizardBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement("div", null); - }; - return AddWizardBlock; -}(LeafBlock_1.default)); + } +} exports.AddWizardBlock = AddWizardBlock; // Persist default tab var defaultCurrentTabId = "palette"; @@ -97,23 +70,23 @@ var defaultExpressionMode = "plain"; // Persist control mode var defaultControlMode = "labelAbove"; /** Pane with search and allowing clicking on a widget to add */ -var AddWizardPane = function (props) { - var designCtx = props.designCtx; - var _a = react_1.useState(""), search = _a[0], setSearch = _a[1]; - var _b = react_1.useState(defaultCurrentTabId), currentTabId = _b[0], setCurrentTabId = _b[1]; - var _c = react_1.useState(defaultExpressionMode), expressionMode = _c[0], setExpressionMode = _c[1]; - var _d = react_1.useState(defaultControlMode), controlMode = _d[0], setControlMode = _d[1]; +const AddWizardPane = (props) => { + const { designCtx } = props; + const [search, setSearch] = react_1.useState(""); + const [currentTabId, setCurrentTabId] = react_1.useState(defaultCurrentTabId); + const [expressionMode, setExpressionMode] = react_1.useState(defaultExpressionMode); + const [controlMode, setControlMode] = react_1.useState(defaultControlMode); // Focus on load - var searchControl = react_1.useRef(null); - react_1.useEffect(function () { + const searchControl = react_1.useRef(null); + react_1.useEffect(() => { if (searchControl.current) { searchControl.current.focus(); } }, []); /** Get entries that are controls based off of columns of first row context variable */ - var getControlEntries = function () { - var allEntries = []; - var wrapBlockDef = function (label, blockDef) { + const getControlEntries = () => { + const allEntries = []; + const wrapBlockDef = (label, blockDef) => { if (controlMode == "plain") { return blockDef; } @@ -137,12 +110,11 @@ var AddWizardPane = function (props) { throw new Error("Not implemented"); }; // Find context var of type row - for (var _i = 0, _a = props.contextVars.filter(function (cv) { return cv.type == "row"; }).reverse(); _i < _a.length; _i++) { - var contextVar = _a[_i]; + for (const contextVar of props.contextVars.filter(cv => cv.type == "row").reverse()) { // Get columns - var columns = designCtx.schema.getColumns(contextVar.table); - var _loop_1 = function (column) { - var addBlock = function (child) { + const columns = designCtx.schema.getColumns(contextVar.table); + for (const column of columns) { + const addBlock = (child) => { allEntries.push({ title: localization_1.localize(column.name) || "", blockDef: wrapBlockDef(column.name, child) @@ -189,18 +161,14 @@ var AddWizardPane = function (props) { required: column.required }); } - }; - for (var _b = 0, columns_1 = columns; _b < columns_1.length; _b++) { - var column = columns_1[_b]; - _loop_1(column); } } return allEntries; }; /** Get entries that are expressions based off of columns of first row context variable */ - var getExpressionEntries = function () { - var allEntries = []; - var wrapBlockDef = function (label, blockDef) { + const getExpressionEntries = () => { + const allEntries = []; + const wrapBlockDef = (label, blockDef) => { if (expressionMode == "plain") { return blockDef; } @@ -224,12 +192,10 @@ var AddWizardPane = function (props) { throw new Error("Not implemented"); }; // Find context var of type row - for (var _i = 0, _a = props.contextVars.filter(function (cv) { return cv.type == "row"; }).reverse(); _i < _a.length; _i++) { - var contextVar = _a[_i]; + for (const contextVar of props.contextVars.filter(cv => cv.type == "row").reverse()) { // Get columns - var columns = designCtx.schema.getColumns(contextVar.table); - for (var _b = 0, columns_2 = columns; _b < columns_2.length; _b++) { - var column = columns_2[_b]; + const columns = designCtx.schema.getColumns(contextVar.table); + for (const column of columns) { // Skip id columns if (column.type == "id" || column.type == "id[]") { continue; @@ -249,10 +215,10 @@ var AddWizardPane = function (props) { return allEntries; }; /** Get entries that are other embedded widgets */ - var getWidgetEntries = function () { - var allEntries = []; - for (var widgetId in props.designCtx.widgetLibrary.widgets) { - var widget = props.designCtx.widgetLibrary.widgets[widgetId]; + const getWidgetEntries = () => { + const allEntries = []; + for (const widgetId in props.designCtx.widgetLibrary.widgets) { + const widget = props.designCtx.widgetLibrary.widgets[widgetId]; // TODO Skip self allEntries.push({ title: widget.name, @@ -268,18 +234,18 @@ var AddWizardPane = function (props) { } return allEntries; }; - var displayAndFilterEntries = function (entries) { + const displayAndFilterEntries = (entries) => { // Compute visible entries - var visibleEntries = entries.filter(function (entry) { + const visibleEntries = entries.filter(entry => { return search ? entry.title.toLowerCase().includes(search.toLowerCase()) : true; }); - return React.createElement("div", null, visibleEntries.map(function (entry, index) { - return React.createElement(PaletteItem, { entry: entry, key: index, designCtx: designCtx, onSelect: function () { return props.onSelect(typeof entry.blockDef == "function" ? entry.blockDef(props.contextVars) : entry.blockDef); } }); + return React.createElement("div", null, visibleEntries.map((entry, index) => { + return React.createElement(PaletteItem, { entry: entry, key: index, designCtx: designCtx, onSelect: () => props.onSelect(typeof entry.blockDef == "function" ? entry.blockDef(props.contextVars) : entry.blockDef) }); })); }; - var renderExpressionOptions = function () { + const renderExpressionOptions = () => { return React.createElement("div", { style: { float: "right", paddingRight: 10 } }, - React.createElement(bootstrap_1.Toggle, { value: expressionMode, onChange: function (em) { + React.createElement(bootstrap_1.Toggle, { value: expressionMode, onChange: (em) => { setExpressionMode(em); defaultExpressionMode = em; }, size: "sm", options: [ @@ -288,9 +254,9 @@ var AddWizardPane = function (props) { { value: "labelBefore", label: "Label Before" } ] })); }; - var renderControlOptions = function () { + const renderControlOptions = () => { return React.createElement("div", { style: { float: "right", paddingRight: 10 } }, - React.createElement(bootstrap_1.Toggle, { value: controlMode, onChange: function (em) { + React.createElement(bootstrap_1.Toggle, { value: controlMode, onChange: (em) => { setControlMode(em); defaultControlMode = em; }, size: "sm", options: [ @@ -304,7 +270,7 @@ var AddWizardPane = function (props) { React.createElement(SearchBlockInstance_1.SearchControl, { value: search, onChange: setSearch, ref: searchControl, placeholder: "Search widgets..." }), currentTabId == "expressions" ? renderExpressionOptions() : null, currentTabId == "controls" ? renderControlOptions() : null), - React.createElement(TabbedComponent_1.default, { tabId: currentTabId, onTabClick: function (tabId) { + React.createElement(TabbedComponent_1.default, { tabId: currentTabId, onTabClick: tabId => { defaultCurrentTabId = tabId; setCurrentTabId(tabId); }, tabs: [ @@ -315,38 +281,33 @@ var AddWizardPane = function (props) { ] })); }; /** Single item in the palette of block choices */ -var PaletteItem = /** @class */ (function (_super) { - __extends(PaletteItem, _super); - function PaletteItem() { - return _super !== null && _super.apply(this, arguments) || this; - } - PaletteItem.prototype.renderContents = function () { - var designCtx = this.props.designCtx; +class PaletteItem extends React.Component { + renderContents() { + const designCtx = this.props.designCtx; if (this.props.entry.elem) { return this.props.entry.elem; } - var entry = this.props.entry; - var block = designCtx.createBlock(typeof entry.blockDef == "function" ? entry.blockDef(designCtx.contextVars) : entry.blockDef); - return block.renderDesign(__assign(__assign({}, designCtx), { selectedId: null, contextVars: [], store: new blocks_1.NullBlockStore(), blockPaletteEntries: [], renderChildBlock: function (props, childBlockDef) { + const entry = this.props.entry; + const block = designCtx.createBlock(typeof entry.blockDef == "function" ? entry.blockDef(designCtx.contextVars) : entry.blockDef); + return block.renderDesign(Object.assign(Object.assign({}, designCtx), { selectedId: null, contextVars: [], store: new blocks_1.NullBlockStore(), blockPaletteEntries: [], renderChildBlock: (props, childBlockDef) => { if (childBlockDef) { - var childBlock = designCtx.createBlock(childBlockDef); + const childBlock = designCtx.createBlock(childBlockDef); return childBlock.renderDesign(props); } else { return React.createElement(BlockPlaceholder_1.default, null); } } })); - }; - PaletteItem.prototype.render = function () { + } + render() { return (React.createElement("div", { className: "add-wizard-palette-item" }, React.createElement("div", { className: "add-wizard-palette-item-title" }, this.props.entry.title), this.renderContents(), React.createElement("div", { className: "add-wizard-palette-item-subtitle" }, this.props.entry.subtitle), React.createElement("div", { onClick: this.props.onSelect, className: "add-wizard-palette-item-cover" }))); - }; - return PaletteItem; -}(React.Component)); + } +} /** Appends to a localized string */ function appendStr(str, append) { - return lodash_1.default.mapValues(str, function (v, k) { return k == "_base" ? v : v + append; }); + return lodash_1.default.mapValues(str, (v, k) => k == "_base" ? v : v + append); } diff --git a/lib/widgets/blocks/alert.js b/lib/widgets/blocks/alert.js index f0e51289..ff550a74 100644 --- a/lib/widgets/blocks/alert.js +++ b/lib/widgets/blocks/alert.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,51 +23,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AlertBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var AlertBlock = /** @class */ (function (_super) { - __extends(AlertBlock, _super); - function AlertBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - AlertBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +class AlertBlock extends blocks_1.Block { + getChildren(contextVars) { return this.blockDef.content ? [{ blockDef: this.blockDef.content, contextVars: contextVars }] : []; - }; - AlertBlock.prototype.validate = function () { return null; }; - AlertBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + validate() { return null; } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; - AlertBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleAdd = function (addedBlockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleAdd = (addedBlockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = addedBlockDef; return b; }), addedBlockDef.id); }; - return (React.createElement("div", { className: "alert alert-" + this.blockDef.style }, props.renderChildBlock(props, this.blockDef.content, handleAdd))); - }; - AlertBlock.prototype.renderInstance = function (props) { - return (React.createElement("div", { className: "alert alert-" + this.blockDef.style }, props.renderChildBlock(props, this.blockDef.content))); - }; - AlertBlock.prototype.renderEditor = function (designCtx) { + return (React.createElement("div", { className: `alert alert-${this.blockDef.style}` }, props.renderChildBlock(props, this.blockDef.content, handleAdd))); + } + renderInstance(props) { + return (React.createElement("div", { className: `alert alert-${this.blockDef.style}` }, props.renderChildBlock(props, this.blockDef.content))); + } + renderEditor(designCtx) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Style" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: designCtx.store.replaceBlock, property: "style" }, function (value, onChange) { - return React.createElement(bootstrap_1.Select, { value: value || null, onChange: onChange, options: [ - { value: "info", label: "Info" }, - { value: "success", label: "Success" }, - { value: "warning", label: "Warning" }, - { value: "danger", label: "Danger" } - ] }); - })))); - }; - return AlertBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: designCtx.store.replaceBlock, property: "style" }, (value, onChange) => React.createElement(bootstrap_1.Select, { value: value || null, onChange: onChange, options: [ + { value: "info", label: "Info" }, + { value: "success", label: "Success" }, + { value: "warning", label: "Warning" }, + { value: "danger", label: "Danger" } + ] }))))); + } +} exports.AlertBlock = AlertBlock; diff --git a/lib/widgets/blocks/button.js b/lib/widgets/blocks/button.js index 25b771cb..eb9e7252 100644 --- a/lib/widgets/blocks/button.js +++ b/lib/widgets/blocks/button.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -40,52 +27,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ButtonBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var propertyEditors_1 = require("../propertyEditors"); -var localization_1 = require("../localization"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var embeddedExprs_1 = require("../../embeddedExprs"); -var ButtonBlock = /** @class */ (function (_super) { - __extends(ButtonBlock, _super); - function ButtonBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ButtonBlock.prototype.validate = function (designCtx) { - var error; +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const propertyEditors_1 = require("../propertyEditors"); +const localization_1 = require("../localization"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const embeddedExprs_1 = require("../../embeddedExprs"); +class ButtonBlock extends LeafBlock_1.default { + validate(designCtx) { + let error; // Validate expressions error = embeddedExprs_1.validateEmbeddedExprs({ embeddedExprs: this.blockDef.labelEmbeddedExprs || [], @@ -97,124 +53,107 @@ var ButtonBlock = /** @class */ (function (_super) { } // Validate action if (this.blockDef.actionDef) { - var action = designCtx.actionLibrary.createAction(this.blockDef.actionDef); + const action = designCtx.actionLibrary.createAction(this.blockDef.actionDef); error = action.validate(designCtx); if (error) { return error; } } return null; - }; - ButtonBlock.prototype.getContextVarExprs = function (contextVar, ctx) { - var exprs = []; + } + getContextVarExprs(contextVar, ctx) { + let exprs = []; if (this.blockDef.labelEmbeddedExprs) { - exprs = exprs.concat(lodash_1.default.compact(lodash_1.default.map(this.blockDef.labelEmbeddedExprs, function (ee) { return ee.contextVarId === contextVar.id ? ee.expr : null; }))); + exprs = exprs.concat(lodash_1.default.compact(lodash_1.default.map(this.blockDef.labelEmbeddedExprs, ee => ee.contextVarId === contextVar.id ? ee.expr : null))); } return exprs; - }; - ButtonBlock.prototype.renderDesign = function (props) { - var label = localization_1.localize(this.blockDef.label, props.locale); + } + renderDesign(props) { + const label = localization_1.localize(this.blockDef.label, props.locale); return react_1.default.createElement(ButtonComponent, { label: label, blockDef: this.blockDef }); - }; - ButtonBlock.prototype.renderInstance = function (instanceCtx) { + } + renderInstance(instanceCtx) { return react_1.default.createElement(ButtonInstance, { blockDef: this.blockDef, instanceCtx: instanceCtx }); - }; - ButtonBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Label" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "label" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "label" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Label embedded expressions", help: "Reference in text as {0}, {1}, etc." }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "labelEmbeddedExprs" }, function (value, onChange) { return (react_1.default.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "labelEmbeddedExprs" }, (value, onChange) => (react_1.default.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Style" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "style" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ - { value: "default", label: "Default" }, - { value: "primary", label: "Primary" }, - { value: "link", label: "Link" }, - { value: "plainlink", label: "Plain Link" }, - ] }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "style" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ + { value: "default", label: "Default" }, + { value: "primary", label: "Primary" }, + { value: "link", label: "Link" }, + { value: "plainlink", label: "Plain Link" }, + ] }))), this.blockDef.style != "plainlink" ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Size" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "size" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ - { value: "normal", label: "Default" }, - { value: "small", label: "Small" }, - { value: "extrasmall", label: "Extra-small" }, - { value: "large", label: "Large" } - ] }); - })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "size" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ + { value: "normal", label: "Default" }, + { value: "small", label: "Small" }, + { value: "extrasmall", label: "Extra-small" }, + { value: "large", label: "Large" } + ] }))) : null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Icon" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "icon" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Select, { value: value, onChange: onChange, nullLabel: "None", options: [ - { value: "plus", label: "Add" }, - { value: "pencil", label: "Edit" }, - { value: "times", label: "Remove" }, - { value: "print", label: "Print" }, - { value: "upload", label: "Upload" }, - { value: "download", label: "Download" }, - { value: "info-circle", label: "Information" }, - { value: "link", label: "Link" }, - { value: "external-link", label: "External Link" }, - { value: "search", label: "Search" }, - { value: "question-circle", label: "Help" }, - { value: "folder-open", label: "Open" }, - { value: "refresh", label: "Refresh" }, - { value: "arrow-right", label: "Right Arrow" } - ] }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "icon" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Select, { value: value, onChange: onChange, nullLabel: "None", options: [ + { value: "plus", label: "Add" }, + { value: "pencil", label: "Edit" }, + { value: "times", label: "Remove" }, + { value: "print", label: "Print" }, + { value: "upload", label: "Upload" }, + { value: "download", label: "Download" }, + { value: "info-circle", label: "Information" }, + { value: "link", label: "Link" }, + { value: "external-link", label: "External Link" }, + { value: "search", label: "Search" }, + { value: "question-circle", label: "Help" }, + { value: "folder-open", label: "Open" }, + { value: "refresh", label: "Refresh" }, + { value: "arrow-right", label: "Right Arrow" } + ] }))), this.blockDef.style != "plainlink" ? - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "block" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Block-style"); }) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "block" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Block-style")) : null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "When button clicked" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "actionDef" }, function (value, onChange) { return (react_1.default.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: props })); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "actionDef" }, (value, onChange) => (react_1.default.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: props })))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Confirm message" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "confirmMessage" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })))); - }; - return ButtonBlock; -}(LeafBlock_1.default)); + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "confirmMessage" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))))); + } +} exports.ButtonBlock = ButtonBlock; function ButtonInstance(props) { - var _this = this; - var instanceCtx = props.instanceCtx, blockDef = props.blockDef; + const { instanceCtx, blockDef } = props; // Track when action in process - var _a = react_1.useState(false), busy = _a[0], setBusy = _a[1]; - var handleClick = function (ev) { return __awaiter(_this, void 0, void 0, function () { - var action; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - // Ensure button doesn't trigger other actions - ev.stopPropagation(); - // Confirm if confirm message - if (blockDef.confirmMessage) { - if (!confirm(localization_1.localize(blockDef.confirmMessage, instanceCtx.locale))) { - return [2 /*return*/]; - } - } - if (!blockDef.actionDef) return [3 /*break*/, 4]; - action = instanceCtx.actionLibrary.createAction(blockDef.actionDef); - _a.label = 1; - case 1: - _a.trys.push([1, , 3, 4]); - setBusy(true); - return [4 /*yield*/, action.performAction(instanceCtx)]; - case 2: - _a.sent(); - return [3 /*break*/, 4]; - case 3: - setBusy(false); - return [7 /*endfinally*/]; - case 4: return [2 /*return*/]; + const [busy, setBusy] = react_1.useState(false); + const handleClick = (ev) => __awaiter(this, void 0, void 0, function* () { + // Ensure button doesn't trigger other actions + ev.stopPropagation(); + // Confirm if confirm message + if (blockDef.confirmMessage) { + if (!confirm(localization_1.localize(blockDef.confirmMessage, instanceCtx.locale))) { + return; } - }); - }); }; + } + // Run action + if (blockDef.actionDef) { + const action = instanceCtx.actionLibrary.createAction(blockDef.actionDef); + try { + setBusy(true); + yield action.performAction(instanceCtx); + } + finally { + setBusy(false); + } + } + }); // Get label - var label = localization_1.localize(blockDef.label, instanceCtx.locale); + let label = localization_1.localize(blockDef.label, instanceCtx.locale); if (label) { // Get any embedded expression values - var exprValues = lodash_1.default.map(blockDef.labelEmbeddedExprs || [], function (ee) { return instanceCtx.getContextVarExprValue(ee.contextVarId, ee.expr); }); + const exprValues = lodash_1.default.map(blockDef.labelEmbeddedExprs || [], ee => instanceCtx.getContextVarExprValue(ee.contextVarId, ee.expr)); // Format and replace label = embeddedExprs_1.formatEmbeddedExprString({ text: label, @@ -230,8 +169,8 @@ function ButtonInstance(props) { } /** Draws the button */ function ButtonComponent(props) { - var label = props.label, onClick = props.onClick, blockDef = props.blockDef; - var icon = blockDef.icon ? react_1.default.createElement("i", { className: "fa fa-fw fa-" + blockDef.icon }) : null; + const { label, onClick, blockDef } = props; + const icon = blockDef.icon ? react_1.default.createElement("i", { className: `fa fa-fw fa-${blockDef.icon}` }) : null; // Special case of plain link if (blockDef.style == "plainlink") { return react_1.default.createElement("div", null, @@ -240,24 +179,24 @@ function ButtonComponent(props) { icon && label ? "\u00A0" : null, label)); } - var className = "btn btn-" + blockDef.style; + let className = "btn btn-" + blockDef.style; switch (blockDef.size) { case "normal": break; case "small": - className += " btn-sm"; + className += ` btn-sm`; break; case "extrasmall": - className += " btn-xs"; + className += ` btn-xs`; break; case "large": - className += " btn-lg"; + className += ` btn-lg`; break; } if (blockDef.block) { className += " btn-block"; } - var style = {}; + const style = {}; if (!blockDef.block) { style.margin = 5; } diff --git a/lib/widgets/blocks/collapsible.js b/lib/widgets/blocks/collapsible.js index caf94856..1128f858 100644 --- a/lib/widgets/blocks/collapsible.js +++ b/lib/widgets/blocks/collapsible.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,81 +23,73 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CollapsibleComponent = exports.CollapsibleBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var _ = __importStar(require("lodash")); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var CollapsibleBlock = /** @class */ (function (_super) { - __extends(CollapsibleBlock, _super); - function CollapsibleBlock() { - return _super !== null && _super.apply(this, arguments) || this; +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const _ = __importStar(require("lodash")); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +class CollapsibleBlock extends blocks_1.Block { + getChildren(contextVars) { + return _.compact([this.blockDef.label, this.blockDef.content]).map(bd => ({ blockDef: bd, contextVars: contextVars })); } - CollapsibleBlock.prototype.getChildren = function (contextVars) { - return _.compact([this.blockDef.label, this.blockDef.content]).map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; - CollapsibleBlock.prototype.validate = function () { return null; }; - CollapsibleBlock.prototype.processChildren = function (action) { - var label = action(this.blockDef.label); - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + validate() { return null; } + processChildren(action) { + const label = action(this.blockDef.label); + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.label = label; draft.content = content; }); - }; - CollapsibleBlock.prototype.renderDesign = function (props) { - var _this = this; + } + renderDesign(props) { // Allow dropping - var handleSetLabel = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const handleSetLabel = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.label = blockDef; return b; }), blockDef.id); }; - var handleSetContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const handleSetContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = blockDef; return b; }), blockDef.id); }; - var labelNode = props.renderChildBlock(props, this.blockDef.label, handleSetLabel); - var contentNode = props.renderChildBlock(props, this.blockDef.content, handleSetContent); + const labelNode = props.renderChildBlock(props, this.blockDef.label, handleSetLabel); + const contentNode = props.renderChildBlock(props, this.blockDef.content, handleSetContent); return (React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, React.createElement(CollapsibleComponent, { label: labelNode, forceOpen: true }, contentNode))); - }; - CollapsibleBlock.prototype.renderInstance = function (props) { - var labelNode = this.blockDef.label ? + } + renderInstance(props) { + const labelNode = this.blockDef.label ? props.createBlock(this.blockDef.label).renderInstance(props) : null; - var contentNode = this.blockDef.content ? + const contentNode = this.blockDef.content ? props.createBlock(this.blockDef.content).renderInstance(props) : null; return (React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, React.createElement(CollapsibleComponent, { label: labelNode, initialCollapsed: this.blockDef.initialCollapsed }, contentNode))); - }; - CollapsibleBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (React.createElement("div", null, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "initialCollapsed" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Initially Collapsed"); }))); - }; - return CollapsibleBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "initialCollapsed" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Initially Collapsed")))); + } +} exports.CollapsibleBlock = CollapsibleBlock; /** Collapsible UI control */ -var CollapsibleComponent = /** @class */ (function (_super) { - __extends(CollapsibleComponent, _super); - function CollapsibleComponent(props) { - var _this = _super.call(this, props) || this; - _this.handleToggle = function () { - if (!_this.props.forceOpen) { - _this.setState({ collapsed: !_this.state.collapsed }); +class CollapsibleComponent extends React.Component { + constructor(props) { + super(props); + this.handleToggle = () => { + if (!this.props.forceOpen) { + this.setState({ collapsed: !this.state.collapsed }); } }; - _this.state = { + this.state = { // Collapse if not forced open and initialCollapsed - collapsed: !(_this.props.forceOpen || false) && (_this.props.initialCollapsed || false) + collapsed: !(this.props.forceOpen || false) && (this.props.initialCollapsed || false) }; - return _this; } - CollapsibleComponent.prototype.render = function () { + render() { return React.createElement("div", null, React.createElement("table", { style: { width: "100%" } }, React.createElement("tbody", null, @@ -118,7 +97,6 @@ var CollapsibleComponent = /** @class */ (function (_super) { React.createElement("td", { key: "left", style: { verticalAlign: "middle", paddingRight: 5, fontSize: 18, color: "#3bd" } }, this.state.collapsed ? React.createElement("i", { className: "fa fa-caret-right" }) : React.createElement("i", { className: "fa fa-caret-down" })), React.createElement("td", { key: "main", style: { width: "100%", verticalAlign: "middle" } }, this.props.label)))), !this.state.collapsed ? this.props.children : null); - }; - return CollapsibleComponent; -}(React.Component)); + } +} exports.CollapsibleComponent = CollapsibleComponent; diff --git a/lib/widgets/blocks/conditional.js b/lib/widgets/blocks/conditional.js index 21c23c07..0f64e6db 100644 --- a/lib/widgets/blocks/conditional.js +++ b/lib/widgets/blocks/conditional.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,22 +23,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConditionalBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var ConditionalBlock = /** @class */ (function (_super) { - __extends(ConditionalBlock, _super); - function ConditionalBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ConditionalBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +class ConditionalBlock extends blocks_1.Block { + getChildren(contextVars) { if (this.blockDef.content) { return [{ blockDef: this.blockDef.content, contextVars: contextVars }]; } return []; - }; - ConditionalBlock.prototype.validate = function (ctx) { + } + validate(ctx) { return blocks_1.validateContextVarExpr({ schema: ctx.schema, contextVars: ctx.contextVars, @@ -70,45 +42,42 @@ var ConditionalBlock = /** @class */ (function (_super) { expr: this.blockDef.expr, types: ["boolean"] }); - }; - ConditionalBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; + } /** Get context variable expressions needed to add */ - ConditionalBlock.prototype.getContextVarExprs = function (contextVar) { + getContextVarExprs(contextVar) { return (contextVar.id === this.blockDef.contextVarId && this.blockDef.expr) ? [this.blockDef.expr] : []; - }; - ConditionalBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSetContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleSetContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = blockDef; return b; }), blockDef.id); }; - var contentNode = props.renderChildBlock(props, this.blockDef.content, handleSetContent); + const contentNode = props.renderChildBlock(props, this.blockDef.content, handleSetContent); return (React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5, border: "dashed 1px #CCC" } }, contentNode)); - }; - ConditionalBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { // Check expression value - var value = props.getContextVarExprValue(this.blockDef.contextVarId, this.blockDef.expr); + const value = props.getContextVarExprValue(this.blockDef.contextVarId, this.blockDef.expr); if (!value) { return React.createElement("div", null); } return React.createElement("div", null, props.renderChildBlock(props, this.blockDef.content)); - }; - ConditionalBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { return (React.createElement("div", null, React.createElement("h3", null, "Conditional"), React.createElement(propertyEditors_1.LabeledProperty, { label: "Conditional Expression" }, - React.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, aggrStatuses: ["individual", "aggregate", "literal"], types: ["boolean"], contextVarId: this.blockDef.contextVarId, expr: this.blockDef.expr, onChange: function (contextVarId, expr) { - props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { contextVarId: contextVarId, expr: expr })); + React.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, aggrStatuses: ["individual", "aggregate", "literal"], types: ["boolean"], contextVarId: this.blockDef.contextVarId, expr: this.blockDef.expr, onChange: (contextVarId, expr) => { + props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { contextVarId, expr })); } })))); - }; - return ConditionalBlock; -}(blocks_1.Block)); + } +} exports.ConditionalBlock = ConditionalBlock; diff --git a/lib/widgets/blocks/controls/ControlBlock.js b/lib/widgets/blocks/controls/ControlBlock.js index 89237600..c9be6d66 100644 --- a/lib/widgets/blocks/controls/ControlBlock.js +++ b/lib/widgets/blocks/controls/ControlBlock.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -40,112 +27,79 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ControlBlock = void 0; -var LeafBlock_1 = __importDefault(require("../../LeafBlock")); -var React = __importStar(require("react")); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var localization_1 = require("../../localization"); -var DataSourceDatabase_1 = require("../../../database/DataSourceDatabase"); -var scrolling_1 = require("../../scrolling"); -var collapsible_1 = require("../collapsible"); +const LeafBlock_1 = __importDefault(require("../../LeafBlock")); +const React = __importStar(require("react")); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const localization_1 = require("../../localization"); +const DataSourceDatabase_1 = require("../../../database/DataSourceDatabase"); +const scrolling_1 = require("../../scrolling"); +const collapsible_1 = require("../collapsible"); /** Abstract class for a control such as a dropdown, text field, etc that operates on a single column */ -var ControlBlock = /** @class */ (function (_super) { - __extends(ControlBlock, _super); - function ControlBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } +class ControlBlock extends LeafBlock_1.default { /** Implement this to render any editor parts that are not selecting the basic row cv and column */ - ControlBlock.prototype.renderControlEditor = function (props) { + renderControlEditor(props) { return null; - }; - ControlBlock.prototype.renderDesign = function (designCtx) { - var _this = this; - var renderControlProps = { + } + renderDesign(designCtx) { + const renderControlProps = { value: null, - rowContextVar: designCtx.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId; }), - onChange: function () { return; }, + rowContextVar: designCtx.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId), + onChange: () => { return; }, locale: designCtx.locale, database: new DataSourceDatabase_1.DataSourceDatabase(designCtx.schema, designCtx.dataSource), schema: designCtx.schema, dataSource: designCtx.dataSource, disabled: false, - getFilters: function () { return []; }, + getFilters: () => [], contextVars: designCtx.contextVars, contextVarValues: {}, formatLocale: designCtx.formatLocale }; return this.renderControl(renderControlProps); - }; - ControlBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement(ControlInstance, { instanceCtx: props, block: this }); - }; + } /** Allow subclasses to clear/update other fields on the column changing */ - ControlBlock.prototype.processColumnChanged = function (blockDef) { + processColumnChanged(blockDef) { // Default does nothing return blockDef; - }; - ControlBlock.prototype.renderEditor = function (props) { - var _this = this; - var contextVar = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId; }); - var handleColumnChanged = function (blockDef) { - props.store.replaceBlock(_this.processColumnChanged(blockDef)); + } + renderEditor(props) { + const contextVar = props.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId); + const handleColumnChanged = (blockDef) => { + props.store.replaceBlock(this.processColumnChanged(blockDef)); }; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Context Variable" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["row"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["row"] }))), contextVar ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Column" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: handleColumnChanged, property: "column" }, function (value, onChange) { - var columnOptions = props.schema.getColumns(contextVar.table) - .filter(function (c) { return _this.filterColumn(c); }) - .map(function (c) { return ({ value: c.id, label: localization_1.localize(c.name) }); }); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: handleColumnChanged, property: "column" }, (value, onChange) => { + const columnOptions = props.schema.getColumns(contextVar.table) + .filter(c => this.filterColumn(c)) + .map(c => ({ value: c.id, label: localization_1.localize(c.name) })); return React.createElement(bootstrap_1.Select, { value: value, onChange: onChange, nullLabel: "Select column", options: columnOptions }); })) : null, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "required" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Required"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "required" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Required")), this.blockDef.required ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Required Message" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "requiredMessage" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "requiredMessage" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))) : null, this.renderControlEditor(props), React.createElement("br", null), React.createElement(collapsible_1.CollapsibleComponent, { label: "Optional Readonly Expression", initialCollapsed: true }, React.createElement(propertyEditors_1.LabeledProperty, { label: "Readonly", hint: "optional expression that makes read-only if true" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "readonlyExpr" }, function (value, onChange) { return (React.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, contextVarId: value ? value.contextVarId : null, expr: value ? value.expr : null, onChange: function (contextVarId, expr) { onChange({ contextVarId: contextVarId, expr: expr }); }, types: ["boolean"] })); }))))); - }; - ControlBlock.prototype.getContextVarExprs = function (contextVar) { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "readonlyExpr" }, (value, onChange) => (React.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, contextVarId: value ? value.contextVarId : null, expr: value ? value.expr : null, onChange: (contextVarId, expr) => { onChange({ contextVarId, expr }); }, types: ["boolean"] }))))))); + } + getContextVarExprs(contextVar) { if (this.blockDef.rowContextVarId && this.blockDef.rowContextVarId === contextVar.id && this.blockDef.column) { return [ { type: "id", table: contextVar.table }, @@ -155,12 +109,11 @@ var ControlBlock = /** @class */ (function (_super) { else { return []; } - }; + } /** Determine if block is valid. null means valid, string is error message. Does not validate children */ - ControlBlock.prototype.validate = function (options) { - var _this = this; + validate(options) { // Validate row - var rowCV = options.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId && cv.type === "row"; }); + const rowCV = options.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId && cv.type === "row"); if (!rowCV) { return "Row required"; } @@ -171,97 +124,79 @@ var ControlBlock = /** @class */ (function (_super) { return "Valid column required"; } return null; - }; - return ControlBlock; -}(LeafBlock_1.default)); + } +} exports.ControlBlock = ControlBlock; -var ControlInstance = /** @class */ (function (_super) { - __extends(ControlInstance, _super); - function ControlInstance(props) { - var _this = _super.call(this, props) || this; +class ControlInstance extends React.Component { + constructor(props) { + super(props); /** Validate the instance. Returns null if correct, message if not */ - _this.validate = function (isFirstError) { + this.validate = (isFirstError) => { // Check for null - if (_this.getValue() == null && _this.props.block.blockDef.required) { - _this.setState({ requiredError: _this.props.block.blockDef.requiredMessage ? localization_1.localize(_this.props.block.blockDef.requiredMessage, _this.props.instanceCtx.locale) : "" }); + if (this.getValue() == null && this.props.block.blockDef.required) { + this.setState({ requiredError: this.props.block.blockDef.requiredMessage ? localization_1.localize(this.props.block.blockDef.requiredMessage, this.props.instanceCtx.locale) : "" }); // Scroll into view if first error - if (isFirstError && _this.controlRef.current && _this.controlRef.current.scrollIntoView) { - _this.controlRef.current.scrollIntoView(true); + if (isFirstError && this.controlRef.current && this.controlRef.current.scrollIntoView) { + this.controlRef.current.scrollIntoView(true); // Add some padding - var scrollParent = scrolling_1.getScrollParent(_this.controlRef.current); + const scrollParent = scrolling_1.getScrollParent(this.controlRef.current); if (scrollParent) scrollParent.scrollBy(0, -30); } return ""; } else { - _this.setState({ requiredError: null }); + this.setState({ requiredError: null }); return null; } }; - _this.handleChange = function (newValue) { return __awaiter(_this, void 0, void 0, function () { - var instanceCtx, blockDef, contextVar, id, txn, err_1; - var _a; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - instanceCtx = this.props.instanceCtx; - blockDef = this.props.block.blockDef; - contextVar = instanceCtx.contextVars.find(function (cv) { return cv.id === blockDef.rowContextVarId; }); - id = instanceCtx.getContextVarExprValue(blockDef.rowContextVarId, { type: "id", table: contextVar.table }); - // Update database - this.setState({ updating: true }); - _b.label = 1; - case 1: - _b.trys.push([1, 4, 5, 6]); - txn = this.props.instanceCtx.database.transaction(); - return [4 /*yield*/, txn.updateRow(contextVar.table, id, (_a = {}, _a[blockDef.column] = newValue, _a))]; - case 2: - _b.sent(); - return [4 /*yield*/, txn.commit()]; - case 3: - _b.sent(); - return [3 /*break*/, 6]; - case 4: - err_1 = _b.sent(); - // TODO localize - alert("Unable to save changes: " + err_1.message); - console.error(err_1.message); - return [3 /*break*/, 6]; - case 5: - this.setState({ updating: false }); - return [7 /*endfinally*/]; - case 6: return [2 /*return*/]; - } - }); - }); }; - _this.controlRef = React.createRef(); - _this.state = { + this.handleChange = (newValue) => __awaiter(this, void 0, void 0, function* () { + const instanceCtx = this.props.instanceCtx; + const blockDef = this.props.block.blockDef; + const contextVar = instanceCtx.contextVars.find(cv => cv.id === blockDef.rowContextVarId); + const id = instanceCtx.getContextVarExprValue(blockDef.rowContextVarId, { type: "id", table: contextVar.table }); + // Update database + this.setState({ updating: true }); + try { + const txn = this.props.instanceCtx.database.transaction(); + yield txn.updateRow(contextVar.table, id, { [blockDef.column]: newValue }); + yield txn.commit(); + } + catch (err) { + // TODO localize + alert("Unable to save changes: " + err.message); + console.error(err.message); + } + finally { + this.setState({ updating: false }); + } + }); + this.controlRef = React.createRef(); + this.state = { updating: false, requiredError: null }; - return _this; } - ControlInstance.prototype.componentDidMount = function () { + componentDidMount() { this.unregisterValidation = this.props.instanceCtx.registerForValidation(this.validate); - }; - ControlInstance.prototype.componentWillUnmount = function () { + } + componentWillUnmount() { this.unregisterValidation(); - }; - ControlInstance.prototype.getValue = function () { - var instanceCtx = this.props.instanceCtx; - var blockDef = this.props.block.blockDef; - var contextVar = instanceCtx.contextVars.find(function (cv) { return cv.id === blockDef.rowContextVarId; }); + } + getValue() { + const instanceCtx = this.props.instanceCtx; + const blockDef = this.props.block.blockDef; + const contextVar = instanceCtx.contextVars.find(cv => cv.id === blockDef.rowContextVarId); // Get current value return instanceCtx.getContextVarExprValue(blockDef.rowContextVarId, { type: "field", table: contextVar.table, column: blockDef.column }); - }; - ControlInstance.prototype.render = function () { - var instanceCtx = this.props.instanceCtx; - var blockDef = this.props.block.blockDef; - var contextVar = instanceCtx.contextVars.find(function (cv) { return cv.id === blockDef.rowContextVarId; }); - var id = instanceCtx.getContextVarExprValue(blockDef.rowContextVarId, { type: "id", table: contextVar.table }); - var readonly = blockDef.readonlyExpr ? instanceCtx.getContextVarExprValue(blockDef.readonlyExpr.contextVarId, blockDef.readonlyExpr.expr) : false; - var renderControlProps = { + } + render() { + const instanceCtx = this.props.instanceCtx; + const blockDef = this.props.block.blockDef; + const contextVar = instanceCtx.contextVars.find(cv => cv.id === blockDef.rowContextVarId); + const id = instanceCtx.getContextVarExprValue(blockDef.rowContextVarId, { type: "id", table: contextVar.table }); + const readonly = blockDef.readonlyExpr ? instanceCtx.getContextVarExprValue(blockDef.readonlyExpr.contextVarId, blockDef.readonlyExpr.expr) : false; + const renderControlProps = { value: this.getValue(), onChange: readonly ? undefined : this.handleChange, schema: this.props.instanceCtx.schema, @@ -274,7 +209,7 @@ var ControlInstance = /** @class */ (function (_super) { contextVars: this.props.instanceCtx.contextVars, contextVarValues: this.props.instanceCtx.contextVarValues }; - var style = { + const style = { opacity: this.state.updating ? 0.6 : undefined }; // Add red border if required @@ -288,6 +223,5 @@ var ControlInstance = /** @class */ (function (_super) { this.state.requiredError ? React.createElement("div", { key: "error", className: "text-danger" }, this.state.requiredError) : null)); - }; - return ControlInstance; -}(React.Component)); + } +} diff --git a/lib/widgets/blocks/controls/IdDropdownComponent.js b/lib/widgets/blocks/controls/IdDropdownComponent.js index c86fc26b..97952373 100644 --- a/lib/widgets/blocks/controls/IdDropdownComponent.js +++ b/lib/widgets/blocks/controls/IdDropdownComponent.js @@ -4,26 +4,26 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IdDropdownComponent = void 0; -var async_1 = __importDefault(require("react-select/async")); -var react_1 = require("react"); -var react_2 = __importDefault(require("react")); +const async_1 = __importDefault(require("react-select/async")); +const react_1 = require("react"); +const react_2 = __importDefault(require("react")); /** Displays a combo box that allows selecting one id value from a list */ function IdDropdownComponent(props) { - var _a = react_1.useState(), currentValue = _a[0], setCurrentValue = _a[1]; - var _b = react_1.useState(false), loading = _b[0], setLoading = _b[1]; + const [currentValue, setCurrentValue] = react_1.useState(); + const [loading, setLoading] = react_1.useState(false); /** Creates an option from a query row that is in form { id:, label0:, label1:, ...} */ - var rowToOption = function (row) { - var value = { id: row.id, labelValues: [] }; - for (var i = 0; i < props.labelEmbeddedExprs.length; i++) { - value.labelValues[i] = row["label" + i]; + const rowToOption = (row) => { + const value = { id: row.id, labelValues: [] }; + for (let i = 0; i < props.labelEmbeddedExprs.length; i++) { + value.labelValues[i] = row[`label${i}`]; } return value; }; // Load current value - react_1.useEffect(function () { + react_1.useEffect(() => { if (props.value) { setLoading(true); - var where = props.multi ? + const where = props.multi ? { type: "op", op: "= any", table: props.table, exprs: [ { type: "id", table: props.table }, { type: "literal", idTable: props.table, valueType: "id[]", value: props.value } @@ -33,7 +33,7 @@ function IdDropdownComponent(props) { { type: "id", table: props.table }, { type: "literal", idTable: props.table, valueType: "id", value: props.value } ] }; - var query = { + const query = { select: { id: { type: "id", table: props.table } }, @@ -41,14 +41,14 @@ function IdDropdownComponent(props) { where: where }; // Add label exprs - for (var i = 0; i < props.labelEmbeddedExprs.length; i++) { - query.select["label" + i] = props.labelEmbeddedExprs[i]; + for (let i = 0; i < props.labelEmbeddedExprs.length; i++) { + query.select[`label${i}`] = props.labelEmbeddedExprs[i]; } - var results = props.database.query(query, props.contextVars, props.contextVarValues); - results.then(function (rows) { + const results = props.database.query(query, props.contextVars, props.contextVarValues); + results.then((rows) => { if (props.multi) { if (rows[0]) { - setCurrentValue(rows.map(function (r) { return rowToOption(r); })); + setCurrentValue(rows.map(r => rowToOption(r))); } else { setCurrentValue(undefined); @@ -63,23 +63,22 @@ function IdDropdownComponent(props) { } } setLoading(false); - }).catch(function (err) { throw err; }); + }).catch(err => { throw err; }); } else { setCurrentValue(undefined); } }, [props.value, props.table, props.multi]); // Callback that react-select uses to get values - var loadOptions = react_1.useCallback(function (input, callback) { + const loadOptions = react_1.useCallback((input, callback) => { // Determine filter expressions - var filters = []; + const filters = []; if (input) { - var orFilter = { - type: "op", table: props.table, op: "or", - exprs: props.searchExprs.map(function (se) { return ({ type: "op", table: props.table, op: "~*", exprs: [ + const orFilter = { + type: "op", table: props.table, op: "or", exprs: props.searchExprs.map(se => ({ type: "op", table: props.table, op: "~*", exprs: [ se, { type: "literal", valueType: "text", value: "^" + escapeRegex(input) } - ] }); }) + ] })) }; filters.push(orFilter); } @@ -87,7 +86,7 @@ function IdDropdownComponent(props) { filters.push(props.filterExpr); } // Perform query to get options - var query = { + const query = { select: { id: { type: "id", table: props.table } }, @@ -97,34 +96,34 @@ function IdDropdownComponent(props) { limit: 50 }; // Add label exprs - for (var i = 0; i < props.labelEmbeddedExprs.length; i++) { - query.select["label" + i] = props.labelEmbeddedExprs[i]; + for (let i = 0; i < props.labelEmbeddedExprs.length; i++) { + query.select[`label${i}`] = props.labelEmbeddedExprs[i]; } - var results = props.database.query(query, props.contextVars, props.contextVarValues); - results.then(function (rows) { - callback(rows.map(function (r) { return rowToOption(r); })); + const results = props.database.query(query, props.contextVars, props.contextVarValues); + results.then((rows) => { + callback(rows.map(r => rowToOption(r))); }); }, [props.table, props.filterExpr]); - var handleChange = react_1.useCallback(function (option) { + const handleChange = react_1.useCallback((option) => { if (!props.onChange) { return; } if (props.multi) { - props.onChange(option && option.length > 0 ? option.map(function (v) { return v.id; }) : null); + props.onChange(option && option.length > 0 ? option.map((v) => v.id) : null); } else { props.onChange(option ? option.id : null); } }, [props.onChange]); - var getOptionLabel = react_1.useCallback(function (option) { + const getOptionLabel = react_1.useCallback((option) => { return props.formatLabel(option.labelValues); }, [props.formatLabel]); - var getOptionValue = react_1.useCallback(function (option) { + const getOptionValue = react_1.useCallback((option) => { return option.id + ""; }, []); return react_2.default.createElement("div", { style: { width: "100%", minWidth: 160 } }, - react_2.default.createElement(async_1.default, { value: currentValue, placeholder: props.placeholder, loadOptions: loadOptions, isMulti: props.multi, isClearable: true, isLoading: loading, onChange: props.onChange ? handleChange : undefined, isDisabled: !props.onChange, noOptionsMessage: function () { return "..."; }, defaultOptions: true, closeMenuOnScroll: true, menuPortalTarget: document.body, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, classNamePrefix: "react-select-short", styles: props.styles })); + react_2.default.createElement(async_1.default, { value: currentValue, placeholder: props.placeholder, loadOptions: loadOptions, isMulti: props.multi, isClearable: true, isLoading: loading, onChange: props.onChange ? handleChange : undefined, isDisabled: !props.onChange, noOptionsMessage: () => "...", defaultOptions: true, closeMenuOnScroll: true, menuPortalTarget: document.body, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, classNamePrefix: "react-select-short", styles: props.styles })); } exports.IdDropdownComponent = IdDropdownComponent; /** Escape a regex */ -var escapeRegex = function (str) { return str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); }; +const escapeRegex = (str) => str.replace(/[-\\^$*+?.()|[\]{}]/g, "\\$&"); diff --git a/lib/widgets/blocks/controls/datefield.js b/lib/widgets/blocks/controls/datefield.js index d6f341b4..f6c618cc 100644 --- a/lib/widgets/blocks/controls/datefield.js +++ b/lib/widgets/blocks/controls/datefield.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,84 +23,75 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DatefieldBlock = void 0; -var React = __importStar(require("react")); -var ControlBlock_1 = require("./ControlBlock"); -var localization_1 = require("../../localization"); -var propertyEditors_1 = require("../../propertyEditors"); -var react_datepicker_1 = __importDefault(require("react-datepicker")); -var moment_1 = __importDefault(require("moment")); -var react_dom_1 = __importDefault(require("react-dom")); +const React = __importStar(require("react")); +const ControlBlock_1 = require("./ControlBlock"); +const localization_1 = require("../../localization"); +const propertyEditors_1 = require("../../propertyEditors"); +const react_datepicker_1 = __importDefault(require("react-datepicker")); +const moment_1 = __importDefault(require("moment")); +const react_dom_1 = __importDefault(require("react-dom")); /** Block that is a text input control linked to a specific field */ -var DatefieldBlock = /** @class */ (function (_super) { - __extends(DatefieldBlock, _super); - function DatefieldBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - DatefieldBlock.prototype.renderControl = function (props) { +class DatefieldBlock extends ControlBlock_1.ControlBlock { + renderControl(props) { // Get column - var column; + let column; if (props.rowContextVar && this.blockDef.column) { column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); } - var datetime = column ? column.type === "datetime" : false; - var format = this.blockDef.format ? this.blockDef.format : (datetime ? "lll" : "ll"); + const datetime = column ? column.type === "datetime" : false; + const format = this.blockDef.format ? this.blockDef.format : (datetime ? "lll" : "ll"); return React.createElement(Datefield, { value: props.value, onChange: props.onChange, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), disabled: props.disabled || !props.onChange, datetime: datetime, format: format }); - }; + } /** Implement this to render any editor parts that are not selecting the basic row cv and column */ - DatefieldBlock.prototype.renderControlEditor = function (props) { - var _this = this; - var contextVar = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId; }); + renderControlEditor(props) { + const contextVar = props.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId); // Get column - var column; + let column; if (contextVar && this.blockDef.column) { column = props.schema.getColumn(contextVar.table, this.blockDef.column); } return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Placeholder" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), column && column.type === "date" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Date Format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, function (value, onChange) { return (React.createElement(propertyEditors_1.DateFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, (value, onChange) => (React.createElement(propertyEditors_1.DateFormatEditor, { value: value, onChange: onChange })))) : null, column && column.type === "datetime" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Date/time Format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, function (value, onChange) { return (React.createElement(propertyEditors_1.DatetimeFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, (value, onChange) => (React.createElement(propertyEditors_1.DatetimeFormatEditor, { value: value, onChange: onChange })))) : null)); - }; + } /** Filter the columns that this control is for */ - DatefieldBlock.prototype.filterColumn = function (column) { + filterColumn(column) { return column.type === "date" || column.type === "datetime"; - }; + } /** Clear format */ - DatefieldBlock.prototype.processColumnChanged = function (blockDef) { - return __assign(__assign({}, blockDef), { format: null }); - }; - return DatefieldBlock; -}(ControlBlock_1.ControlBlock)); + processColumnChanged(blockDef) { + return Object.assign(Object.assign({}, blockDef), { format: null }); + } +} exports.DatefieldBlock = DatefieldBlock; /** Date field */ -var Datefield = /** @class */ (function (_super) { - __extends(Datefield, _super); - function Datefield() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleChange = function (value) { - if (!_this.props.onChange) { +class Datefield extends React.Component { + constructor() { + super(...arguments); + this.handleChange = (value) => { + if (!this.props.onChange) { return; } - if (_this.props.datetime) { - _this.props.onChange(value ? value.toISOString() : null); + if (this.props.datetime) { + this.props.onChange(value ? value.toISOString() : null); } else { - _this.props.onChange(value ? value.format("YYYY-MM-DD") : null); + this.props.onChange(value ? value.format("YYYY-MM-DD") : null); } }; - return _this; } - Datefield.prototype.render = function () { + render() { return (React.createElement(react_datepicker_1.default, { isClearable: true, placeholderText: this.props.placeholder, disabled: this.props.disabled || !this.props.onChange, selected: this.props.value ? moment_1.default(this.props.value, moment_1.default.ISO_8601) : null, onChange: this.handleChange, showTimeSelect: this.props.datetime, timeFormat: "HH:mm", dateFormat: this.props.format, className: "form-control", popperContainer: createPopperContainer, showMonthDropdown: true, showYearDropdown: true })); - }; - return Datefield; -}(React.Component)); + } +} // https://github.com/Hacker0x01/react-datepicker/issues/1366 function createPopperContainer(props) { return react_dom_1.default.createPortal(React.createElement("div", { style: { zIndex: 10000 } }, props.children), document.body); diff --git a/lib/widgets/blocks/controls/dropdown.js b/lib/widgets/blocks/controls/dropdown.js index 98b3f6ec..7f10219c 100644 --- a/lib/widgets/blocks/controls/dropdown.js +++ b/lib/widgets/blocks/controls/dropdown.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,29 +23,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DropdownBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var React = __importStar(require("react")); -var blocks_1 = require("../../blocks"); -var ControlBlock_1 = require("./ControlBlock"); -var mwater_expressions_1 = require("mwater-expressions"); -var localization_1 = require("../../localization"); -var propertyEditors_1 = require("../../propertyEditors"); -var react_select_1 = __importDefault(require("react-select")); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var IdDropdownComponent_1 = require("./IdDropdownComponent"); -var embeddedExprs_1 = require("../../../embeddedExprs"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var ListEditor_1 = __importDefault(require("../../ListEditor")); -var DropdownBlock = /** @class */ (function (_super) { - __extends(DropdownBlock, _super); - function DropdownBlock() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.formatIdLabel = function (ctx, labelValues) { - if (_this.blockDef.idMode == "advanced") { +const lodash_1 = __importDefault(require("lodash")); +const React = __importStar(require("react")); +const blocks_1 = require("../../blocks"); +const ControlBlock_1 = require("./ControlBlock"); +const mwater_expressions_1 = require("mwater-expressions"); +const localization_1 = require("../../localization"); +const propertyEditors_1 = require("../../propertyEditors"); +const react_select_1 = __importDefault(require("react-select")); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const IdDropdownComponent_1 = require("./IdDropdownComponent"); +const embeddedExprs_1 = require("../../../embeddedExprs"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const ListEditor_1 = __importDefault(require("../../ListEditor")); +class DropdownBlock extends ControlBlock_1.ControlBlock { + constructor() { + super(...arguments); + this.formatIdLabel = (ctx, labelValues) => { + if (this.blockDef.idMode == "advanced") { return embeddedExprs_1.formatEmbeddedExprString({ - text: localization_1.localize(_this.blockDef.idLabelText, ctx.locale), + text: localization_1.localize(this.blockDef.idLabelText, ctx.locale), contextVars: [], - embeddedExprs: _this.blockDef.idLabelEmbeddedExprs, + embeddedExprs: this.blockDef.idLabelEmbeddedExprs, exprValues: labelValues, formatLocale: ctx.formatLocale, locale: ctx.locale, @@ -80,20 +55,18 @@ var DropdownBlock = /** @class */ (function (_super) { return labelValues[0]; } }; - return _this; } - DropdownBlock.prototype.validate = function (options) { - var _this = this; - var error = _super.prototype.validate.call(this, options); + validate(options) { + let error = super.validate(options); if (error) { return error; } - var contextVar = options.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId; }); - var column = options.schema.getColumn(contextVar.table, this.blockDef.column); + const contextVar = options.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId); + const column = options.schema.getColumn(contextVar.table, this.blockDef.column); if (column.type === "id" || column.type == "id[]" || column.type == "join") { - var idMode = this.blockDef.idMode || "simple"; - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - var idTable = column.type == "join" ? column.join.toTable : column.idTable; + const idMode = this.blockDef.idMode || "simple"; + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + const idTable = column.type == "join" ? column.join.toTable : column.idTable; if (idMode == "simple") { if (!this.blockDef.idLabelExpr) { return "Label Expression required"; @@ -128,16 +101,14 @@ var DropdownBlock = /** @class */ (function (_super) { return error; } // Validate orderBy - for (var _i = 0, _a = this.blockDef.idOrderBy || []; _i < _a.length; _i++) { - var orderBy = _a[_i]; + for (const orderBy of this.blockDef.idOrderBy || []) { error = exprValidator.validateExpr(orderBy.expr, { table: idTable }); if (error) { return error; } } // Validate search - for (var _b = 0, _c = this.blockDef.idSearchExprs; _b < _c.length; _b++) { - var searchExpr = _c[_b]; + for (const searchExpr of this.blockDef.idSearchExprs) { if (!searchExpr) { return "Search expression required"; } @@ -150,22 +121,22 @@ var DropdownBlock = /** @class */ (function (_super) { } } return null; - }; + } /** Generate a single synthetic context variable to allow embedded expressions to work in label */ - DropdownBlock.prototype.generateEmbedContextVars = function (idTable) { + generateEmbedContextVars(idTable) { return [ { id: "dropdown-embed", name: "Label", table: idTable, type: "row" } ]; - }; - DropdownBlock.prototype.renderControl = function (props) { + } + renderControl(props) { // If can't be rendered due to missing context variable, just show placeholder if (!props.rowContextVar || !this.blockDef.column) { - return React.createElement(react_select_1.default, { menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); + return React.createElement(react_select_1.default, { menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); } // Get column - var column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); + const column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); if (!column) { - return React.createElement(react_select_1.default, { menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); + return React.createElement(react_select_1.default, { menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); } if (column.type === "enum") { return this.renderEnum(props, column); @@ -187,59 +158,57 @@ var DropdownBlock = /** @class */ (function (_super) { return this.renderId(props, column); } throw new Error("Unsupported type"); - }; - DropdownBlock.prototype.renderEnum = function (props, column) { - var _this = this; + } + renderEnum(props, column) { var enumValues = column.enumValues; // Handle include/exclude if (this.blockDef.includeValues && this.blockDef.includeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return _this.blockDef.includeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => this.blockDef.includeValues.includes(ev.id)); } if (this.blockDef.excludeValues && this.blockDef.excludeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return !_this.blockDef.excludeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => !this.blockDef.excludeValues.includes(ev.id)); } // Lookup enumvalue - var enumValue = enumValues.find(function (ev) { return ev.id === props.value; }) || null; - var getOptionLabel = function (ev) { return localization_1.localize(ev.name, props.locale); }; - var getOptionValue = function (ev) { return ev.id; }; - var handleChange = function (ev) { + const enumValue = enumValues.find(ev => ev.id === props.value) || null; + const getOptionLabel = (ev) => localization_1.localize(ev.name, props.locale); + const getOptionValue = (ev) => ev.id; + const handleChange = (ev) => { if (props.onChange) { props.onChange(ev ? ev.id : null); } }; - return React.createElement(react_select_1.default, { value: enumValue, onChange: handleChange, options: enumValues, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isDisabled: props.disabled || !props.onChange, isClearable: true, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); - }; - DropdownBlock.prototype.renderEnumset = function (props, column) { - var _this = this; + return React.createElement(react_select_1.default, { value: enumValue, onChange: handleChange, options: enumValues, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isDisabled: props.disabled || !props.onChange, isClearable: true, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); + } + renderEnumset(props, column) { var enumValues = column.enumValues; // Handle include/exclude if (this.blockDef.includeValues && this.blockDef.includeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return _this.blockDef.includeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => this.blockDef.includeValues.includes(ev.id)); } if (this.blockDef.excludeValues && this.blockDef.excludeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return !_this.blockDef.excludeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => !this.blockDef.excludeValues.includes(ev.id)); } // Map value to array - var value = null; + let value = null; if (props.value) { - value = lodash_1.default.compact(props.value.map(function (v) { return enumValues.find(function (ev) { return ev.id === v; }); })); + value = lodash_1.default.compact(props.value.map((v) => enumValues.find(ev => ev.id === v))); } - var getOptionLabel = function (ev) { return localization_1.localize(ev.name, props.locale); }; - var getOptionValue = function (ev) { return ev.id; }; - var handleChange = function (evs) { + const getOptionLabel = (ev) => localization_1.localize(ev.name, props.locale); + const getOptionValue = (ev) => ev.id; + const handleChange = (evs) => { if (props.onChange) { - props.onChange(evs && evs.length > 0 ? evs.map(function (ev) { return ev.id; }) : null); + props.onChange(evs && evs.length > 0 ? evs.map(ev => ev.id) : null); } }; - return React.createElement(react_select_1.default, { value: value, onChange: handleChange, options: enumValues, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isDisabled: props.disabled || !props.onChange, isClearable: true, isMulti: true, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); - }; - DropdownBlock.prototype.renderId = function (props, column) { - var labelEmbeddedExprs; - var searchExprs; - var orderBy; + return React.createElement(react_select_1.default, { value: value, onChange: handleChange, options: enumValues, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isDisabled: props.disabled || !props.onChange, isClearable: true, isMulti: true, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short", styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); + } + renderId(props, column) { + let labelEmbeddedExprs; + let searchExprs; + let orderBy; // Handle modes if (this.blockDef.idMode == "advanced") { - labelEmbeddedExprs = (this.blockDef.idLabelEmbeddedExprs || []).map(function (ee) { return ee.expr; }); + labelEmbeddedExprs = (this.blockDef.idLabelEmbeddedExprs || []).map(ee => ee.expr); searchExprs = this.blockDef.idSearchExprs || []; orderBy = this.blockDef.idOrderBy || []; } @@ -249,16 +218,16 @@ var DropdownBlock = /** @class */ (function (_super) { orderBy = [{ expr: this.blockDef.idLabelExpr, dir: "asc" }]; } // Dropdowns support n-1 and 1-1 joins as well as id columns - var idTable = column.type == "join" ? column.join.toTable : column.idTable; - return React.createElement(IdDropdownComponent_1.IdDropdownComponent, { database: props.database, table: idTable, value: props.value, onChange: props.onChange, multi: false, labelEmbeddedExprs: labelEmbeddedExprs, searchExprs: searchExprs, orderBy: orderBy, filterExpr: this.blockDef.idFilterExpr || null, formatLabel: this.formatIdLabel.bind(null, props), contextVars: props.contextVars, contextVarValues: props.contextVarValues, styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); - }; - DropdownBlock.prototype.renderIds = function (props, column) { - var labelEmbeddedExprs; - var searchExprs; - var orderBy; + const idTable = column.type == "join" ? column.join.toTable : column.idTable; + return React.createElement(IdDropdownComponent_1.IdDropdownComponent, { database: props.database, table: idTable, value: props.value, onChange: props.onChange, multi: false, labelEmbeddedExprs: labelEmbeddedExprs, searchExprs: searchExprs, orderBy: orderBy, filterExpr: this.blockDef.idFilterExpr || null, formatLabel: this.formatIdLabel.bind(null, props), contextVars: props.contextVars, contextVarValues: props.contextVarValues, styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); + } + renderIds(props, column) { + let labelEmbeddedExprs; + let searchExprs; + let orderBy; // Handle modes if (this.blockDef.idMode == "advanced") { - labelEmbeddedExprs = (this.blockDef.idLabelEmbeddedExprs || []).map(function (ee) { return ee.expr; }); + labelEmbeddedExprs = (this.blockDef.idLabelEmbeddedExprs || []).map(ee => ee.expr); searchExprs = this.blockDef.idSearchExprs || []; orderBy = this.blockDef.idOrderBy || []; } @@ -267,86 +236,81 @@ var DropdownBlock = /** @class */ (function (_super) { searchExprs = [this.blockDef.idLabelExpr]; orderBy = [{ expr: this.blockDef.idLabelExpr, dir: "asc" }]; } - return React.createElement(IdDropdownComponent_1.IdDropdownComponent, { database: props.database, table: column.idTable, value: props.value, onChange: props.onChange, multi: true, labelEmbeddedExprs: labelEmbeddedExprs, searchExprs: searchExprs, orderBy: orderBy, filterExpr: this.blockDef.idFilterExpr || null, formatLabel: this.formatIdLabel.bind(null, props), contextVars: props.contextVars, contextVarValues: props.contextVarValues, styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); - }; - DropdownBlock.prototype.renderBoolean = function (props, column) { + return React.createElement(IdDropdownComponent_1.IdDropdownComponent, { database: props.database, table: column.idTable, value: props.value, onChange: props.onChange, multi: true, labelEmbeddedExprs: labelEmbeddedExprs, searchExprs: searchExprs, orderBy: orderBy, filterExpr: this.blockDef.idFilterExpr || null, formatLabel: this.formatIdLabel.bind(null, props), contextVars: props.contextVars, contextVarValues: props.contextVarValues, styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); + } + renderBoolean(props, column) { console.log(props.value); return React.createElement(bootstrap_1.Select, { options: [ { value: true, label: localization_1.localize(this.blockDef.trueLabel) || "Yes" }, { value: false, label: localization_1.localize(this.blockDef.falseLabel) || "No" } ], value: props.value, onChange: props.onChange, nullLabel: "" }); - }; + } /** Implement this to render any editor parts that are not selecting the basic row cv and column */ - DropdownBlock.prototype.renderControlEditor = function (props) { - var _this = this; - var contextVar = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId; }); - var column = null; + renderControlEditor(props) { + const contextVar = props.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId); + let column = null; if (contextVar && contextVar.table && this.blockDef.column) { column = props.schema.getColumn(contextVar.table, this.blockDef.column); } - var isIdType = column && (column.type == "id" || column.type == "id[]" || column.type == "join"); - var idMode = this.blockDef.idMode || "simple"; - var idTable = column ? column.idTable : null; - var isBooleanType = column && column.type == "boolean"; - var handleConvertToToggle = function () { + const isIdType = column && (column.type == "id" || column.type == "id[]" || column.type == "join"); + const idMode = this.blockDef.idMode || "simple"; + const idTable = column ? column.idTable : null; + const isBooleanType = column && column.type == "boolean"; + const handleConvertToToggle = () => { props.store.replaceBlock({ - id: _this.blockDef.id, + id: this.blockDef.id, type: "toggle", - column: _this.blockDef.column, - required: _this.blockDef.required, - requiredMessage: _this.blockDef.requiredMessage, - rowContextVarId: _this.blockDef.rowContextVarId, - includeValues: _this.blockDef.includeValues, - excludeValues: _this.blockDef.excludeValues + column: this.blockDef.column, + required: this.blockDef.required, + requiredMessage: this.blockDef.requiredMessage, + rowContextVarId: this.blockDef.rowContextVarId, + includeValues: this.blockDef.includeValues, + excludeValues: this.blockDef.excludeValues }); }; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Placeholder", key: "placeholder" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), isIdType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Mode", key: "mode" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idMode" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value || "simple", onChange: onChange, options: [ - { value: "simple", label: "Simple" }, - { value: "advanced", label: "Advanced" } - ] }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idMode" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "simple", onChange: onChange, options: [ + { value: "simple", label: "Simple" }, + { value: "advanced", label: "Advanced" } + ] }))) : null, isIdType && idMode == "simple" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label Expression", key: "idLabelExpr" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idLabelExpr" }, function (value, onChange) { return React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value || null, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["text"], table: idTable }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idLabelExpr" }, (value, onChange) => React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value || null, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["text"], table: idTable }))) : null, isIdType && idMode == "advanced" ? React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Label", key: "idLabelText" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idLabelText" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idLabelText" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Embedded label expressions", help: "Reference in text as {0}, {1}, etc.", key: "idLabelEmbeddedExprs" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idLabelEmbeddedExprs" }, function (value, onChange) { return (React.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: _this.generateEmbedContextVars(idTable) })); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idLabelEmbeddedExprs" }, (value, onChange) => (React.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: this.generateEmbedContextVars(idTable) })))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Option ordering", key: "idOrderBy" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idOrderBy" }, function (value, onChange) { - return React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value || [], onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: idTable }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idOrderBy" }, (value, onChange) => React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value || [], onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: idTable }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Search expressions", key: "idSearchExprs" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idSearchExprs" }, function (value, onItemsChange) { - var handleAddSearchExpr = function () { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idSearchExprs" }, (value, onItemsChange) => { + const handleAddSearchExpr = () => { onItemsChange((value || []).concat(null)); }; return (React.createElement("div", null, - React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onItemsChange }, function (expr, onExprChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: expr, schema: props.schema, dataSource: props.dataSource, onChange: onExprChange, table: idTable, types: ["text", "enum", "enumset"], variables: blocks_1.createExprVariables(props.contextVars) })); }), + React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onItemsChange }, (expr, onExprChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: expr, schema: props.schema, dataSource: props.dataSource, onChange: onExprChange, table: idTable, types: ["text", "enum", "enumset"], variables: blocks_1.createExprVariables(props.contextVars) }))), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddSearchExpr }, "+ Add Expression"))); }))) : null, isIdType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter Expression", key: "idFilterExpr" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idFilterExpr" }, function (value, onChange) { return React.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: idTable, variables: blocks_1.createExprVariables(props.contextVars) }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idFilterExpr" }, (value, onChange) => React.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: idTable, variables: blocks_1.createExprVariables(props.contextVars) }))) : null, column && (column.type === "enum" || column.type === "enumset") ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Include Values", key: "includeValues" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "includeValues" }, function (value, onChange) { return React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "includeValues" }, (value, onChange) => React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }))) : null, column && (column.type === "enum" || column.type === "enumset") ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Exclude Values", key: "excludeValues" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "excludeValues" }, function (value, onChange) { return React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "excludeValues" }, (value, onChange) => React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }))) : null, !isIdType ? React.createElement("div", { key: "convert_to_toggle" }, @@ -354,15 +318,15 @@ var DropdownBlock = /** @class */ (function (_super) { : null, isBooleanType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label for true", key: "trueLabel", hint: "Must be set to allow localization" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "trueLabel" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "Yes" }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "trueLabel" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "Yes" }))) : null, isBooleanType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label for false", key: "falseLabel", hint: "Must be set to allow localization" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "falseLabel" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "No" }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "falseLabel" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "No" }))) : null)); - }; + } /** Filter the columns that this control is for. Can't be expression */ - DropdownBlock.prototype.filterColumn = function (column) { + filterColumn(column) { if (column.expr) { return false; } @@ -372,7 +336,6 @@ var DropdownBlock = /** @class */ (function (_super) { || column.type === "id[]" || column.type == "boolean" || (column.type == "join" && (column.join.type === "n-1" || column.join.type === "1-1")); - }; - return DropdownBlock; -}(ControlBlock_1.ControlBlock)); + } +} exports.DropdownBlock = DropdownBlock; diff --git a/lib/widgets/blocks/controls/numberbox.js b/lib/widgets/blocks/controls/numberbox.js index b7556eb9..69121ef8 100644 --- a/lib/widgets/blocks/controls/numberbox.js +++ b/lib/widgets/blocks/controls/numberbox.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,37 +20,32 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NumberboxBlock = void 0; -var React = __importStar(require("react")); -var ControlBlock_1 = require("./ControlBlock"); -var localization_1 = require("../../localization"); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var NumberboxBlock = /** @class */ (function (_super) { - __extends(NumberboxBlock, _super); - function NumberboxBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - NumberboxBlock.prototype.renderControl = function (props) { +const React = __importStar(require("react")); +const ControlBlock_1 = require("./ControlBlock"); +const localization_1 = require("../../localization"); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +class NumberboxBlock extends ControlBlock_1.ControlBlock { + renderControl(props) { return React.createElement(bootstrap_1.NumberInput, { value: props.value, onChange: props.onChange, style: { maxWidth: "12em", width: "100%" }, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), decimal: this.blockDef.decimal, decimalPlaces: this.blockDef.decimalPlaces != null ? this.blockDef.decimalPlaces : undefined }); - }; + } /** Implement this to render any editor parts that are not selecting the basic row cv and column */ - NumberboxBlock.prototype.renderControlEditor = function (props) { + renderControlEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Placeholder" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "decimal" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, " Decimal Number"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "decimal" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, " Decimal Number")), this.blockDef.decimal ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Decimal Places" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "decimalPlaces" }, function (value, onChange) { return React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: false }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "decimalPlaces" }, (value, onChange) => React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: false }))) : null)); - }; + } /** Filter the columns that this control is for. Can't be expression */ - NumberboxBlock.prototype.filterColumn = function (column) { + filterColumn(column) { if (column.expr) { return false; } return column.type === "number"; - }; - return NumberboxBlock; -}(ControlBlock_1.ControlBlock)); + } +} exports.NumberboxBlock = NumberboxBlock; diff --git a/lib/widgets/blocks/controls/tagsEditor.js b/lib/widgets/blocks/controls/tagsEditor.js index 9c609e89..db4fe87a 100644 --- a/lib/widgets/blocks/controls/tagsEditor.js +++ b/lib/widgets/blocks/controls/tagsEditor.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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) { @@ -32,162 +8,108 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TagsEditorBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importDefault(require("react")); -var ControlBlock_1 = require("./ControlBlock"); -var async_creatable_1 = __importDefault(require("react-select/async-creatable")); -var react_select_1 = __importDefault(require("react-select")); +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importDefault(require("react")); +const ControlBlock_1 = require("./ControlBlock"); +const async_creatable_1 = __importDefault(require("react-select/async-creatable")); +const react_select_1 = __importDefault(require("react-select")); /** Block which shows a dropdown control to select existing or create new tags */ -var TagsEditorBlock = /** @class */ (function (_super) { - __extends(TagsEditorBlock, _super); - function TagsEditorBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - TagsEditorBlock.prototype.renderControl = function (props) { - var styles = { - control: function (base) { return (__assign(__assign({}, base), { minWidth: 150 })); }, +class TagsEditorBlock extends ControlBlock_1.ControlBlock { + renderControl(props) { + const styles = { + control: (base) => (Object.assign(Object.assign({}, base), { minWidth: 150 })), // Keep menu above other controls - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; // If can't be displayed properly - var defaultControl = react_1.default.createElement("div", { style: { padding: 5 } }, + const defaultControl = react_1.default.createElement("div", { style: { padding: 5 } }, react_1.default.createElement(react_select_1.default, { classNamePrefix: "react-select-short", styles: styles, menuPortalTarget: document.body })); // If can't be rendered due to missing context variable, just show error if (!props.rowContextVar || !this.blockDef.column) { return defaultControl; } // Get column - var column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); + const column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); if (!column) { return defaultControl; } return react_1.default.createElement(TagEditorInstance, { table: props.rowContextVar.table, disabled: props.disabled, column: column.id, database: props.database, value: props.value, onChange: props.onChange }); - }; + } /** Filter the columns that this control is for. Must be text[] */ - TagsEditorBlock.prototype.filterColumn = function (column) { + filterColumn(column) { return (!column.expr && column.type == "text[]"); - }; - return TagsEditorBlock; -}(ControlBlock_1.ControlBlock)); + } +} exports.TagsEditorBlock = TagsEditorBlock; /** Allows editing of a series of tags, allowing selecting existing or creating new */ -var TagEditorInstance = /** @class */ (function (_super) { - __extends(TagEditorInstance, _super); - function TagEditorInstance() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.getOptions = function (input) { return __awaiter(_this, void 0, void 0, function () { - var _a; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - if (!!this.options) return [3 /*break*/, 2]; - _a = this; - return [4 /*yield*/, this.loadOptions()]; - case 1: - _a.options = _b.sent(); - _b.label = 2; - case 2: - // Filter by input string - if (input) { - return [2 /*return*/, this.options.filter(function (o) { return o.label.toLowerCase().startsWith(input.toLowerCase()); })]; - } - else { - return [2 /*return*/, this.options]; - } - return [2 /*return*/]; - } - }); - }); }; - _this.handleChange = function (value) { - if (!_this.props.onChange) { +class TagEditorInstance extends react_1.default.Component { + constructor() { + super(...arguments); + this.getOptions = (input) => __awaiter(this, void 0, void 0, function* () { + // Load options if not loaded + if (!this.options) { + this.options = yield this.loadOptions(); + } + // Filter by input string + if (input) { + return this.options.filter(o => o.label.toLowerCase().startsWith(input.toLowerCase())); + } + else { + return this.options; + } + }); + this.handleChange = (value) => { + if (!this.props.onChange) { return; } if (value) { - _this.props.onChange(value.map(function (v) { return v.value; })); + this.props.onChange(value.map((v) => v.value)); } else { - _this.props.onChange(null); + this.props.onChange(null); } }; - return _this; } - TagEditorInstance.prototype.loadOptions = function () { - return __awaiter(this, void 0, void 0, function () { - var _a, table, column, queryOptions, rows, values, err_1; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - _a = this.props, table = _a.table, column = _a.column; - queryOptions = { - select: { value: { type: "field", table: table, column: column } }, - distinct: true, - from: table, - where: { - type: "op", - op: "is not null", - table: table, - exprs: [{ type: "field", table: table, column: column }] - }, - limit: 250 - }; - _b.label = 1; - case 1: - _b.trys.push([1, 3, , 4]); - return [4 /*yield*/, this.props.database.query(queryOptions, [], {}) - // Flatten and keep distinct - ]; - case 2: - rows = _b.sent(); - values = lodash_1.default.uniq(lodash_1.default.flatten(rows.map(function (r) { return r.value; }))).sort(); - return [2 /*return*/, values.map(function (v) { return ({ value: v, label: v }); })]; - case 3: - err_1 = _b.sent(); - // TODO localize - alert("Unable to load options"); - return [2 /*return*/, []]; - case 4: return [2 /*return*/]; - } - }); + loadOptions() { + return __awaiter(this, void 0, void 0, function* () { + const { table, column } = this.props; + // Query all distinct values, which will include possibly more than one copy of each text string, as it + // can appear in different combinations + const queryOptions = { + select: { value: { type: "field", table, column } }, + distinct: true, + from: table, + where: { + type: "op", + op: "is not null", + table, + exprs: [{ type: "field", table, column }] + }, + limit: 250 + }; + try { + const rows = yield this.props.database.query(queryOptions, [], {}); + // Flatten and keep distinct + const values = lodash_1.default.uniq(lodash_1.default.flatten(rows.map(r => r.value))).sort(); + return values.map(v => ({ value: v, label: v })); + } + catch (err) { + // TODO localize + alert("Unable to load options"); + return []; + } }); - }; - TagEditorInstance.prototype.render = function () { - var styles = { - control: function (style) { return (__assign({}, style)); }, - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + } + render() { + const styles = { + control: (style) => (Object.assign({}, style)), + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; - return react_1.default.createElement(async_creatable_1.default, { cacheOptions: true, defaultOptions: true, loadOptions: this.getOptions, styles: styles, value: this.props.value ? this.props.value.map(function (v) { return ({ value: v, label: v }); }) : null, classNamePrefix: "react-select-short", menuPortalTarget: document.body, isMulti: true, onChange: this.handleChange, isDisabled: this.props.disabled || !this.props.onChange }); - }; - return TagEditorInstance; -}(react_1.default.Component)); + return react_1.default.createElement(async_creatable_1.default, { cacheOptions: true, defaultOptions: true, loadOptions: this.getOptions, styles: styles, value: this.props.value ? this.props.value.map(v => ({ value: v, label: v })) : null, classNamePrefix: "react-select-short", menuPortalTarget: document.body, isMulti: true, onChange: this.handleChange, isDisabled: this.props.disabled || !this.props.onChange }); + } +} diff --git a/lib/widgets/blocks/controls/textbox.js b/lib/widgets/blocks/controls/textbox.js index 727bf924..8fdc5d88 100644 --- a/lib/widgets/blocks/controls/textbox.js +++ b/lib/widgets/blocks/controls/textbox.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,72 +20,64 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TextboxBlock = void 0; -var React = __importStar(require("react")); -var ControlBlock_1 = require("./ControlBlock"); -var localization_1 = require("../../localization"); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); +const React = __importStar(require("react")); +const ControlBlock_1 = require("./ControlBlock"); +const localization_1 = require("../../localization"); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); require("./textbox.css"); /** Block that is a text input control linked to a specific field */ -var TextboxBlock = /** @class */ (function (_super) { - __extends(TextboxBlock, _super); - function TextboxBlock() { - return _super !== null && _super.apply(this, arguments) || this; +class TextboxBlock extends ControlBlock_1.ControlBlock { + renderControl(props) { + return React.createElement(Textbox, { value: props.value, onChange: props.onChange ? props.onChange : () => { }, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), disabled: props.disabled || !props.onChange, numLines: this.blockDef.numLines || undefined, editOnFocus: this.blockDef.editOnFocus || false }); } - TextboxBlock.prototype.renderControl = function (props) { - return React.createElement(Textbox, { value: props.value, onChange: props.onChange ? props.onChange : function () { }, placeholder: localization_1.localize(this.blockDef.placeholder, props.locale), disabled: props.disabled || !props.onChange, numLines: this.blockDef.numLines || undefined, editOnFocus: this.blockDef.editOnFocus || false }); - }; /** Implement this to render any editor parts that are not selecting the basic row cv and column */ - TextboxBlock.prototype.renderControlEditor = function (props) { + renderControlEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Placeholder" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Number of lines" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "numLines" }, function (value, onChange) { return React.createElement(bootstrap_1.NumberInput, { value: value || 1, onChange: onChange, decimal: false }); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "editOnFocus" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Edit On Focus"); }))); - }; + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "numLines" }, (value, onChange) => React.createElement(bootstrap_1.NumberInput, { value: value || 1, onChange: onChange, decimal: false }))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "editOnFocus" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Edit On Focus")))); + } /** Filter the columns that this control is for */ - TextboxBlock.prototype.filterColumn = function (column) { + filterColumn(column) { return column.type === "text"; - }; - return TextboxBlock; -}(ControlBlock_1.ControlBlock)); + } +} exports.TextboxBlock = TextboxBlock; /** Text box that updates only on blur */ -var Textbox = /** @class */ (function (_super) { - __extends(Textbox, _super); - function Textbox(props) { - var _this = _super.call(this, props) || this; - _this.handleFocus = function () { +class Textbox extends React.Component { + constructor(props) { + super(props); + this.handleFocus = () => { // Start tracking state internally - _this.setState({ text: _this.props.value, focused: true }); + this.setState({ text: this.props.value, focused: true }); }; - _this.handleBlur = function (ev) { + this.handleBlur = (ev) => { // Stop tracking state internally - _this.setState({ text: null, focused: false }); + this.setState({ text: null, focused: false }); // Only change if different - var value = ev.target.value || null; - if (value !== _this.props.value) { - _this.props.onChange(value); + const value = ev.target.value || null; + if (value !== this.props.value) { + this.props.onChange(value); } }; - _this.handleChange = function (ev) { - _this.setState({ text: ev.target.value }); + this.handleChange = (ev) => { + this.setState({ text: ev.target.value }); }; - _this.state = { text: null, focused: false }; - return _this; + this.state = { text: null, focused: false }; } - Textbox.prototype.componentDidUpdate = function (prevProps) { + componentDidUpdate(prevProps) { // If different, override text if (prevProps.value !== this.props.value && this.state.text != null) { this.setState({ text: this.props.value }); } - }; - Textbox.prototype.render = function () { + } + render() { if (this.props.numLines && this.props.numLines > 1) { return (React.createElement("textarea", { className: this.props.editOnFocus ? "form-control edit-on-focus" : "form-control", placeholder: this.props.placeholder, disabled: this.props.disabled, value: this.state.text != null ? this.state.text : this.props.value || "", onFocus: this.handleFocus, onBlur: this.handleBlur, onChange: this.handleChange, rows: this.props.numLines })); } return (React.createElement("input", { className: this.props.editOnFocus ? "form-control edit-on-focus" : "form-control", type: "text", placeholder: this.props.placeholder, disabled: this.props.disabled, value: this.state.text != null ? this.state.text : this.props.value || "", onFocus: this.handleFocus, onBlur: this.handleBlur, onChange: this.handleChange })); - }; - return Textbox; -}(React.Component)); + } +} diff --git a/lib/widgets/blocks/controls/toggle.js b/lib/widgets/blocks/controls/toggle.js index 96a9c0b2..bace11f0 100644 --- a/lib/widgets/blocks/controls/toggle.js +++ b/lib/widgets/blocks/controls/toggle.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,20 +23,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ToggleBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var React = __importStar(require("react")); -var ControlBlock_1 = require("./ControlBlock"); -var localization_1 = require("../../localization"); -var propertyEditors_1 = require("../../propertyEditors"); +const lodash_1 = __importDefault(require("lodash")); +const React = __importStar(require("react")); +const ControlBlock_1 = require("./ControlBlock"); +const localization_1 = require("../../localization"); +const propertyEditors_1 = require("../../propertyEditors"); /** Block which shows a toggle to control an enum or boolean or enumset */ -var ToggleBlock = /** @class */ (function (_super) { - __extends(ToggleBlock, _super); - function ToggleBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ToggleBlock.prototype.renderControl = function (props) { +class ToggleBlock extends ControlBlock_1.ControlBlock { + renderControl(props) { // If can't be displayed properly - var defaultControl = React.createElement("div", { className: "btn-group" }, + const defaultControl = React.createElement("div", { className: "btn-group" }, React.createElement("button", { key: "1", type: "button", className: "btn btn-primary active" }, "Option 1"), React.createElement("button", { key: "2", type: "button", className: "btn btn-default" }, "Option 2")); // If can't be rendered due to missing context variable, just show error @@ -57,7 +40,7 @@ var ToggleBlock = /** @class */ (function (_super) { return defaultControl; } // Get column - var column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); + const column = props.schema.getColumn(props.rowContextVar.table, this.blockDef.column); if (!column) { return defaultControl; } @@ -71,85 +54,81 @@ var ToggleBlock = /** @class */ (function (_super) { return this.renderBoolean(props, column); } throw new Error("Unsupported type"); - }; - ToggleBlock.prototype.renderEnum = function (props, column) { - var _this = this; + } + renderEnum(props, column) { var enumValues = column.enumValues; // Handle include/exclude if (this.blockDef.includeValues && this.blockDef.includeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return _this.blockDef.includeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => this.blockDef.includeValues.includes(ev.id)); } if (this.blockDef.excludeValues && this.blockDef.excludeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return !_this.blockDef.excludeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => !this.blockDef.excludeValues.includes(ev.id)); } - return React.createElement("div", { className: "btn-group" }, enumValues.map(function (option) { - return React.createElement("button", { key: option.id, type: "button", disabled: props.disabled || !props.onChange, className: props.value == option.id ? "btn btn-primary active" : "btn btn-default", onClick: props.onChange != null ? function () { return props.onChange(option.id == props.value ? null : option.id); } : undefined }, localization_1.localize(option.name, props.locale)); + return React.createElement("div", { className: "btn-group" }, enumValues.map(option => { + return React.createElement("button", { key: option.id, type: "button", disabled: props.disabled || !props.onChange, className: props.value == option.id ? "btn btn-primary active" : "btn btn-default", onClick: props.onChange != null ? () => props.onChange(option.id == props.value ? null : option.id) : undefined }, localization_1.localize(option.name, props.locale)); })); - }; - ToggleBlock.prototype.renderEnumset = function (props, column) { - var _this = this; + } + renderEnumset(props, column) { var enumValues = column.enumValues; // Handle include/exclude if (this.blockDef.includeValues && this.blockDef.includeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return _this.blockDef.includeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => this.blockDef.includeValues.includes(ev.id)); } if (this.blockDef.excludeValues && this.blockDef.excludeValues.length > 0) { - enumValues = enumValues.filter(function (ev) { return !_this.blockDef.excludeValues.includes(ev.id); }); + enumValues = enumValues.filter(ev => !this.blockDef.excludeValues.includes(ev.id)); } - var handleToggle = function (id) { + const handleToggle = (id) => { if ((props.value || []).includes(id)) { - var newValue = lodash_1.default.difference(props.value || [], [id]); + const newValue = lodash_1.default.difference(props.value || [], [id]); props.onChange(newValue.length > 0 ? newValue : null); } else { - var newValue = lodash_1.default.union(props.value || [], [id]); + const newValue = lodash_1.default.union(props.value || [], [id]); props.onChange(newValue); } }; - return React.createElement("div", { className: "btn-group" }, enumValues.map(function (option) { + return React.createElement("div", { className: "btn-group" }, enumValues.map(option => { return React.createElement("button", { key: option.id, type: "button", disabled: props.disabled || !props.onChange, className: (props.value || []).includes(option.id) ? "btn btn-primary active" : "btn btn-default", onClick: handleToggle.bind(null, option.id) }, localization_1.localize(option.name, props.locale)); })); - }; - ToggleBlock.prototype.renderBoolean = function (props, column) { + } + renderBoolean(props, column) { return React.createElement("div", { className: "btn-group" }, - React.createElement("button", { key: "true", type: "button", disabled: props.disabled || !props.onChange, className: props.value == true ? "btn btn-primary active" : "btn btn-default", onClick: props.onChange ? function () { return props.onChange(props.value === true ? null : true); } : undefined }, localization_1.localize(this.blockDef.trueLabel, props.locale) || "Yes"), - React.createElement("button", { key: "false", type: "button", disabled: props.disabled || !props.onChange, className: props.value == false ? "btn btn-primary active" : "btn btn-default", onClick: props.onChange ? function () { return props.onChange(props.value === false ? null : false); } : undefined }, localization_1.localize(this.blockDef.falseLabel, props.locale) || "No")); - }; + React.createElement("button", { key: "true", type: "button", disabled: props.disabled || !props.onChange, className: props.value == true ? "btn btn-primary active" : "btn btn-default", onClick: props.onChange ? () => props.onChange(props.value === true ? null : true) : undefined }, localization_1.localize(this.blockDef.trueLabel, props.locale) || "Yes"), + React.createElement("button", { key: "false", type: "button", disabled: props.disabled || !props.onChange, className: props.value == false ? "btn btn-primary active" : "btn btn-default", onClick: props.onChange ? () => props.onChange(props.value === false ? null : false) : undefined }, localization_1.localize(this.blockDef.falseLabel, props.locale) || "No")); + } /** Implement this to render any editor parts that are not selecting the basic row cv and column */ - ToggleBlock.prototype.renderControlEditor = function (props) { - var _this = this; - var contextVar = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowContextVarId; }); - var column = null; + renderControlEditor(props) { + const contextVar = props.contextVars.find(cv => cv.id === this.blockDef.rowContextVarId); + let column = null; if (contextVar && contextVar.table && this.blockDef.column) { column = props.schema.getColumn(contextVar.table, this.blockDef.column); } return (React.createElement("div", null, column && (column.type === "enum" || column.type === "enumset") ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Include Values", key: "includeValues" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "includeValues" }, function (value, onChange) { return React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "includeValues" }, (value, onChange) => React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }))) : null, column && (column.type === "enum" || column.type === "enumset") ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Exclude Values", key: "excludeValues" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "excludeValues" }, function (value, onChange) { return React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "excludeValues" }, (value, onChange) => React.createElement(propertyEditors_1.EnumArrayEditor, { value: value, onChange: onChange, enumValues: column.enumValues }))) : null, column && column.type === "boolean" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label for true", key: "trueLabel", hint: "Must be set to allow localization" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "trueLabel" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "Yes" }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "trueLabel" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "Yes" }))) : null, column && column.type === "boolean" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label for false", key: "falseLabel", hint: "Must be set to allow localization" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "falseLabel" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "No" }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "falseLabel" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "No" }))) : null)); - }; + } /** Filter the columns that this control is for. Can't be expression */ - ToggleBlock.prototype.filterColumn = function (column) { + filterColumn(column) { if (column.expr) { return false; } return column.type === "enum" || column.type === "enumset" || column.type === "boolean"; - }; - return ToggleBlock; -}(ControlBlock_1.ControlBlock)); + } +} exports.ToggleBlock = ToggleBlock; diff --git a/lib/widgets/blocks/dateInject.js b/lib/widgets/blocks/dateInject.js index 88bf604e..c9face6c 100644 --- a/lib/widgets/blocks/dateInject.js +++ b/lib/widgets/blocks/dateInject.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,75 +23,68 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DateInjectBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var react_datepicker_1 = __importDefault(require("react-datepicker")); -var moment_1 = __importDefault(require("moment")); -var ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); -var react_1 = require("react"); -var DateInjectBlock = /** @class */ (function (_super) { - __extends(DateInjectBlock, _super); - function DateInjectBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - DateInjectBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const react_datepicker_1 = __importDefault(require("react-datepicker")); +const moment_1 = __importDefault(require("moment")); +const ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); +const react_1 = require("react"); +class DateInjectBlock extends blocks_1.Block { + getChildren(contextVars) { if (this.blockDef.content) { return [{ blockDef: this.blockDef.content, contextVars: contextVars.concat([this.createContextVar()]) }]; } return []; - }; - DateInjectBlock.prototype.createContextVar = function () { + } + createContextVar() { return { type: "date", id: this.blockDef.id, name: "Date" }; - }; - DateInjectBlock.prototype.validate = function (options) { + } + validate(options) { return null; - }; - DateInjectBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; - DateInjectBlock.prototype.renderDesign = function (designCtx) { - var _this = this; - var handleSetContent = function (blockDef) { - designCtx.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(designCtx) { + const handleSetContent = (blockDef) => { + designCtx.store.alterBlock(this.id, immer_1.default((b) => { b.content = blockDef; return b; }), blockDef.id); }; // Create ctx for child - var contextVar = this.createContextVar(); - var contentDesignCtx = designCtx; + const contextVar = this.createContextVar(); + let contentDesignCtx = designCtx; // Add context variable if knowable if (contextVar) { - contentDesignCtx = __assign(__assign({}, contentDesignCtx), { contextVars: designCtx.contextVars.concat([contextVar]) }); + contentDesignCtx = Object.assign(Object.assign({}, contentDesignCtx), { contextVars: designCtx.contextVars.concat([contextVar]) }); } - var contentNode = designCtx.renderChildBlock(contentDesignCtx, this.blockDef.content, handleSetContent); + const contentNode = designCtx.renderChildBlock(contentDesignCtx, this.blockDef.content, handleSetContent); return (React.createElement("div", null, React.createElement("div", null, - React.createElement(react_datepicker_1.default, { selected: moment_1.default(), onChange: function () { }, dateFormat: "ll", className: "form-control" })), + React.createElement(react_datepicker_1.default, { selected: moment_1.default(), onChange: () => { }, dateFormat: "ll", className: "form-control" })), contentNode)); - }; - DateInjectBlock.prototype.renderInstance = function (instanceCtx) { + } + renderInstance(instanceCtx) { return React.createElement(DateInjectInstance, { instanceCtx: instanceCtx, block: this }); - }; - DateInjectBlock.prototype.renderEditor = function (designCtx) { + } + renderEditor(designCtx) { return (React.createElement("div", null)); - }; - return DateInjectBlock; -}(blocks_1.Block)); + } +} exports.DateInjectBlock = DateInjectBlock; -var DateInjectInstance = function (props) { - var _a; - var _b = react_1.useState(moment_1.default().format("YYYY-MM-DD")), date = _b[0], setDate = _b[1]; - var instanceCtx = props.instanceCtx, block = props.block; - var dateContextVar = block.createContextVar(); +const DateInjectInstance = (props) => { + const [date, setDate] = react_1.useState(moment_1.default().format("YYYY-MM-DD")); + const { instanceCtx, block } = props; + const dateContextVar = block.createContextVar(); return (React.createElement("div", null, React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, - React.createElement(react_datepicker_1.default, { selected: moment_1.default(date, "YYYY-MM-DD"), onChange: function (momentDate) { setDate(momentDate.format("YYYY-MM-DD")); }, dateFormat: "ll", isClearable: false, className: "form-control" })), - React.createElement(ContextVarsInjector_1.default, { injectedContextVars: [dateContextVar], injectedContextVarValues: (_a = {}, _a[dateContextVar.id] = { type: "literal", valueType: "date", value: date }, _a), innerBlock: block.blockDef.content, instanceCtx: instanceCtx }, function (innerInstanceCtx, loading, refreshing) { + React.createElement(react_datepicker_1.default, { selected: moment_1.default(date, "YYYY-MM-DD"), onChange: (momentDate) => { setDate(momentDate.format("YYYY-MM-DD")); }, dateFormat: "ll", isClearable: false, className: "form-control" })), + React.createElement(ContextVarsInjector_1.default, { injectedContextVars: [dateContextVar], injectedContextVarValues: { [dateContextVar.id]: { type: "literal", valueType: "date", value: date } }, innerBlock: block.blockDef.content, instanceCtx: instanceCtx }, (innerInstanceCtx, loading, refreshing) => { if (loading) { return React.createElement("div", { style: { color: "#AAA", textAlign: "center" } }, React.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); diff --git a/lib/widgets/blocks/dropdownFilter/DateExprComponent.js b/lib/widgets/blocks/dropdownFilter/DateExprComponent.js index 7de6fa46..9b817e77 100644 --- a/lib/widgets/blocks/dropdownFilter/DateExprComponent.js +++ b/lib/widgets/blocks/dropdownFilter/DateExprComponent.js @@ -1,31 +1,18 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createDateFilterExpr = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_onclickout_1 = __importDefault(require("react-onclickout")); -var react_datepicker_1 = __importDefault(require("react-datepicker")); -var moment_1 = __importDefault(require("moment")); -var react_1 = __importDefault(require("react")); +const lodash_1 = __importDefault(require("lodash")); +const react_onclickout_1 = __importDefault(require("react-onclickout")); +const react_datepicker_1 = __importDefault(require("react-datepicker")); +const moment_1 = __importDefault(require("moment")); +const react_1 = __importDefault(require("react")); require("react-datepicker/dist/react-datepicker.css"); require("./datepicker-tweaks.css"); -var localization_1 = require("../../localization"); -var presets = [ +const localization_1 = require("../../localization"); +const presets = [ { id: "thisyear", name: { @@ -107,7 +94,7 @@ var presets = [ } } ]; -var toLiteral = function (datetime, value) { +const toLiteral = (datetime, value) => { if (!value) { return null; } @@ -119,7 +106,7 @@ var toLiteral = function (datetime, value) { } }; /** Convert a filter value to an expression */ -exports.createDateFilterExpr = function (table, expr, datetime, value) { +exports.createDateFilterExpr = (table, expr, datetime, value) => { if (!value) { return null; } @@ -140,54 +127,52 @@ exports.createDateFilterExpr = function (table, expr, datetime, value) { }; }; /** Allows selection of a date range including presets */ -var DateExprComponent = /** @class */ (function (_super) { - __extends(DateExprComponent, _super); - function DateExprComponent(props) { - var _this = _super.call(this, props) || this; - _this.handleClickOut = function () { - _this.setState({ dropdownOpen: false }); +class DateExprComponent extends react_1.default.Component { + constructor(props) { + super(props); + this.handleClickOut = () => { + this.setState({ dropdownOpen: false }); }; - _this.handleCustom = function () { - _this.setState({ custom: true }); + this.handleCustom = () => { + this.setState({ custom: true }); }; - _this.handleStartChange = function (value) { + this.handleStartChange = (value) => { // Clear end if after - if (lodash_1.default.isArray(_this.props.value) && _this.props.value[1] && _this.fromMoment(value) > _this.props.value[1]) { - _this.props.onChange([_this.fromMoment(value), null]); + if (lodash_1.default.isArray(this.props.value) && this.props.value[1] && this.fromMoment(value) > this.props.value[1]) { + this.props.onChange([this.fromMoment(value), null]); } else { - _this.props.onChange([_this.fromMoment(value), lodash_1.default.isArray(_this.props.value) ? _this.props.value[1] : null]); + this.props.onChange([this.fromMoment(value), lodash_1.default.isArray(this.props.value) ? this.props.value[1] : null]); } }; - _this.handleEndChange = function (value) { + this.handleEndChange = (value) => { // Go to end of day if datetime - if (_this.props.datetime) { + if (this.props.datetime) { value = moment_1.default(value); value.endOf("day"); } // Clear start if before - if (lodash_1.default.isArray(_this.props.value) && _this.props.value[0] && _this.fromMoment(value) < _this.props.value[0]) { - _this.props.onChange([null, _this.fromMoment(value)]); + if (lodash_1.default.isArray(this.props.value) && this.props.value[0] && this.fromMoment(value) < this.props.value[0]) { + this.props.onChange([null, this.fromMoment(value)]); } else { - _this.props.onChange([lodash_1.default.isArray(_this.props.value) ? _this.props.value[0] : null, _this.fromMoment(value)]); + this.props.onChange([lodash_1.default.isArray(this.props.value) ? this.props.value[0] : null, this.fromMoment(value)]); } - _this.setState({ dropdownOpen: false }); + this.setState({ dropdownOpen: false }); }; - _this.handlePreset = function (preset) { - _this.props.onChange(preset.id); - _this.setState({ dropdownOpen: false }); + this.handlePreset = (preset) => { + this.props.onChange(preset.id); + this.setState({ dropdownOpen: false }); }; - _this.handleOpen = function () { - _this.setState({ dropdownOpen: true, custom: false }); + this.handleOpen = () => { + this.setState({ dropdownOpen: true, custom: false }); }; - _this.state = { + this.state = { dropdownOpen: false, custom: false }; - return _this; } - DateExprComponent.prototype.toMoment = function (value) { + toMoment(value) { if (!value) { return null; } @@ -197,8 +182,8 @@ var DateExprComponent = /** @class */ (function (_super) { else { return moment_1.default(value, "YYYY-MM-DD"); } - }; - DateExprComponent.prototype.fromMoment = function (value) { + } + fromMoment(value) { if (!value) { return null; } @@ -208,23 +193,22 @@ var DateExprComponent = /** @class */ (function (_super) { else { return value.format("YYYY-MM-DD"); } - }; - DateExprComponent.prototype.renderClear = function () { + } + renderClear() { return (react_1.default.createElement("div", { style: { position: "absolute", right: 10, top: 7, color: "#AAA" }, onClick: this.props.onChange.bind(null, null) }, react_1.default.createElement("i", { className: "fa fa-remove" }))); - }; - DateExprComponent.prototype.renderSummary = function () { - var _this = this; + } + renderSummary() { if (!this.props.value) { return react_1.default.createElement("span", { className: "text-muted" }, this.props.placeholder || ""); } - var preset = presets.find(function (p) { return p.id === _this.props.value; }); + const preset = presets.find(p => p.id === this.props.value); if (preset) { return localization_1.localize(preset.name, this.props.locale); } if (Array.isArray(this.props.value)) { - var startDate = this.toMoment(this.props.value[0]); - var endDate = this.toMoment(this.props.value[1]); + const startDate = this.toMoment(this.props.value[0]); + const endDate = this.toMoment(this.props.value[1]); // Add/subtract hours to work around https://github.com/moment/moment/issues/2749 if (this.props.datetime) { return (startDate ? startDate.add("hours", 3).format("ll") : "") + " - " + (endDate ? endDate.subtract("hours", 3).format("ll") : ""); @@ -234,14 +218,13 @@ var DateExprComponent = /** @class */ (function (_super) { } } return "???"; - }; - DateExprComponent.prototype.renderPresets = function () { - var _this = this; + } + renderPresets() { return (react_1.default.createElement("div", { style: { position: "absolute", top: "100%", left: 0, zIndex: 4000, padding: 5, border: "solid 1px #AAA", backgroundColor: "white", borderRadius: 4 } }, react_1.default.createElement("ul", { className: "nav nav-pills nav-stacked" }, - presets.map(function (preset) { + presets.map(preset => { return (react_1.default.createElement("li", { key: preset.id }, - react_1.default.createElement("a", { style: { padding: 5 }, onClick: _this.handlePreset.bind(null, preset) }, localization_1.localize(preset.name, _this.props.locale)))); + react_1.default.createElement("a", { style: { padding: 5 }, onClick: this.handlePreset.bind(null, preset) }, localization_1.localize(preset.name, this.props.locale)))); }), react_1.default.createElement("li", null, react_1.default.createElement("a", { style: { padding: 5 }, onClick: this.handleCustom }, localization_1.localize({ @@ -249,26 +232,26 @@ var DateExprComponent = /** @class */ (function (_super) { en: "Custom Date Range...", es: "Rango de fechas personalizado...." }, this.props.locale)))))); - }; - DateExprComponent.prototype.renderDropdown = function () { + } + renderDropdown() { if (this.state.custom) { return this.renderCustomDropdown(); } else { return this.renderPresets(); } - }; - DateExprComponent.prototype.renderCustomDropdown = function () { - var startDate = this.toMoment(lodash_1.default.isArray(this.props.value) ? this.props.value[0] : null) || undefined; - var endDate = this.toMoment(lodash_1.default.isArray(this.props.value) ? this.props.value[1] : null) || undefined; + } + renderCustomDropdown() { + const startDate = this.toMoment(lodash_1.default.isArray(this.props.value) ? this.props.value[0] : null) || undefined; + const endDate = this.toMoment(lodash_1.default.isArray(this.props.value) ? this.props.value[1] : null) || undefined; return (react_1.default.createElement("div", { style: { position: "absolute", top: "100%", left: 0, zIndex: 4000, padding: 5, border: "solid 1px #AAA", backgroundColor: "white", borderRadius: 4 } }, react_1.default.createElement("div", { style: { whiteSpace: "nowrap" } }, react_1.default.createElement("div", { style: { display: "inline-block", verticalAlign: "top" } }, react_1.default.createElement(react_datepicker_1.default, { inline: true, selectsStart: true, selected: startDate, startDate: startDate, endDate: endDate, showYearDropdown: true, onChange: this.handleStartChange })), react_1.default.createElement("div", { style: { display: "inline-block", verticalAlign: "top" } }, react_1.default.createElement(react_datepicker_1.default, { inline: true, selectsEnd: true, selected: endDate, startDate: startDate, endDate: endDate, showYearDropdown: true, onChange: this.handleEndChange }))))); - }; - DateExprComponent.prototype.render = function () { + } + render() { return (react_1.default.createElement(react_onclickout_1.default, { onClickOut: this.handleClickOut }, react_1.default.createElement("div", { style: { display: "inline-block", position: "relative" } }, react_1.default.createElement("div", { className: "form-control", style: { width: 220, height: 34 }, onClick: this.handleOpen }, this.renderSummary()), @@ -278,7 +261,6 @@ var DateExprComponent = /** @class */ (function (_super) { this.state.dropdownOpen ? this.renderDropdown() : null))); - }; - return DateExprComponent; -}(react_1.default.Component)); + } +} exports.default = DateExprComponent; diff --git a/lib/widgets/blocks/dropdownFilter/DateFilterInstance.js b/lib/widgets/blocks/dropdownFilter/DateFilterInstance.js index 407e1b65..3e7dc5f8 100644 --- a/lib/widgets/blocks/dropdownFilter/DateFilterInstance.js +++ b/lib/widgets/blocks/dropdownFilter/DateFilterInstance.js @@ -1,26 +1,15 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DateFilterInstance = void 0; -var react_1 = __importDefault(require("react")); -var react_select_1 = __importDefault(require("react-select")); +const react_1 = __importDefault(require("react")); +const react_select_1 = __importDefault(require("react-select")); /** Simple date filter that is year, month or year-month */ -exports.DateFilterInstance = function (props) { - var options = []; - var months = [ +exports.DateFilterInstance = (props) => { + let options = []; + const months = [ { value: "01", label: "January" }, { value: "02", label: "February" }, { value: "03", label: "March" }, @@ -38,25 +27,25 @@ exports.DateFilterInstance = function (props) { options = months; } else if (props.mode == "year") { - var year = new Date().getFullYear(); - for (var y = year; y >= year - 10; y--) { - options.push({ value: y + "-01-01", label: "" + y }); + const year = new Date().getFullYear(); + for (let y = year; y >= year - 10; y--) { + options.push({ value: `${y}-01-01`, label: `${y}` }); } } else if (props.mode == "yearmonth") { - var year = new Date().getFullYear(); - for (var y = year; y >= year - 10; y--) { - for (var m = (y == year) ? new Date().getMonth() : 11; m >= 0; m--) { - options.push({ value: y + "-" + months[m].value + "-01", label: months[m].label + " " + y }); + const year = new Date().getFullYear(); + for (let y = year; y >= year - 10; y--) { + for (let m = (y == year) ? new Date().getMonth() : 11; m >= 0; m--) { + options.push({ value: `${y}-${months[m].value}-01`, label: `${months[m].label} ${y}` }); } } } - var styles = { + const styles = { // control: (style: CSSProperties) => ({ ...style, minWidth: minWidth }), - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; - var handleChange = function (ev) { return props.onChange(ev ? ev.value : null); }; + const handleChange = (ev) => props.onChange(ev ? ev.value : null); // Find option - var option = options.find(function (opt) { return opt.value == props.value; }); + const option = options.find(opt => opt.value == props.value); return react_1.default.createElement(react_select_1.default, { value: option, onChange: handleChange, options: options, placeholder: props.placeholder, isClearable: true, styles: styles, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short" }); }; diff --git a/lib/widgets/blocks/dropdownFilter/EnumInstance.js b/lib/widgets/blocks/dropdownFilter/EnumInstance.js index a0c2cdd2..7e9cf392 100644 --- a/lib/widgets/blocks/dropdownFilter/EnumInstance.js +++ b/lib/widgets/blocks/dropdownFilter/EnumInstance.js @@ -1,57 +1,27 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var mwater_expressions_1 = require("mwater-expressions"); -var blocks_1 = require("../../blocks"); -var localization_1 = require("../../localization"); -var react_select_1 = __importDefault(require("react-select")); -var EnumInstance = /** @class */ (function (_super) { - __extends(EnumInstance, _super); - function EnumInstance() { - return _super !== null && _super.apply(this, arguments) || this; - } - EnumInstance.prototype.render = function () { - var _this = this; - var enumValues = this.props.blockDef.filterExpr ? new mwater_expressions_1.ExprUtils(this.props.schema, blocks_1.createExprVariables(this.props.contextVars)).getExprEnumValues(this.props.blockDef.filterExpr) : null; - var enumValue = enumValues ? enumValues.find(function (ev) { return ev.id === _this.props.value; }) : null; - var getOptionLabel = function (ev) { return localization_1.localize(ev.name, _this.props.locale); }; - var getOptionValue = function (ev) { return ev.id; }; - var handleChange = function (ev) { return _this.props.onChange(ev ? ev.id : null); }; +const react_1 = __importDefault(require("react")); +const mwater_expressions_1 = require("mwater-expressions"); +const blocks_1 = require("../../blocks"); +const localization_1 = require("../../localization"); +const react_select_1 = __importDefault(require("react-select")); +class EnumInstance extends react_1.default.Component { + render() { + const enumValues = this.props.blockDef.filterExpr ? new mwater_expressions_1.ExprUtils(this.props.schema, blocks_1.createExprVariables(this.props.contextVars)).getExprEnumValues(this.props.blockDef.filterExpr) : null; + const enumValue = enumValues ? enumValues.find(ev => ev.id === this.props.value) : null; + const getOptionLabel = (ev) => localization_1.localize(ev.name, this.props.locale); + const getOptionValue = (ev) => ev.id; + const handleChange = (ev) => this.props.onChange(ev ? ev.id : null); // Make minimum size to fit text - var minWidth = Math.min(300, Math.max(enumValue ? getOptionLabel(enumValue).length * 8 + 90 : 0, 150)); - var styles = { - control: function (style) { return (__assign(__assign({}, style), { minWidth: minWidth })); }, - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + const minWidth = Math.min(300, Math.max(enumValue ? getOptionLabel(enumValue).length * 8 + 90 : 0, 150)); + const styles = { + control: (style) => (Object.assign(Object.assign({}, style), { minWidth: minWidth })), + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; return react_1.default.createElement(react_select_1.default, { value: enumValue, onChange: handleChange, options: enumValues || undefined, placeholder: localization_1.localize(this.props.blockDef.placeholder, this.props.locale), getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isClearable: true, styles: styles, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short" }); - }; - return EnumInstance; -}(react_1.default.Component)); + } +} exports.default = EnumInstance; diff --git a/lib/widgets/blocks/dropdownFilter/EnumsetInstance.js b/lib/widgets/blocks/dropdownFilter/EnumsetInstance.js index 24cc507a..9f9b2ddf 100644 --- a/lib/widgets/blocks/dropdownFilter/EnumsetInstance.js +++ b/lib/widgets/blocks/dropdownFilter/EnumsetInstance.js @@ -1,58 +1,28 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var mwater_expressions_1 = require("mwater-expressions"); -var blocks_1 = require("../../blocks"); -var localization_1 = require("../../localization"); -var react_select_1 = __importDefault(require("react-select")); -var EnumsetInstance = /** @class */ (function (_super) { - __extends(EnumsetInstance, _super); - function EnumsetInstance() { - return _super !== null && _super.apply(this, arguments) || this; - } - EnumsetInstance.prototype.render = function () { - var _this = this; - var enumValues = this.props.blockDef.filterExpr ? new mwater_expressions_1.ExprUtils(this.props.schema, blocks_1.createExprVariables(this.props.contextVars)).getExprEnumValues(this.props.blockDef.filterExpr) : null; +const react_1 = __importDefault(require("react")); +const mwater_expressions_1 = require("mwater-expressions"); +const blocks_1 = require("../../blocks"); +const localization_1 = require("../../localization"); +const react_select_1 = __importDefault(require("react-select")); +class EnumsetInstance extends react_1.default.Component { + render() { + const enumValues = this.props.blockDef.filterExpr ? new mwater_expressions_1.ExprUtils(this.props.schema, blocks_1.createExprVariables(this.props.contextVars)).getExprEnumValues(this.props.blockDef.filterExpr) : null; // Get selected values as enum values - var selectedValues = enumValues && this.props.value ? this.props.value.map(function (v) { return enumValues.find(function (ev) { return ev.id == v; }); }) : null; - var getOptionLabel = function (ev) { return localization_1.localize(ev.name, _this.props.locale); }; - var getOptionValue = function (ev) { return ev.id; }; - var handleChange = function (evs) { return _this.props.onChange(evs && evs.length > 0 ? evs.map(function (ev) { return ev.id; }) : null); }; + const selectedValues = enumValues && this.props.value ? this.props.value.map((v) => enumValues.find(ev => ev.id == v)) : null; + const getOptionLabel = (ev) => localization_1.localize(ev.name, this.props.locale); + const getOptionValue = (ev) => ev.id; + const handleChange = (evs) => this.props.onChange(evs && evs.length > 0 ? evs.map(ev => ev.id) : null); // Make minimum size to fit text TODO just max for now - var minWidth = 400; //Math.min(300, Math.max(selectedValue ? getOptionLabel(selectedValue).length * 8 + 90 : 0, 150)) - var styles = { - control: function (style) { return (__assign(__assign({}, style), { minWidth: minWidth })); }, - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + const minWidth = 400; //Math.min(300, Math.max(selectedValue ? getOptionLabel(selectedValue).length * 8 + 90 : 0, 150)) + const styles = { + control: (style) => (Object.assign(Object.assign({}, style), { minWidth: minWidth })), + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; return react_1.default.createElement(react_select_1.default, { value: selectedValues, isMulti: true, onChange: handleChange, options: enumValues || undefined, placeholder: localization_1.localize(this.props.blockDef.placeholder, this.props.locale), getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isClearable: true, styles: styles, closeMenuOnScroll: true, menuPortalTarget: document.body, classNamePrefix: "react-select-short" }); - }; - return EnumsetInstance; -}(react_1.default.Component)); + } +} exports.default = EnumsetInstance; diff --git a/lib/widgets/blocks/dropdownFilter/IdInstance.js b/lib/widgets/blocks/dropdownFilter/IdInstance.js index 6213ed7b..7baf75a2 100644 --- a/lib/widgets/blocks/dropdownFilter/IdInstance.js +++ b/lib/widgets/blocks/dropdownFilter/IdInstance.js @@ -1,31 +1,20 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.IdInstance = void 0; -var react_1 = __importDefault(require("react")); -var mwater_expressions_1 = require("mwater-expressions"); -var blocks_1 = require("../../blocks"); -var IdDropdownComponent_1 = require("../controls/IdDropdownComponent"); -var embeddedExprs_1 = require("../../../embeddedExprs"); -var localization_1 = require("../../localization"); +const react_1 = __importDefault(require("react")); +const mwater_expressions_1 = require("mwater-expressions"); +const blocks_1 = require("../../blocks"); +const IdDropdownComponent_1 = require("../controls/IdDropdownComponent"); +const embeddedExprs_1 = require("../../../embeddedExprs"); +const localization_1 = require("../../localization"); /** Dropdown filter that is an id */ -exports.IdInstance = function (props) { - var exprUtils = new mwater_expressions_1.ExprUtils(props.ctx.schema, blocks_1.createExprVariables(props.ctx.contextVars)); - var idTable = exprUtils.getExprIdTable(props.blockDef.filterExpr); - var formatIdLabel = function (labelValues) { +exports.IdInstance = (props) => { + const exprUtils = new mwater_expressions_1.ExprUtils(props.ctx.schema, blocks_1.createExprVariables(props.ctx.contextVars)); + const idTable = exprUtils.getExprIdTable(props.blockDef.filterExpr); + const formatIdLabel = (labelValues) => { if (props.blockDef.idMode == "advanced") { return embeddedExprs_1.formatEmbeddedExprString({ text: localization_1.localize(props.blockDef.idLabelText, props.ctx.locale), @@ -41,12 +30,12 @@ exports.IdInstance = function (props) { return labelValues[0]; } }; - var labelEmbeddedExprs; - var searchExprs; - var orderBy; + let labelEmbeddedExprs; + let searchExprs; + let orderBy; // Handle modes if (props.blockDef.idMode == "advanced") { - labelEmbeddedExprs = (props.blockDef.idLabelEmbeddedExprs || []).map(function (ee) { return ee.expr; }); + labelEmbeddedExprs = (props.blockDef.idLabelEmbeddedExprs || []).map(ee => ee.expr); searchExprs = props.blockDef.idSearchExprs || []; orderBy = props.blockDef.idOrderBy || []; } @@ -55,5 +44,5 @@ exports.IdInstance = function (props) { searchExprs = [props.blockDef.idLabelExpr]; orderBy = [{ expr: props.blockDef.idLabelExpr, dir: "asc" }]; } - return react_1.default.createElement(IdDropdownComponent_1.IdDropdownComponent, { database: props.ctx.database, table: idTable, value: props.value, onChange: props.onChange, multi: false, labelEmbeddedExprs: labelEmbeddedExprs, searchExprs: searchExprs, orderBy: orderBy, filterExpr: props.blockDef.idFilterExpr || null, formatLabel: formatIdLabel, placeholder: localization_1.localize(props.blockDef.placeholder, props.locale), contextVars: props.ctx.contextVars, contextVarValues: props.ctx.contextVarValues, styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); + return react_1.default.createElement(IdDropdownComponent_1.IdDropdownComponent, { database: props.ctx.database, table: idTable, value: props.value, onChange: props.onChange, multi: false, labelEmbeddedExprs: labelEmbeddedExprs, searchExprs: searchExprs, orderBy: orderBy, filterExpr: props.blockDef.idFilterExpr || null, formatLabel: formatIdLabel, placeholder: localization_1.localize(props.blockDef.placeholder, props.locale), contextVars: props.ctx.contextVars, contextVarValues: props.ctx.contextVarValues, styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); }; diff --git a/lib/widgets/blocks/dropdownFilter/TextArrInstance.js b/lib/widgets/blocks/dropdownFilter/TextArrInstance.js index fdce52cd..a215ac89 100644 --- a/lib/widgets/blocks/dropdownFilter/TextArrInstance.js +++ b/lib/widgets/blocks/dropdownFilter/TextArrInstance.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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) { @@ -32,139 +8,92 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importDefault(require("react")); -var localization_1 = require("../../localization"); -var async_1 = __importDefault(require("react-select/async")); +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importDefault(require("react")); +const localization_1 = require("../../localization"); +const async_1 = __importDefault(require("react-select/async")); /** Dropdown filter that is a text[]. Should search in database for matches, returning value to match */ -var TextArrInstance = /** @class */ (function (_super) { - __extends(TextArrInstance, _super); - function TextArrInstance() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.getOptions = function (input) { return __awaiter(_this, void 0, void 0, function () { - var _a; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - if (!!this.options) return [3 /*break*/, 2]; - _a = this; - return [4 /*yield*/, this.loadOptions()]; - case 1: - _a.options = _b.sent(); - _b.label = 2; - case 2: - // Filter by input string - if (input) { - return [2 /*return*/, this.options.filter(function (o) { return o.label.toLowerCase().startsWith(input.toLowerCase()); })]; - } - else { - return [2 /*return*/, this.options]; - } - return [2 /*return*/]; - } - }); - }); }; - _this.handleChange = function (option) { - var value = option ? (option.value || null) : null; // Blank is null - _this.props.onChange(value); +class TextArrInstance extends react_1.default.Component { + constructor() { + super(...arguments); + this.getOptions = (input) => __awaiter(this, void 0, void 0, function* () { + // Load options if not loaded + if (!this.options) { + this.options = yield this.loadOptions(); + } + // Filter by input string + if (input) { + return this.options.filter(o => o.label.toLowerCase().startsWith(input.toLowerCase())); + } + else { + return this.options; + } + }); + this.handleChange = (option) => { + const value = option ? (option.value || null) : null; // Blank is null + this.props.onChange(value); }; - return _this; } - TextArrInstance.prototype.loadOptions = function () { - return __awaiter(this, void 0, void 0, function () { - var contextVar, table, whereExprs, cvValue, queryOptions, rows, values, err_1; - var _this = this; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = this.props.contextVars.find(function (cv) { return cv.id === _this.props.blockDef.rowsetContextVarId; }); - table = contextVar.table; - whereExprs = []; - cvValue = this.props.instanceCtx.contextVarValues[contextVar.id]; - if (cvValue) { - whereExprs.push(cvValue); - } - // Filter out blanks - whereExprs.push({ - type: "op", - op: "is not null", - table: table, - exprs: [this.props.blockDef.filterExpr] - }); - queryOptions = { - select: { value: this.props.blockDef.filterExpr }, - distinct: true, - from: table, - where: { - type: "op", - op: "and", - table: table, - exprs: whereExprs - }, - limit: 250 - }; - _a.label = 1; - case 1: - _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, this.props.database.query(queryOptions, this.props.contextVars, {}) - // Flatten and keep distinct - ]; - case 2: - rows = _a.sent(); - values = lodash_1.default.uniq(lodash_1.default.flatten(rows.map(function (r) { return r.value; }))).sort(); - return [2 /*return*/, values.map(function (v) { return ({ value: v, label: v }); })]; - case 3: - err_1 = _a.sent(); - // TODO localize - alert("Unable to load options"); - return [2 /*return*/, []]; - case 4: return [2 /*return*/]; - } + loadOptions() { + return __awaiter(this, void 0, void 0, function* () { + const contextVar = this.props.contextVars.find(cv => cv.id === this.props.blockDef.rowsetContextVarId); + const table = contextVar.table; + const whereExprs = []; + // Add context var value to only show possible text values. Do not filter on other + // filters, as this causes problems due to https://github.com/JedWatson/react-select/issues/4012 + // as well as needing to exclude self-filters + const cvValue = this.props.instanceCtx.contextVarValues[contextVar.id]; + if (cvValue) { + whereExprs.push(cvValue); + } + // Filter out blanks + whereExprs.push({ + type: "op", + op: "is not null", + table: table, + exprs: [this.props.blockDef.filterExpr] }); + // Query all distinct values, which will include possibly more than one copy of each text string, as it + // can appear in different combinations + const queryOptions = { + select: { value: this.props.blockDef.filterExpr }, + distinct: true, + from: table, + where: { + type: "op", + op: "and", + table: table, + exprs: whereExprs + }, + limit: 250 + }; + try { + const rows = yield this.props.database.query(queryOptions, this.props.contextVars, {}); + // Flatten and keep distinct + const values = lodash_1.default.uniq(lodash_1.default.flatten(rows.map(r => r.value))).sort(); + return values.map(v => ({ value: v, label: v })); + } + catch (err) { + // TODO localize + alert("Unable to load options"); + return []; + } }); - }; - TextArrInstance.prototype.render = function () { - var currentValue = this.props.value ? { value: this.props.value, label: this.props.value } : null; + } + render() { + const currentValue = this.props.value ? { value: this.props.value, label: this.props.value } : null; // Make minimum size to fit text - var minWidth = Math.min(300, Math.max(this.props.value ? this.props.value.length * 8 + 90 : 0, 150)); - var noOptionsMessage = function () { return "Type to search"; }; - var styles = { - control: function (style) { return (__assign(__assign({}, style), { minWidth: minWidth })); }, - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + const minWidth = Math.min(300, Math.max(this.props.value ? this.props.value.length * 8 + 90 : 0, 150)); + const noOptionsMessage = () => "Type to search"; + const styles = { + control: (style) => (Object.assign(Object.assign({}, style), { minWidth: minWidth })), + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; return react_1.default.createElement(async_1.default, { placeholder: localization_1.localize(this.props.blockDef.placeholder, this.props.locale), value: currentValue, defaultOptions: true, loadOptions: this.getOptions, onChange: this.handleChange, isClearable: true, noOptionsMessage: noOptionsMessage, styles: styles, classNamePrefix: "react-select-short", menuPortalTarget: document.body }); - }; - return TextArrInstance; -}(react_1.default.Component)); + } +} exports.default = TextArrInstance; diff --git a/lib/widgets/blocks/dropdownFilter/TextInstance.js b/lib/widgets/blocks/dropdownFilter/TextInstance.js index ccc7ad47..5b91b2b8 100644 --- a/lib/widgets/blocks/dropdownFilter/TextInstance.js +++ b/lib/widgets/blocks/dropdownFilter/TextInstance.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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) { @@ -32,118 +8,79 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var localization_1 = require("../../localization"); -var async_1 = __importDefault(require("react-select/async")); +const react_1 = __importDefault(require("react")); +const localization_1 = require("../../localization"); +const async_1 = __importDefault(require("react-select/async")); /** Dropdown filter that is a text string. Should search in database for matches */ -var TextInstance = /** @class */ (function (_super) { - __extends(TextInstance, _super); - function TextInstance() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.getOptions = function (input) { return __awaiter(_this, void 0, void 0, function () { - var contextVar, table, escapeRegex, whereExprs, cvValue, queryOptions, rows, values, err_1; - var _this = this; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = this.props.contextVars.find(function (cv) { return cv.id === _this.props.blockDef.rowsetContextVarId; }); - table = contextVar.table; - escapeRegex = function (s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); }; - whereExprs = []; - cvValue = this.props.instanceCtx.contextVarValues[contextVar.id]; - if (cvValue) { - whereExprs.push(cvValue); - } - // Filter by input string - whereExprs.push({ - type: "op", - op: "~*", - table: table, - exprs: [ - this.props.blockDef.filterExpr, - { type: "literal", valueType: "text", value: "^" + escapeRegex(input) } - ] - }); - queryOptions = { - select: { value: this.props.blockDef.filterExpr }, - distinct: true, - from: table, - where: { - type: "op", - op: "and", - table: table, - exprs: whereExprs - }, - orderBy: [{ expr: this.props.blockDef.filterExpr, dir: "asc" }], - limit: 250 - }; - _a.label = 1; - case 1: - _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, this.props.database.query(queryOptions, this.props.contextVars, {}) - // Filter null and blank - ]; - case 2: - rows = _a.sent(); - values = rows.map(function (r) { return r.value; }).filter(function (v) { return v; }); - return [2 /*return*/, values.map(function (v) { return ({ value: v, label: v }); })]; - case 3: - err_1 = _a.sent(); - // TODO localize - alert("Unable to load options"); - return [2 /*return*/, []]; - case 4: return [2 /*return*/]; - } +class TextInstance extends react_1.default.Component { + constructor() { + super(...arguments); + this.getOptions = (input) => __awaiter(this, void 0, void 0, function* () { + const contextVar = this.props.contextVars.find(cv => cv.id === this.props.blockDef.rowsetContextVarId); + const table = contextVar.table; + const escapeRegex = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + const whereExprs = []; + // Add context var value to only show possible text values. Do not filter on other + // filters, as this causes problems due to https://github.com/JedWatson/react-select/issues/4012 + // as well as needing to exclude self-filters + const cvValue = this.props.instanceCtx.contextVarValues[contextVar.id]; + if (cvValue) { + whereExprs.push(cvValue); + } + // Filter by input string + whereExprs.push({ + type: "op", + op: "~*", + table: table, + exprs: [ + this.props.blockDef.filterExpr, + { type: "literal", valueType: "text", value: "^" + escapeRegex(input) } + ] }); - }); }; - _this.handleChange = function (option) { - var value = option ? (option.value || null) : null; // Blank is null - _this.props.onChange(value); + const queryOptions = { + select: { value: this.props.blockDef.filterExpr }, + distinct: true, + from: table, + where: { + type: "op", + op: "and", + table: table, + exprs: whereExprs + }, + orderBy: [{ expr: this.props.blockDef.filterExpr, dir: "asc" }], + limit: 250 + }; + try { + const rows = yield this.props.database.query(queryOptions, this.props.contextVars, {}); + // Filter null and blank + const values = rows.map(r => r.value).filter(v => v); + return values.map(v => ({ value: v, label: v })); + } + catch (err) { + // TODO localize + alert("Unable to load options"); + return []; + } + }); + this.handleChange = (option) => { + const value = option ? (option.value || null) : null; // Blank is null + this.props.onChange(value); }; - return _this; } - TextInstance.prototype.render = function () { - var currentValue = this.props.value ? { value: this.props.value, label: this.props.value } : null; + render() { + const currentValue = this.props.value ? { value: this.props.value, label: this.props.value } : null; // Make minimum size to fit text - var minWidth = Math.min(300, Math.max(this.props.value ? this.props.value.length * 8 + 90 : 0, 150)); - var noOptionsMessage = function () { return "Type to search"; }; - var styles = { - control: function (style) { return (__assign(__assign({}, style), { minWidth: minWidth })); }, - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + const minWidth = Math.min(300, Math.max(this.props.value ? this.props.value.length * 8 + 90 : 0, 150)); + const noOptionsMessage = () => "Type to search"; + const styles = { + control: (style) => (Object.assign(Object.assign({}, style), { minWidth: minWidth })), + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; return react_1.default.createElement(async_1.default, { placeholder: localization_1.localize(this.props.blockDef.placeholder, this.props.locale), value: currentValue, defaultOptions: true, loadOptions: this.getOptions, onChange: this.handleChange, isClearable: true, noOptionsMessage: noOptionsMessage, styles: styles, classNamePrefix: "react-select-short", menuPortalTarget: document.body }); - }; - return TextInstance; -}(react_1.default.Component)); + } +} exports.default = TextInstance; diff --git a/lib/widgets/blocks/dropdownFilter/dropdownFilter.js b/lib/widgets/blocks/dropdownFilter/dropdownFilter.js index 3fb5eb3f..7f4e35bf 100644 --- a/lib/widgets/blocks/dropdownFilter/dropdownFilter.js +++ b/lib/widgets/blocks/dropdownFilter/dropdownFilter.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,92 +23,81 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DropdownFilterBlock = void 0; -var React = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../../LeafBlock")); -var blocks_1 = require("../../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var propertyEditors_1 = require("../../propertyEditors"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var localization_1 = require("../../localization"); -var react_select_1 = __importDefault(require("react-select")); -var EnumInstance_1 = __importDefault(require("./EnumInstance")); -var TextInstance_1 = __importDefault(require("./TextInstance")); -var DateExprComponent_1 = __importStar(require("./DateExprComponent")); -var immer_1 = __importDefault(require("immer")); -var EnumsetInstance_1 = __importDefault(require("./EnumsetInstance")); -var embeddedExprs_1 = require("../../../embeddedExprs"); -var IdInstance_1 = require("./IdInstance"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var ListEditor_1 = __importDefault(require("../../ListEditor")); -var DateFilterInstance_1 = require("./DateFilterInstance"); -var TextArrInstance_1 = __importDefault(require("./TextArrInstance")); +const React = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../../LeafBlock")); +const blocks_1 = require("../../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const propertyEditors_1 = require("../../propertyEditors"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const localization_1 = require("../../localization"); +const react_select_1 = __importDefault(require("react-select")); +const EnumInstance_1 = __importDefault(require("./EnumInstance")); +const TextInstance_1 = __importDefault(require("./TextInstance")); +const DateExprComponent_1 = __importStar(require("./DateExprComponent")); +const immer_1 = __importDefault(require("immer")); +const EnumsetInstance_1 = __importDefault(require("./EnumsetInstance")); +const embeddedExprs_1 = require("../../../embeddedExprs"); +const IdInstance_1 = require("./IdInstance"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const ListEditor_1 = __importDefault(require("../../ListEditor")); +const DateFilterInstance_1 = require("./DateFilterInstance"); +const TextArrInstance_1 = __importDefault(require("./TextArrInstance")); /** Dropdown that filters one or more rowsets. The value of the filter is stored in the memo of the rowset filter * and depends on which type of filter it is. */ -var DropdownFilterBlock = /** @class */ (function (_super) { - __extends(DropdownFilterBlock, _super); - function DropdownFilterBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - DropdownFilterBlock.prototype.validate = function (options) { - var _this = this; +class DropdownFilterBlock extends LeafBlock_1.default { + validate(options) { // Validate rowset - var rowsetCV = options.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + const rowsetCV = options.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return "Rowset required"; } if (!this.blockDef.filterExpr) { return "Filter expression required"; } - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); // Validate expr - var error; + let error; error = exprValidator.validateExpr(this.blockDef.filterExpr, { table: rowsetCV.table, types: ["enum", "enumset", "text", "date", "datetime", "id", "text[]"] }); if (error) { return error; } - var exprUtils = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)); - var valueType = exprUtils.getExprType(this.blockDef.filterExpr); - var valueIdTableId = exprUtils.getExprIdTable(this.blockDef.filterExpr); + const exprUtils = new mwater_expressions_1.ExprUtils(options.schema, blocks_1.createExprVariables(options.contextVars)); + const valueType = exprUtils.getExprType(this.blockDef.filterExpr); + const valueIdTableId = exprUtils.getExprIdTable(this.blockDef.filterExpr); // Validate extra filter exprs if (this.blockDef.extraFilters) { - var _loop_1 = function (extraFilter) { + for (const extraFilter of this.blockDef.extraFilters) { // Validate rowset - var extraRowsetCV = options.contextVars.find(function (cv) { return cv.id === extraFilter.rowsetContextVarId && cv.type === "rowset"; }); + const extraRowsetCV = options.contextVars.find(cv => cv.id === extraFilter.rowsetContextVarId && cv.type === "rowset"); if (!extraRowsetCV) { - return { value: "Rowset required" }; + return "Rowset required"; } if (!extraFilter.filterExpr) { - return { value: "Filter expression required" }; + return "Filter expression required"; } // Validate expr - var error_1 = void 0; - error_1 = exprValidator.validateExpr(extraFilter.filterExpr, { + let error; + error = exprValidator.validateExpr(extraFilter.filterExpr, { table: extraRowsetCV.table, types: [valueType], idTable: valueIdTableId || undefined }); - if (error_1) { - return { value: error_1 }; + if (error) { + return error; } - }; - for (var _i = 0, _a = this.blockDef.extraFilters; _i < _a.length; _i++) { - var extraFilter = _a[_i]; - var state_1 = _loop_1(extraFilter); - if (typeof state_1 === "object") - return state_1.value; } } if (valueType === "id") { if (!valueIdTableId) { return "Id table required"; } - var valueIdTable = options.schema.getTable(valueIdTableId); + const valueIdTable = options.schema.getTable(valueIdTableId); if (!valueIdTable) { return "Id table missing"; } - var idMode = this.blockDef.idMode || "simple"; - var exprValidator_1 = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + const idMode = this.blockDef.idMode || "simple"; + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); if (this.blockDef.idWithin && !valueIdTable.ancestry && !valueIdTable.ancestryTable) { return "Within requires hierarchical table"; } @@ -141,7 +106,7 @@ var DropdownFilterBlock = /** @class */ (function (_super) { return "Label Expression required"; } // Validate expr - error = exprValidator_1.validateExpr(this.blockDef.idLabelExpr || null, { table: valueIdTableId, types: ["text"] }); + error = exprValidator.validateExpr(this.blockDef.idLabelExpr || null, { table: valueIdTableId, types: ["text"] }); if (error) { return error; } @@ -170,21 +135,19 @@ var DropdownFilterBlock = /** @class */ (function (_super) { return error; } // Validate orderBy - for (var _b = 0, _c = this.blockDef.idOrderBy || []; _b < _c.length; _b++) { - var orderBy = _c[_b]; - error = exprValidator_1.validateExpr(orderBy.expr, { table: valueIdTableId }); + for (const orderBy of this.blockDef.idOrderBy || []) { + error = exprValidator.validateExpr(orderBy.expr, { table: valueIdTableId }); if (error) { return error; } } // Validate search - for (var _d = 0, _e = this.blockDef.idSearchExprs; _d < _e.length; _d++) { - var searchExpr = _e[_d]; + for (const searchExpr of this.blockDef.idSearchExprs) { if (!searchExpr) { return "Search expression required"; } // Validate expr - error = exprValidator_1.validateExpr(searchExpr, { table: valueIdTableId, types: ["text", "enum", "enumset"] }); + error = exprValidator.validateExpr(searchExpr, { table: valueIdTableId, types: ["text", "enum", "enumset"] }); if (error) { return error; } @@ -192,20 +155,20 @@ var DropdownFilterBlock = /** @class */ (function (_super) { } } return null; - }; + } /** Generate a single synthetic context variable to allow embedded expressions to work in label */ - DropdownFilterBlock.prototype.generateEmbedContextVars = function (idTable) { + generateEmbedContextVars(idTable) { return [ { id: "dropdown-embed", name: "Label", table: idTable, type: "row" } ]; - }; + } /** Create a filter of the appropriate type for the value selected */ - DropdownFilterBlock.prototype.createFilter = function (rowsetContextVarId, filterExpr, schema, contextVars, value) { - var exprUtils = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)); - var valueType = exprUtils.getExprType(filterExpr); - var valueIdTable = exprUtils.getExprIdTable(filterExpr); - var contextVar = contextVars.find(function (cv) { return cv.id === rowsetContextVarId; }); - var table = contextVar.table; + createFilter(rowsetContextVarId, filterExpr, schema, contextVars, value) { + const exprUtils = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)); + const valueType = exprUtils.getExprType(filterExpr); + const valueIdTable = exprUtils.getExprIdTable(filterExpr); + const contextVar = contextVars.find(cv => cv.id === rowsetContextVarId); + const table = contextVar.table; switch (valueType) { case "enum": return { @@ -227,7 +190,7 @@ var DropdownFilterBlock = /** @class */ (function (_super) { }; case "date": case "datetime": - var dateMode = this.blockDef.dateMode || "full"; + const dateMode = this.blockDef.dateMode || "full"; if (dateMode == "full") { return { id: this.blockDef.id, @@ -292,27 +255,26 @@ var DropdownFilterBlock = /** @class */ (function (_super) { }; } throw new Error("Unknown type"); - }; - DropdownFilterBlock.prototype.renderDesign = function (props) { - var _this = this; - var contextVar = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var styles = { - control: function (base) { return (__assign(__assign({}, base), { minWidth: 150 })); }, + } + renderDesign(props) { + const contextVar = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const styles = { + control: (base) => (Object.assign(Object.assign({}, base), { minWidth: 150 })), // Keep menu above other controls - menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } + menuPortal: (style) => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) }; - var placeholder = localization_1.localize(this.blockDef.placeholder, props.locale); - var valueType = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).getExprType(this.blockDef.filterExpr); - var handleSetDefault = function (defaultValue) { - props.store.alterBlock(_this.blockDef.id, function (bd) { - return __assign(__assign({}, bd), { defaultValue: defaultValue }); + const placeholder = localization_1.localize(this.blockDef.placeholder, props.locale); + const valueType = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).getExprType(this.blockDef.filterExpr); + const handleSetDefault = (defaultValue) => { + props.store.alterBlock(this.blockDef.id, (bd) => { + return Object.assign(Object.assign({}, bd), { defaultValue }); }); }; if (valueType === "date" || valueType === "datetime") { - var dateMode = this.blockDef.dateMode || "full"; + const dateMode = this.blockDef.dateMode || "full"; if (dateMode == "full") { // Fake table - var table = contextVar ? contextVar.table || "" : ""; + const table = contextVar ? contextVar.table || "" : ""; return (React.createElement("div", { style: { padding: 5 } }, React.createElement(DateExprComponent_1.default, { table: table, datetime: valueType === "datetime", value: this.blockDef.defaultValue, onChange: handleSetDefault, placeholder: placeholder, locale: props.locale }))); } @@ -330,17 +292,16 @@ var DropdownFilterBlock = /** @class */ (function (_super) { } return React.createElement("div", { style: { padding: 5 } }, React.createElement(react_select_1.default, { classNamePrefix: "react-select-short", styles: styles, placeholder: placeholder, menuPortalTarget: document.body })); - }; - DropdownFilterBlock.prototype.getInitialFilters = function (contextVarId, instanceCtx) { - var filters = []; + } + getInitialFilters(contextVarId, instanceCtx) { + const filters = []; if (contextVarId == this.blockDef.rowsetContextVarId) { if (this.blockDef.defaultValue) { filters.push(this.createFilter(this.blockDef.rowsetContextVarId, this.blockDef.filterExpr, instanceCtx.schema, instanceCtx.contextVars, this.blockDef.defaultValue)); } } // Add extra filters - for (var _i = 0, _a = this.blockDef.extraFilters || []; _i < _a.length; _i++) { - var extraFilter = _a[_i]; + for (const extraFilter of this.blockDef.extraFilters || []) { if (contextVarId == extraFilter.rowsetContextVarId) { if (this.blockDef.defaultValue) { filters.push(this.createFilter(extraFilter.rowsetContextVarId, extraFilter.filterExpr, instanceCtx.schema, instanceCtx.contextVars, this.blockDef.defaultValue)); @@ -348,27 +309,25 @@ var DropdownFilterBlock = /** @class */ (function (_super) { } } return filters; - }; - DropdownFilterBlock.prototype.renderInstance = function (ctx) { - var _this = this; - var contextVar = ctx.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var filter = ctx.getFilters(this.blockDef.rowsetContextVarId).find(function (f) { return f.id === _this.blockDef.id; }); - var value = filter ? filter.memo : null; - var handleChange = function (newValue) { + } + renderInstance(ctx) { + const contextVar = ctx.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const filter = ctx.getFilters(this.blockDef.rowsetContextVarId).find(f => f.id === this.blockDef.id); + const value = filter ? filter.memo : null; + const handleChange = (newValue) => { // Create filter - var newFilter = _this.createFilter(_this.blockDef.rowsetContextVarId, _this.blockDef.filterExpr, ctx.schema, ctx.contextVars, newValue); + const newFilter = this.createFilter(this.blockDef.rowsetContextVarId, this.blockDef.filterExpr, ctx.schema, ctx.contextVars, newValue); ctx.setFilter(contextVar.id, newFilter); // Create extra filters - for (var _i = 0, _a = _this.blockDef.extraFilters || []; _i < _a.length; _i++) { - var extraFilter = _a[_i]; - var newExtraFilter = _this.createFilter(extraFilter.rowsetContextVarId, extraFilter.filterExpr, ctx.schema, ctx.contextVars, newValue); + for (const extraFilter of this.blockDef.extraFilters || []) { + const newExtraFilter = this.createFilter(extraFilter.rowsetContextVarId, extraFilter.filterExpr, ctx.schema, ctx.contextVars, newValue); ctx.setFilter(extraFilter.rowsetContextVarId, newExtraFilter); } }; - var exprUtils = new mwater_expressions_1.ExprUtils(ctx.schema, blocks_1.createExprVariables(ctx.contextVars)); - var valueType = exprUtils.getExprType(this.blockDef.filterExpr); - var placeholder = localization_1.localize(this.blockDef.placeholder, ctx.locale); - var elem; + const exprUtils = new mwater_expressions_1.ExprUtils(ctx.schema, blocks_1.createExprVariables(ctx.contextVars)); + const valueType = exprUtils.getExprType(this.blockDef.filterExpr); + const placeholder = localization_1.localize(this.blockDef.placeholder, ctx.locale); + let elem; switch (valueType) { case "enum": elem = React.createElement(EnumInstance_1.default, { blockDef: this.blockDef, schema: ctx.schema, contextVars: ctx.contextVars, value: value, onChange: handleChange, locale: ctx.locale }); @@ -381,7 +340,7 @@ var DropdownFilterBlock = /** @class */ (function (_super) { break; case "date": case "datetime": - var dateMode = this.blockDef.dateMode || "full"; + const dateMode = this.blockDef.dateMode || "full"; if (dateMode == "full") { elem = React.createElement(DateExprComponent_1.default, { datetime: valueType == "datetime", table: contextVar.table, value: value, onChange: handleChange, placeholder: placeholder, locale: ctx.locale }); } @@ -399,28 +358,27 @@ var DropdownFilterBlock = /** @class */ (function (_super) { elem = React.createElement("div", null); } return React.createElement("div", { style: { padding: 5 } }, elem); - }; - DropdownFilterBlock.prototype.renderEditor = function (ctx) { - var _this = this; + } + renderEditor(ctx) { // Get rowset context variable - var rowsetCV = ctx.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var idMode = this.blockDef.idMode || "simple"; - var exprUtils = new mwater_expressions_1.ExprUtils(ctx.schema, blocks_1.createExprVariables(ctx.contextVars)); - var exprType = exprUtils.getExprType(this.blockDef.filterExpr); - var isIdType = exprType == "id"; - var idTableId = exprUtils.getExprIdTable(this.blockDef.filterExpr); - var idTable = idTableId ? ctx.schema.getTable(idTableId) : null; - var isIdTableHierarchical = idTable ? idTable.ancestryTable != null || idTable.ancestry != null : null; - var isDateType = exprType == "date" || exprType == "datetime"; - var handleExprChange = function (expr) { - ctx.store.replaceBlock(immer_1.default(_this.blockDef, function (draft) { + const rowsetCV = ctx.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const idMode = this.blockDef.idMode || "simple"; + const exprUtils = new mwater_expressions_1.ExprUtils(ctx.schema, blocks_1.createExprVariables(ctx.contextVars)); + const exprType = exprUtils.getExprType(this.blockDef.filterExpr); + const isIdType = exprType == "id"; + const idTableId = exprUtils.getExprIdTable(this.blockDef.filterExpr); + const idTable = idTableId ? ctx.schema.getTable(idTableId) : null; + const isIdTableHierarchical = idTable ? idTable.ancestryTable != null || idTable.ancestry != null : null; + const isDateType = exprType == "date" || exprType == "datetime"; + const handleExprChange = (expr) => { + ctx.store.replaceBlock(immer_1.default(this.blockDef, (draft) => { // Clear default value if expression changes draft.filterExpr = expr; delete draft.defaultValue; })); }; - var handleDateModeChange = function (dateMode) { - ctx.store.replaceBlock(immer_1.default(_this.blockDef, function (draft) { + const handleDateModeChange = (dateMode) => { + ctx.store.replaceBlock(immer_1.default(this.blockDef, (draft) => { // Clear default value if expression changes draft.dateMode = dateMode; delete draft.defaultValue; @@ -428,13 +386,13 @@ var DropdownFilterBlock = /** @class */ (function (_super) { }; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "rowsetContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: ctx.contextVars, types: ["rowset"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "rowsetContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: ctx.contextVars, types: ["rowset"] }))), rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter expression" }, React.createElement(mwater_expressions_ui_1.ExprComponent, { value: this.blockDef.filterExpr, schema: ctx.schema, dataSource: ctx.dataSource, onChange: handleExprChange, table: rowsetCV.table, variables: blocks_1.createExprVariables(ctx.contextVars), types: ["enum", "enumset", "text", "date", "datetime", "id", "text[]"] })) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Placeholder" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "placeholder" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: ctx.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "placeholder" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: ctx.locale }))), isDateType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Mode", key: "dateMode" }, React.createElement(bootstrap_1.Toggle, { value: this.blockDef.dateMode || "full", onChange: handleDateModeChange, options: [ @@ -446,71 +404,64 @@ var DropdownFilterBlock = /** @class */ (function (_super) { : null, isIdType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Mode", key: "mode" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idMode" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value || "simple", onChange: onChange, options: [ - { value: "simple", label: "Simple" }, - { value: "advanced", label: "Advanced" } - ] }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idMode" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "simple", onChange: onChange, options: [ + { value: "simple", label: "Simple" }, + { value: "advanced", label: "Advanced" } + ] }))) : null, isIdTableHierarchical ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Match Mode", key: "within" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idWithin" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value || false, onChange: onChange, options: [ - { value: false, label: "Exact" }, - { value: true, label: "Is Within" } - ] }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idWithin" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || false, onChange: onChange, options: [ + { value: false, label: "Exact" }, + { value: true, label: "Is Within" } + ] }))) : null, isIdType && idMode == "simple" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label Expression", key: "idLabelExpr" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idLabelExpr" }, function (value, onChange) { return React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value || null, onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, types: ["text"], table: idTableId }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idLabelExpr" }, (value, onChange) => React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value || null, onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, types: ["text"], table: idTableId }))) : null, isIdType && idMode == "advanced" ? React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Label", key: "idLabelText" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idLabelText" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: ctx.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idLabelText" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: ctx.locale }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Embedded label expressions", help: "Reference in text as {0}, {1}, etc.", key: "idLabelEmbeddedExprs" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idLabelEmbeddedExprs" }, function (value, onChange) { return (React.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, contextVars: _this.generateEmbedContextVars(idTableId) })); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idLabelEmbeddedExprs" }, (value, onChange) => (React.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, contextVars: this.generateEmbedContextVars(idTableId) })))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Option ordering", key: "idOrderBy" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idOrderBy" }, function (value, onChange) { - return React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value || [], onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, contextVars: ctx.contextVars, table: idTableId }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idOrderBy" }, (value, onChange) => React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value || [], onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, contextVars: ctx.contextVars, table: idTableId }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Search expressions", key: "idSearchExprs" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idSearchExprs" }, function (value, onItemsChange) { - var handleAddSearchExpr = function () { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idSearchExprs" }, (value, onItemsChange) => { + const handleAddSearchExpr = () => { onItemsChange((value || []).concat(null)); }; return (React.createElement("div", null, - React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onItemsChange }, function (expr, onExprChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: expr, schema: ctx.schema, dataSource: ctx.dataSource, onChange: onExprChange, table: idTableId, types: ["text", "enum", "enumset"], variables: blocks_1.createExprVariables(ctx.contextVars) })); }), + React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onItemsChange }, (expr, onExprChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: expr, schema: ctx.schema, dataSource: ctx.dataSource, onChange: onExprChange, table: idTableId, types: ["text", "enum", "enumset"], variables: blocks_1.createExprVariables(ctx.contextVars) }))), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddSearchExpr }, "+ Add Expression"))); }))) : null, isIdType ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter expression for id table", key: "idFilterExpr" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idFilterExpr" }, function (value, onChange) { return React.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, table: idTableId }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "idFilterExpr" }, (value, onChange) => React.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: ctx.schema, dataSource: ctx.dataSource, table: idTableId }))) : null, rowsetCV && this.blockDef.filterExpr ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Additional filters on other rowsets" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "extraFilters" }, function (value, onItemsChange) { - var handleAddExtraFilter = function () { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: ctx.store.replaceBlock, property: "extraFilters" }, (value, onItemsChange) => { + const handleAddExtraFilter = () => { onItemsChange((value || []).concat({ rowsetContextVarId: null, filterExpr: null })); }; return (React.createElement("div", null, - React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onItemsChange }, function (extraFilter, onExtraFilterChange) { - var extraFilterCV = ctx.contextVars.find(function (cv) { return cv.id === extraFilter.rowsetContextVarId; }); + React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onItemsChange }, (extraFilter, onExtraFilterChange) => { + const extraFilterCV = ctx.contextVars.find(cv => cv.id === extraFilter.rowsetContextVarId); return React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: extraFilter, onChange: onExtraFilterChange, property: "rowsetContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: ctx.contextVars, types: ["rowset"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: extraFilter, onChange: onExtraFilterChange, property: "rowsetContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: ctx.contextVars, types: ["rowset"] }))), extraFilterCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter expression" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: extraFilter, onChange: onExtraFilterChange, property: "filterExpr" }, function (value, onChange) { return React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, schema: ctx.schema, dataSource: ctx.dataSource, onChange: onChange, table: extraFilterCV.table, types: ["enum", "enumset", "text", "date", "datetime", "id"] }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: extraFilter, onChange: onExtraFilterChange, property: "filterExpr" }, (value, onChange) => React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, schema: ctx.schema, dataSource: ctx.dataSource, onChange: onChange, table: extraFilterCV.table, types: ["enum", "enumset", "text", "date", "datetime", "id"] }))) : null); }), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddExtraFilter }, "+ Add Filter"))); })) : null)); - }; - return DropdownFilterBlock; -}(LeafBlock_1.default)); + } +} exports.DropdownFilterBlock = DropdownFilterBlock; diff --git a/lib/widgets/blocks/dropdownFilter/dropdownFilter.test.js b/lib/widgets/blocks/dropdownFilter/dropdownFilter.test.js index 655134f2..8ae48be2 100644 --- a/lib/widgets/blocks/dropdownFilter/dropdownFilter.test.js +++ b/lib/widgets/blocks/dropdownFilter/dropdownFilter.test.js @@ -3,22 +3,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var schema_1 = __importDefault(require("../../../__fixtures__/schema")); -var enzyme_1 = require("enzyme"); -var dropdownFilter_1 = require("./dropdownFilter"); -var EnumInstance_1 = __importDefault(require("./EnumInstance")); -var TextInstance_1 = __importDefault(require("./TextInstance")); -describe("enum filter", function () { - var dropdownFilterBlockDef = { +const schema_1 = __importDefault(require("../../../__fixtures__/schema")); +const enzyme_1 = require("enzyme"); +const dropdownFilter_1 = require("./dropdownFilter"); +const EnumInstance_1 = __importDefault(require("./EnumInstance")); +const TextInstance_1 = __importDefault(require("./TextInstance")); +describe("enum filter", () => { + const dropdownFilterBlockDef = { id: "ddf1", filterExpr: { type: "field", table: "t1", column: "enum" }, placeholder: null, rowsetContextVarId: "cv1", type: "dropdownFilter" }; - var dropdownFilterBlock = new dropdownFilter_1.DropdownFilterBlock(dropdownFilterBlockDef); - test("sets filter on change", function () { - var props = { + const dropdownFilterBlock = new dropdownFilter_1.DropdownFilterBlock(dropdownFilterBlockDef); + test("sets filter on change", () => { + const props = { schema: schema_1.default(), getFilters: jest.fn(), setFilter: jest.fn(), @@ -26,7 +26,7 @@ describe("enum filter", function () { contextVars: [{ id: "cv1", type: "rowset", table: "t1" }] }; props.getFilters.mockReturnValue([]); - var inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); + const inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); // Set an option inst.find(EnumInstance_1.default).prop("onChange")("op1"); expect(props.setFilter.mock.calls[0]).toEqual(["cv1", { @@ -38,8 +38,8 @@ describe("enum filter", function () { memo: "op1" }]); }); - test("clears filter on null change", function () { - var props = { + test("clears filter on null change", () => { + const props = { schema: schema_1.default(), getFilters: jest.fn(), setFilter: jest.fn(), @@ -47,7 +47,7 @@ describe("enum filter", function () { contextVars: [{ id: "cv1", type: "rowset", table: "t1" }] }; props.getFilters.mockReturnValue([]); - var inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); + const inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); // Set an option inst.find(EnumInstance_1.default).prop("onChange")(null); expect(props.setFilter.mock.calls[0]).toEqual(["cv1", { @@ -57,17 +57,17 @@ describe("enum filter", function () { }]); }); }); -describe("text filter", function () { - var dropdownFilterBlockDef = { +describe("text filter", () => { + const dropdownFilterBlockDef = { id: "ddf1", filterExpr: { type: "field", table: "t1", column: "text" }, placeholder: null, rowsetContextVarId: "cv1", type: "dropdownFilter" }; - var dropdownFilterBlock = new dropdownFilter_1.DropdownFilterBlock(dropdownFilterBlockDef); - test("sets filter on change", function () { - var props = { + const dropdownFilterBlock = new dropdownFilter_1.DropdownFilterBlock(dropdownFilterBlockDef); + test("sets filter on change", () => { + const props = { schema: schema_1.default(), getFilters: jest.fn(), setFilter: jest.fn(), @@ -75,7 +75,7 @@ describe("text filter", function () { contextVars: [{ id: "cv1", type: "rowset", table: "t1" }] }; props.getFilters.mockReturnValue([]); - var inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); + const inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); // Set an option inst.find(TextInstance_1.default).prop("onChange")("op1"); expect(props.setFilter.mock.calls[0]).toEqual(["cv1", { @@ -87,8 +87,8 @@ describe("text filter", function () { memo: "op1" }]); }); - test("clears filter on null change", function () { - var props = { + test("clears filter on null change", () => { + const props = { schema: schema_1.default(), getFilters: jest.fn(), setFilter: jest.fn(), @@ -96,7 +96,7 @@ describe("text filter", function () { contextVars: [{ id: "cv1", type: "rowset", table: "t1" }] }; props.getFilters.mockReturnValue([]); - var inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); + const inst = enzyme_1.shallow(dropdownFilterBlock.renderInstance(props)); // Set an option inst.find(TextInstance_1.default).prop("onChange")(null); expect(props.setFilter.mock.calls[0]).toEqual(["cv1", { diff --git a/lib/widgets/blocks/expression.js b/lib/widgets/blocks/expression.js index 00a1a07d..2e49753a 100644 --- a/lib/widgets/blocks/expression.js +++ b/lib/widgets/blocks/expression.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,32 +23,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExpressionBlock = void 0; -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var mwater_expressions_1 = require("mwater-expressions"); -var d3Format = __importStar(require("d3-format")); -var moment_1 = __importDefault(require("moment")); -var textual_1 = require("./textual"); -var localization_1 = require("../localization"); -var ExpressionBlock = /** @class */ (function (_super) { - __extends(ExpressionBlock, _super); - function ExpressionBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ExpressionBlock.prototype.getContextVarExprs = function (contextVar) { +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const mwater_expressions_1 = require("mwater-expressions"); +const d3Format = __importStar(require("d3-format")); +const moment_1 = __importDefault(require("moment")); +const textual_1 = require("./textual"); +const localization_1 = require("../localization"); +class ExpressionBlock extends textual_1.TextualBlock { + getContextVarExprs(contextVar) { return (contextVar.id === this.blockDef.contextVarId && this.blockDef.expr) ? [this.blockDef.expr] : []; - }; - ExpressionBlock.prototype.validate = function (ctx) { + } + validate(ctx) { return blocks_1.validateContextVarExpr({ schema: ctx.schema, contextVars: ctx.contextVars, contextVarId: this.blockDef.contextVarId, expr: this.blockDef.expr }); - }; - ExpressionBlock.prototype.renderDesign = function (props) { - var summary = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).summarizeExpr(this.blockDef.expr, props.locale); + } + renderDesign(props) { + let summary = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).summarizeExpr(this.blockDef.expr, props.locale); if (summary.length > 20) { summary = summary.substr(0, 20) + "..."; } @@ -80,15 +52,15 @@ var ExpressionBlock = /** @class */ (function (_super) { React.createElement("span", { className: "text-muted" }, "<"), summary, React.createElement("span", { className: "text-muted" }, ">"))); - }; - ExpressionBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { if (!this.blockDef.expr) { return React.createElement("div", null); } - var value = props.getContextVarExprValue(this.blockDef.contextVarId, this.blockDef.expr); - var exprType = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).getExprType(this.blockDef.expr); - var formatLocale = props.formatLocale || d3Format; - var str; + const value = props.getContextVarExprValue(this.blockDef.contextVarId, this.blockDef.expr); + const exprType = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).getExprType(this.blockDef.expr); + const formatLocale = props.formatLocale || d3Format; + let str; if (value == null) { str = ""; } @@ -123,7 +95,7 @@ var ExpressionBlock = /** @class */ (function (_super) { str = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).stringifyExprLiteral(this.blockDef.expr, value, props.locale); } } - var node; + let node; if (this.blockDef.html) { node = this.processHTML(str); } @@ -134,38 +106,36 @@ var ExpressionBlock = /** @class */ (function (_super) { node = str; } return this.renderText(node); - }; - ExpressionBlock.prototype.renderEditor = function (props) { - var _this = this; - var contextVar = this.blockDef.contextVarId ? props.contextVars.find(function (cv) { return cv.id === _this.blockDef.contextVarId; }) || null : null; - var exprType = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).getExprType(this.blockDef.expr); + } + renderEditor(props) { + const contextVar = this.blockDef.contextVarId ? props.contextVars.find(cv => cv.id === this.blockDef.contextVarId) || null : null; + const exprType = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)).getExprType(this.blockDef.expr); return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Expression" }, - React.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, aggrStatuses: contextVar && contextVar.type == "row" ? ["individual", "literal"] : ["individual", "aggregate", "literal"], contextVarId: this.blockDef.contextVarId, expr: this.blockDef.expr, onChange: function (contextVarId, expr) { - props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { contextVarId: contextVarId, expr: expr })); + React.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, aggrStatuses: contextVar && contextVar.type == "row" ? ["individual", "literal"] : ["individual", "aggregate", "literal"], contextVarId: this.blockDef.contextVarId, expr: this.blockDef.expr, onChange: (contextVarId, expr) => { + props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { contextVarId, expr })); } })), exprType === "number" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Number Format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, function (value, onChange) { return (React.createElement(propertyEditors_1.NumberFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, (value, onChange) => (React.createElement(propertyEditors_1.NumberFormatEditor, { value: value, onChange: onChange })))) : null, exprType === "date" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Date Format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, function (value, onChange) { return (React.createElement(propertyEditors_1.DateFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, (value, onChange) => (React.createElement(propertyEditors_1.DateFormatEditor, { value: value, onChange: onChange })))) : null, exprType === "datetime" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Date/time Format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, function (value, onChange) { return (React.createElement(propertyEditors_1.DatetimeFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "format" }, (value, onChange) => (React.createElement(propertyEditors_1.DatetimeFormatEditor, { value: value, onChange: onChange })))) : null, exprType === "boolean" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Display True As" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "trueLabel" }, function (value, onChange) { return (React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "True" })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "trueLabel" }, (value, onChange) => (React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "True" })))) : null, exprType === "boolean" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Display False As" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "falseLabel" }, function (value, onChange) { return (React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "False" })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "falseLabel" }, (value, onChange) => (React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, placeholder: "False" })))) : null, this.renderTextualEditor(props))); - }; - return ExpressionBlock; -}(textual_1.TextualBlock)); + } +} exports.ExpressionBlock = ExpressionBlock; diff --git a/lib/widgets/blocks/fixedTable.js b/lib/widgets/blocks/fixedTable.js index c8232dc6..1dac05fd 100644 --- a/lib/widgets/blocks/fixedTable.js +++ b/lib/widgets/blocks/fixedTable.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,42 +23,36 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.setNumColumns = exports.setNumRows = exports.FixedTableBlock = void 0; -var React = __importStar(require("react")); -var _ = __importStar(require("lodash")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var immer_1 = __importDefault(require("immer")); -var FixedTableBlock = /** @class */ (function (_super) { - __extends(FixedTableBlock, _super); - function FixedTableBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - FixedTableBlock.prototype.getChildren = function (contextVars) { +const React = __importStar(require("react")); +const _ = __importStar(require("lodash")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const immer_1 = __importDefault(require("immer")); +class FixedTableBlock extends blocks_1.Block { + getChildren(contextVars) { // Get for all cells - return _.compact(_.flatten(this.blockDef.rows.map(function (r) { return r.cells.map(function (c) { return c.content; }); }))).map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; - FixedTableBlock.prototype.validate = function () { return null; }; - FixedTableBlock.prototype.processChildren = function (action) { - var _this = this; - return immer_1.default(this.blockDef, function (draft) { + return _.compact(_.flatten(this.blockDef.rows.map(r => r.cells.map(c => c.content)))).map(bd => ({ blockDef: bd, contextVars: contextVars })); + } + validate() { return null; } + processChildren(action) { + return immer_1.default(this.blockDef, (draft) => { // For each row - _this.blockDef.rows.forEach(function (row, rowIndex) { - row.cells.forEach(function (cell, cellIndex) { + this.blockDef.rows.forEach((row, rowIndex) => { + row.cells.forEach((cell, cellIndex) => { draft.rows[rowIndex].cells[cellIndex].content = action(cell.content); }); }); }); - }; - FixedTableBlock.prototype.renderDesign = function (props) { - var _this = this; + } + renderDesign(props) { // Handle setting of a cell contents - var handleSet = function (rowIndex, columnIndex, content) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const handleSet = (rowIndex, columnIndex, content) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.rows[rowIndex].cells[columnIndex].content = content; }), content.id); }; - var className = "table"; + let className = "table"; switch (this.blockDef.borders || "horizontal") { case "all": className += " table-bordered"; @@ -86,17 +67,16 @@ var FixedTableBlock = /** @class */ (function (_super) { break; } return (React.createElement("table", { className: className }, - React.createElement("colgroup", null, _.range(this.blockDef.numColumns).map(function (colIndex) { + React.createElement("colgroup", null, _.range(this.blockDef.numColumns).map((colIndex) => { // Determine width - var columns = _this.blockDef.columns; - var width = columns && columns[colIndex] ? columns[colIndex].columnWidth : "auto"; + const columns = this.blockDef.columns; + const width = columns && columns[colIndex] ? columns[colIndex].columnWidth : "auto"; return React.createElement("col", { key: colIndex, style: { width: width } }); })), - React.createElement("tbody", null, this.blockDef.rows.map(function (row, rowIndex) { return (React.createElement("tr", { key: rowIndex }, row.cells.map(function (cell, columnIndex) { return React.createElement("td", { key: columnIndex }, props.renderChildBlock(props, cell.content, handleSet.bind(null, rowIndex, columnIndex))); }))); })))); - }; - FixedTableBlock.prototype.renderInstance = function (props) { - var _this = this; - var className = "table"; + React.createElement("tbody", null, this.blockDef.rows.map((row, rowIndex) => (React.createElement("tr", { key: rowIndex }, row.cells.map((cell, columnIndex) => React.createElement("td", { key: columnIndex }, props.renderChildBlock(props, cell.content, handleSet.bind(null, rowIndex, columnIndex)))))))))); + } + renderInstance(props) { + let className = "table"; switch (this.blockDef.borders || "horizontal") { case "all": className += " table-bordered"; @@ -111,27 +91,26 @@ var FixedTableBlock = /** @class */ (function (_super) { break; } return (React.createElement("table", { className: className }, - React.createElement("colgroup", null, _.range(this.blockDef.numColumns).map(function (colIndex) { + React.createElement("colgroup", null, _.range(this.blockDef.numColumns).map((colIndex) => { // Determine width - var columns = _this.blockDef.columns; - var width = columns && columns[colIndex] ? columns[colIndex].columnWidth : "auto"; + const columns = this.blockDef.columns; + const width = columns && columns[colIndex] ? columns[colIndex].columnWidth : "auto"; return React.createElement("col", { key: colIndex, style: { width: width } }); })), - React.createElement("tbody", null, this.blockDef.rows.map(function (row, rowIndex) { return (React.createElement("tr", { key: rowIndex }, row.cells.map(function (cell, columnIndex) { return React.createElement("td", { key: columnIndex }, props.renderChildBlock(props, cell.content)); }))); })))); - }; - FixedTableBlock.prototype.renderEditor = function (props) { - var _this = this; - var handleNumRowsChange = function (numRows) { + React.createElement("tbody", null, this.blockDef.rows.map((row, rowIndex) => (React.createElement("tr", { key: rowIndex }, row.cells.map((cell, columnIndex) => React.createElement("td", { key: columnIndex }, props.renderChildBlock(props, cell.content))))))))); + } + renderEditor(props) { + const handleNumRowsChange = (numRows) => { if (numRows < 1) { return; } - props.store.replaceBlock(setNumRows(_this.blockDef, numRows)); + props.store.replaceBlock(setNumRows(this.blockDef, numRows)); }; - var handleNumColumnsChange = function (numColumns) { + const handleNumColumnsChange = (numColumns) => { if (numColumns < 1) { return; } - props.store.replaceBlock(setNumColumns(_this.blockDef, numColumns)); + props.store.replaceBlock(setNumColumns(this.blockDef, numColumns)); }; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Number of Rows" }, @@ -139,22 +118,21 @@ var FixedTableBlock = /** @class */ (function (_super) { React.createElement(propertyEditors_1.LabeledProperty, { label: "Number of Columns" }, React.createElement(bootstrap_1.NumberInput, { value: this.blockDef.numColumns, onChange: handleNumColumnsChange, decimal: false })), React.createElement(propertyEditors_1.LabeledProperty, { label: "Borders" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "borders" }, function (value, onChange) { return React.createElement(bootstrap_1.Toggle, { value: value || "horizontal", onChange: onChange, options: [{ value: "none", label: "None" }, { value: "horizontal", label: "Horizontal" }, { value: "all", label: "All" }] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "borders" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "horizontal", onChange: onChange, options: [{ value: "none", label: "None" }, { value: "horizontal", label: "Horizontal" }, { value: "all", label: "All" }] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Padding" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "padding" }, function (value, onChange) { return React.createElement(bootstrap_1.Toggle, { value: value || "normal", onChange: onChange, options: [{ value: "normal", label: "Normal" }, { value: "compact", label: "Compact" }] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "padding" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "normal", onChange: onChange, options: [{ value: "normal", label: "Normal" }, { value: "compact", label: "Compact" }] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Columns" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columns" }, function (value, onChange) { return React.createElement(ColumnsEditor, { value: value, onChange: onChange, numColumns: _this.blockDef.numColumns }); })))); - }; - return FixedTableBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columns" }, (value, onChange) => React.createElement(ColumnsEditor, { value: value, onChange: onChange, numColumns: this.blockDef.numColumns }))))); + } +} exports.FixedTableBlock = FixedTableBlock; /** Function to set the number of rows, adding/removing as necessary */ function setNumRows(blockDef, numRows) { - return immer_1.default(blockDef, function (d) { + return immer_1.default(blockDef, (d) => { // Add rows if (numRows > blockDef.numRows) { - for (var i = 0; i < numRows - blockDef.numRows; i++) { - d.rows.push({ cells: _.range(blockDef.numColumns).map(function () { return ({ content: null }); }) }); + for (let i = 0; i < numRows - blockDef.numRows; i++) { + d.rows.push({ cells: _.range(blockDef.numColumns).map(() => ({ content: null })) }); } } // Remove rows @@ -167,29 +145,27 @@ function setNumRows(blockDef, numRows) { exports.setNumRows = setNumRows; /** Function to set the number of columns, adding/removing as necessary */ function setNumColumns(blockDef, numColumns) { - return immer_1.default(blockDef, function (d) { + return immer_1.default(blockDef, (d) => { // Create columns if they don't exist if (!d.columns) { - d.columns = _.range(blockDef.numColumns).map(function (c) { return ({ columnWidth: "auto" }); }); + d.columns = _.range(blockDef.numColumns).map(c => ({ columnWidth: "auto" })); } // Add columns if (numColumns > blockDef.numColumns) { // Add to each row - for (var _i = 0, _a = d.rows; _i < _a.length; _i++) { - var row = _a[_i]; - for (var i = 0; i < numColumns - blockDef.numColumns; i++) { + for (const row of d.rows) { + for (let i = 0; i < numColumns - blockDef.numColumns; i++) { row.cells.push({ content: null }); } } // Add to columns - for (var i = 0; i < numColumns - blockDef.numColumns; i++) { + for (let i = 0; i < numColumns - blockDef.numColumns; i++) { d.columns.push({ columnWidth: "auto" }); } } // Remove columns if (numColumns < blockDef.numColumns) { - for (var _b = 0, _c = d.rows; _b < _c.length; _b++) { - var row = _c[_b]; + for (const row of d.rows) { row.cells.splice(numColumns, blockDef.numColumns - numColumns); } d.columns.splice(numColumns, blockDef.numColumns - numColumns); @@ -199,15 +175,15 @@ function setNumColumns(blockDef, numColumns) { } exports.setNumColumns = setNumColumns; /** Edits column info */ -var ColumnsEditor = function (props) { - var handleColumnWidthChange = function (colIndex, columnWidth) { - props.onChange(immer_1.default(props.value || [], function (draft) { +const ColumnsEditor = (props) => { + const handleColumnWidthChange = (colIndex, columnWidth) => { + props.onChange(immer_1.default(props.value || [], draft => { // Make sure exists draft[colIndex] = draft[colIndex] || { columnWidth: "auto" }; draft[colIndex].columnWidth = columnWidth; })); }; - return React.createElement("ul", { className: "list-group" }, _.map(_.range(props.numColumns), function (colIndex) { + return React.createElement("ul", { className: "list-group" }, _.map(_.range(props.numColumns), colIndex => { return React.createElement("li", { className: "list-group-item", key: colIndex }, React.createElement(propertyEditors_1.LabeledProperty, { label: "Width", key: "width" }, React.createElement(propertyEditors_1.TableColumnWidthEditor, { columnWidth: props.value && props.value[colIndex] ? props.value[colIndex].columnWidth : "auto", onChange: handleColumnWidthChange.bind(null, colIndex) }))); diff --git a/lib/widgets/blocks/fixedTable.test.js b/lib/widgets/blocks/fixedTable.test.js index 11881b58..41bb5cc6 100644 --- a/lib/widgets/blocks/fixedTable.test.js +++ b/lib/widgets/blocks/fixedTable.test.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var fixedTable_1 = require("./fixedTable"); -test("adds rows", function () { - var blockDef = { +const fixedTable_1 = require("./fixedTable"); +test("adds rows", () => { + const blockDef = { id: "xyz", type: "fixedTable", numRows: 1, @@ -11,7 +11,7 @@ test("adds rows", function () { { cells: [{ content: { id: "b11", type: "none" } }] } ] }; - var newBlockDef = fixedTable_1.setNumRows(blockDef, 2); + const newBlockDef = fixedTable_1.setNumRows(blockDef, 2); expect(newBlockDef.numRows).toBe(2); expect(newBlockDef.numColumns).toBe(1); expect(newBlockDef.rows).toEqual([ @@ -19,8 +19,8 @@ test("adds rows", function () { { cells: [{ content: null }] } ]); }); -test("removes rows", function () { - var blockDef = { +test("removes rows", () => { + const blockDef = { id: "xyz", type: "fixedTable", numRows: 2, @@ -30,15 +30,15 @@ test("removes rows", function () { { cells: [{ content: { id: "b21", type: "none" } }] } ] }; - var newBlockDef = fixedTable_1.setNumRows(blockDef, 1); + const newBlockDef = fixedTable_1.setNumRows(blockDef, 1); expect(newBlockDef.numRows).toBe(1); expect(newBlockDef.numColumns).toBe(1); expect(newBlockDef.rows).toEqual([ { cells: [{ content: { id: "b11", type: "none" } }] }, ]); }); -test("adds columns", function () { - var blockDef = { +test("adds columns", () => { + const blockDef = { id: "xyz", type: "fixedTable", numRows: 1, @@ -47,15 +47,15 @@ test("adds columns", function () { { cells: [{ content: { id: "b11", type: "none" } }] } ] }; - var newBlockDef = fixedTable_1.setNumColumns(blockDef, 2); + const newBlockDef = fixedTable_1.setNumColumns(blockDef, 2); expect(newBlockDef.numRows).toBe(1); expect(newBlockDef.numColumns).toBe(2); expect(newBlockDef.rows).toEqual([ { cells: [{ content: { id: "b11", type: "none" } }, { content: null }] }, ]); }); -test("removes columns", function () { - var blockDef = { +test("removes columns", () => { + const blockDef = { id: "xyz", type: "fixedTable", numRows: 1, @@ -64,7 +64,7 @@ test("removes columns", function () { { cells: [{ content: { id: "b11", type: "none" } }, { content: { id: "b12", type: "none" } }] } ] }; - var newBlockDef = fixedTable_1.setNumColumns(blockDef, 1); + const newBlockDef = fixedTable_1.setNumColumns(blockDef, 1); expect(newBlockDef.numRows).toBe(1); expect(newBlockDef.numColumns).toBe(1); expect(newBlockDef.rows).toEqual([ diff --git a/lib/widgets/blocks/float.js b/lib/widgets/blocks/float.js index 852b57fa..79c0ccba 100644 --- a/lib/widgets/blocks/float.js +++ b/lib/widgets/blocks/float.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,72 +23,61 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FloatBlock = void 0; -var React = __importStar(require("react")); -var _ = __importStar(require("lodash")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var immer_1 = __importDefault(require("immer")); -var FloatBlock = /** @class */ (function (_super) { - __extends(FloatBlock, _super); - function FloatBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - FloatBlock.prototype.getChildren = function (contextVars) { +const React = __importStar(require("react")); +const _ = __importStar(require("lodash")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const immer_1 = __importDefault(require("immer")); +class FloatBlock extends blocks_1.Block { + getChildren(contextVars) { // Get for all cells - return _.compact([this.blockDef.mainContent, this.blockDef.floatContent]).map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; - FloatBlock.prototype.validate = function () { return null; }; - FloatBlock.prototype.processChildren = function (action) { - var _this = this; - return immer_1.default(this.blockDef, function (draft) { - draft.mainContent = action(_this.blockDef.mainContent); - draft.floatContent = action(_this.blockDef.floatContent); + return _.compact([this.blockDef.mainContent, this.blockDef.floatContent]).map(bd => ({ blockDef: bd, contextVars: contextVars })); + } + validate() { return null; } + processChildren(action) { + return immer_1.default(this.blockDef, (draft) => { + draft.mainContent = action(this.blockDef.mainContent); + draft.floatContent = action(this.blockDef.floatContent); }); - }; - FloatBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSetMainContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleSetMainContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.mainContent = blockDef; }), blockDef.id); }; - var handleSetFloatContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const handleSetFloatContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.floatContent = blockDef; }), blockDef.id); }; - var mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent, handleSetMainContent); - var floatContentNode = props.renderChildBlock(props, this.blockDef.floatContent, handleSetFloatContent); + const mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent, handleSetMainContent); + const floatContentNode = props.renderChildBlock(props, this.blockDef.floatContent, handleSetFloatContent); return React.createElement(FloatComponent, { float: floatContentNode, main: mainContentNode, direction: this.blockDef.direction, verticalAlign: this.blockDef.verticalAlign }); - }; - FloatBlock.prototype.renderInstance = function (props) { - var mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent); - var floatContentNode = props.renderChildBlock(props, this.blockDef.floatContent); + } + renderInstance(props) { + const mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent); + const floatContentNode = props.renderChildBlock(props, this.blockDef.floatContent); return React.createElement(FloatComponent, { float: floatContentNode, main: mainContentNode, direction: this.blockDef.direction, verticalAlign: this.blockDef.verticalAlign }); - }; - FloatBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Direction" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "direction" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ - { value: "left", label: React.createElement("i", { className: "fa fa-align-left" }) }, - { value: "right", label: React.createElement("i", { className: "fa fa-align-right" }) } - ] }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "direction" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ + { value: "left", label: React.createElement("i", { className: "fa fa-align-left" }) }, + { value: "right", label: React.createElement("i", { className: "fa fa-align-right" }) } + ] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Vertical Alignment" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "verticalAlign" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ - { value: "top", label: "Top" }, - { value: "middle", label: "Middle" }, - { value: "bottom", label: "Bottom" } - ] }); - })))); - }; - return FloatBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "verticalAlign" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [ + { value: "top", label: "Top" }, + { value: "middle", label: "Middle" }, + { value: "bottom", label: "Bottom" } + ] }))))); + } +} exports.FloatBlock = FloatBlock; -var FloatComponent = function (props) { +const FloatComponent = (props) => { return (React.createElement("table", { style: { width: "100%" } }, React.createElement("tbody", null, React.createElement("tr", { key: "float" }, diff --git a/lib/widgets/blocks/ganttChart/GanttChart.js b/lib/widgets/blocks/ganttChart/GanttChart.js index cc3f8235..3aca4178 100644 --- a/lib/widgets/blocks/ganttChart/GanttChart.js +++ b/lib/widgets/blocks/ganttChart/GanttChart.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,32 +23,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GanttChartBlock = void 0; -var React = __importStar(require("react")); -var blocks_1 = require("../../blocks"); -var LeafBlock_1 = __importDefault(require("../../LeafBlock")); -var GanttChart_1 = require("react-library/lib/GanttChart"); -var mwater_expressions_1 = require("mwater-expressions"); -var propertyEditors_1 = require("../../propertyEditors"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var localization_1 = require("../../localization"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var react_datepicker_1 = __importDefault(require("react-datepicker")); -var moment_1 = __importDefault(require("moment")); -var GanttChartInstance_1 = require("./GanttChartInstance"); -var GanttChartBlock = /** @class */ (function (_super) { - __extends(GanttChartBlock, _super); - function GanttChartBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - GanttChartBlock.prototype.validate = function (designCtx) { - var _this = this; +const React = __importStar(require("react")); +const blocks_1 = require("../../blocks"); +const LeafBlock_1 = __importDefault(require("../../LeafBlock")); +const GanttChart_1 = require("react-library/lib/GanttChart"); +const mwater_expressions_1 = require("mwater-expressions"); +const propertyEditors_1 = require("../../propertyEditors"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const localization_1 = require("../../localization"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const react_datepicker_1 = __importDefault(require("react-datepicker")); +const moment_1 = __importDefault(require("moment")); +const GanttChartInstance_1 = require("./GanttChartInstance"); +class GanttChartBlock extends LeafBlock_1.default { + validate(designCtx) { // Validate rowset - var rowsetCV = designCtx.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + const rowsetCV = designCtx.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return "Rowset required"; } - var exprValidator = new mwater_expressions_1.ExprValidator(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); - var error; + const exprValidator = new mwater_expressions_1.ExprValidator(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); + let error; // Validate filter error = exprValidator.validateExpr(this.blockDef.filter, { table: rowsetCV.table, types: ["boolean"] }); if (error) { @@ -95,7 +66,7 @@ var GanttChartBlock = /** @class */ (function (_super) { } // Validate rowOrderColumn if (this.blockDef.rowOrderColumn) { - var col = designCtx.schema.getColumn(rowsetCV.table, this.blockDef.rowOrderColumn); + const col = designCtx.schema.getColumn(rowsetCV.table, this.blockDef.rowOrderColumn); if (!col) { return "Order column not found"; } @@ -105,7 +76,7 @@ var GanttChartBlock = /** @class */ (function (_super) { } // Validate rowParentColumn if (this.blockDef.rowParentColumn) { - var col = designCtx.schema.getColumn(rowsetCV.table, this.blockDef.rowParentColumn); + const col = designCtx.schema.getColumn(rowsetCV.table, this.blockDef.rowParentColumn); if (!col) { return "Parent column not found"; } @@ -115,17 +86,17 @@ var GanttChartBlock = /** @class */ (function (_super) { } // Validate actions if (this.blockDef.rowClickAction) { - var action = designCtx.actionLibrary.createAction(this.blockDef.rowClickAction); + const action = designCtx.actionLibrary.createAction(this.blockDef.rowClickAction); // Create row context variable - var rowCV = this.createRowContextVar(rowsetCV); - error = action.validate(__assign(__assign({}, designCtx), { contextVars: designCtx.contextVars.concat(rowCV) })); + const rowCV = this.createRowContextVar(rowsetCV); + error = action.validate(Object.assign(Object.assign({}, designCtx), { contextVars: designCtx.contextVars.concat(rowCV) })); if (error) { return error; } } if (this.blockDef.addRowAction) { - var action = designCtx.actionLibrary.createAction(this.blockDef.addRowAction); - error = action.validate(__assign(__assign({}, designCtx), { contextVars: designCtx.contextVars.concat([ + const action = designCtx.actionLibrary.createAction(this.blockDef.addRowAction); + error = action.validate(Object.assign(Object.assign({}, designCtx), { contextVars: designCtx.contextVars.concat([ this.createAddRowOrderContextVar(rowsetCV), this.createAddRowParentContextVar(rowsetCV), ]) })); @@ -134,100 +105,98 @@ var GanttChartBlock = /** @class */ (function (_super) { } } return null; - }; + } /** Create the context variable used */ - GanttChartBlock.prototype.createRowContextVar = function (rowsetCV) { - return { id: this.blockDef.id + "_row", name: "GANTT Row of " + rowsetCV.name, type: "row", table: rowsetCV.table }; - }; + createRowContextVar(rowsetCV) { + return { id: this.blockDef.id + "_row", name: `GANTT Row of ${rowsetCV.name}`, type: "row", table: rowsetCV.table }; + } /** Create context variables that add row action receives */ - GanttChartBlock.prototype.createAddRowOrderContextVar = function (rowsetCV) { - return { id: this.blockDef.id + "_add_order", name: "Order of new GANTT row", type: "number" }; - }; + createAddRowOrderContextVar(rowsetCV) { + return { id: this.blockDef.id + "_add_order", name: `Order of new GANTT row`, type: "number" }; + } /** Create context variables that add row action receives */ - GanttChartBlock.prototype.createAddRowParentContextVar = function (rowsetCV) { - return { id: this.blockDef.id + "_add_parent", name: "Parent of new GANTT row", type: "id", table: rowsetCV.table }; - }; - GanttChartBlock.prototype.renderDesign = function (ctx) { - var barColor = this.blockDef.barColor || "#68cdee"; - var milestoneColor = this.blockDef.milestoneColor || "#68cdee"; + createAddRowParentContextVar(rowsetCV) { + return { id: this.blockDef.id + "_add_parent", name: `Parent of new GANTT row`, type: "id", table: rowsetCV.table }; + } + renderDesign(ctx) { + const barColor = this.blockDef.barColor || "#68cdee"; + const milestoneColor = this.blockDef.milestoneColor || "#68cdee"; return React.createElement(GanttChart_1.GanttChart, { rows: [ { color: barColor, level: 0, startDate: "2020-01-14", endDate: "2020-05-23", label: "Activity 1" }, { color: barColor, level: 1, startDate: "2020-02-14", endDate: "2020-06-23", label: "Activity 2" }, { color: milestoneColor, level: 2, startDate: "2020-04-12", endDate: null, label: "Activity 3" } ], startDate: "2020-01-01", endDate: "2020-07-01", T: ctx.T }); - }; - GanttChartBlock.prototype.renderInstance = function (ctx) { + } + renderInstance(ctx) { return React.createElement(GanttChartInstance_1.GanttChartInstance, { block: this, ctx: ctx }); - }; - GanttChartBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { // Get rowset context variable - var rowsetCV = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var rowCV = rowsetCV ? this.createRowContextVar(rowsetCV) : null; + const rowsetCV = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const rowCV = rowsetCV ? this.createRowContextVar(rowsetCV) : null; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }))), rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Label" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowLabelExpr" }, function (value, onChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["text"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowLabelExpr" }, (value, onChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["text"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })))) : null, rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Start Date of Rows" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowStartDateExpr" }, function (value, onChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["date", "datetime"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowStartDateExpr" }, (value, onChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["date", "datetime"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })))) : null, rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "End Date of Rows" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowEndDateExpr" }, function (value, onChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["date", "datetime"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowEndDateExpr" }, (value, onChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["date", "datetime"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })))) : null, rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filter" }, function (value, onChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["boolean"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filter" }, (value, onChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["boolean"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })))) : null, rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Order By Column" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowOrderColumn" }, function (value, onChange) { - var columnOptions = props.schema.getColumns(rowsetCV.table) - .filter(function (c) { return c.type == "date" || c.type == "datetime" || c.type == "number"; }) - .map(function (c) { return ({ value: c.id, label: localization_1.localize(c.name) }); }); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowOrderColumn" }, (value, onChange) => { + const columnOptions = props.schema.getColumns(rowsetCV.table) + .filter(c => c.type == "date" || c.type == "datetime" || c.type == "number") + .map(c => ({ value: c.id, label: localization_1.localize(c.name) })); return React.createElement(bootstrap_1.Select, { value: value, onChange: onChange, nullLabel: "Select column", options: columnOptions }); })) : null, rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Parent Column", hint: "Optional column to make hierarchical" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowParentColumn" }, function (value, onChange) { - var columnOptions = props.schema.getColumns(rowsetCV.table) - .filter(function (c) { return c.type == "id" && c.idTable == rowsetCV.table; }) - .map(function (c) { return ({ value: c.id, label: localization_1.localize(c.name) }); }); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowParentColumn" }, (value, onChange) => { + const columnOptions = props.schema.getColumns(rowsetCV.table) + .filter(c => c.type == "id" && c.idTable == rowsetCV.table) + .map(c => ({ value: c.id, label: localization_1.localize(c.name) })); return React.createElement(bootstrap_1.Select, { value: value, onChange: onChange, nullLabel: "None", options: columnOptions }); })) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Override Start Date" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "startDate" }, function (value, onChange) { return (React.createElement(react_datepicker_1.default, { selected: value ? moment_1.default(value, "YYYY-MM-DD") : null, onChange: function (momentDate) { onChange(momentDate.format("YYYY-MM-DD")); }, dateFormat: "ll", isClearable: true, className: "form-control" })); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "startDate" }, (value, onChange) => (React.createElement(react_datepicker_1.default, { selected: value ? moment_1.default(value, "YYYY-MM-DD") : null, onChange: (momentDate) => { onChange(momentDate.format("YYYY-MM-DD")); }, dateFormat: "ll", isClearable: true, className: "form-control" })))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Override End Date" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "endDate" }, function (value, onChange) { return (React.createElement(react_datepicker_1.default, { selected: value ? moment_1.default(value, "YYYY-MM-DD") : null, onChange: function (momentDate) { onChange(momentDate.format("YYYY-MM-DD")); }, dateFormat: "ll", isClearable: true, className: "form-control" })); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "endDate" }, (value, onChange) => (React.createElement(react_datepicker_1.default, { selected: value ? moment_1.default(value, "YYYY-MM-DD") : null, onChange: (momentDate) => { onChange(momentDate.format("YYYY-MM-DD")); }, dateFormat: "ll", isClearable: true, className: "form-control" })))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Bar color", hint: "CSS format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "barColor" }, function (value, onChange) { return (React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange, emptyNull: true, placeholder: "#68cdee" })); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "barColor" }, (value, onChange) => (React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange, emptyNull: true, placeholder: "#68cdee" })))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Milestone color", hint: "CSS format" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "milestoneColor" }, function (value, onChange) { return (React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange, emptyNull: true, placeholder: "#68cdee" })); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "autoNumberRows" }, function (value, onChange) { return (React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Autonumber Rows")); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "milestoneColor" }, (value, onChange) => (React.createElement(bootstrap_1.TextInput, { value: value, onChange: onChange, emptyNull: true, placeholder: "#68cdee" })))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "autoNumberRows" }, (value, onChange) => (React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Autonumber Rows"))), rowCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "When row clicked" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowClickAction" }, function (value, onChange) { return (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: __assign(__assign({}, props), { contextVars: props.contextVars.concat(rowCV) }) })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowClickAction" }, (value, onChange) => (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: Object.assign(Object.assign({}, props), { contextVars: props.contextVars.concat(rowCV) }) })))) : null, rowCV && rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "When row added" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "addRowAction" }, function (value, onChange) { return (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: __assign(__assign({}, props), { contextVars: props.contextVars.concat([_this.createAddRowOrderContextVar(rowsetCV), _this.createAddRowParentContextVar(rowsetCV)]) }) })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "addRowAction" }, (value, onChange) => (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: Object.assign(Object.assign({}, props), { contextVars: props.contextVars.concat([this.createAddRowOrderContextVar(rowsetCV), this.createAddRowParentContextVar(rowsetCV)]) }) })))) : null, this.blockDef.addRowAction ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Add row link text" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "addRowLabel" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "addRowLabel" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))) : null, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "allowRemove" }, function (value, onChange) { return (React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Allow removing rows")); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "allowRemove" }, (value, onChange) => (React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Allow removing rows"))), this.blockDef.allowRemove ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Remove confirm message" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "removeConfirmMessage" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "removeConfirmMessage" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))) : null)); - }; - return GanttChartBlock; -}(LeafBlock_1.default)); + } +} exports.GanttChartBlock = GanttChartBlock; diff --git a/lib/widgets/blocks/ganttChart/GanttChartInstance.js b/lib/widgets/blocks/ganttChart/GanttChartInstance.js index 1944c94e..972260e1 100644 --- a/lib/widgets/blocks/ganttChart/GanttChartInstance.js +++ b/lib/widgets/blocks/ganttChart/GanttChartInstance.js @@ -1,15 +1,4 @@ "use strict"; -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) { @@ -19,62 +8,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createChartRows = exports.GanttChartInstance = void 0; -var react_1 = require("react"); -var contexts_1 = require("../../../contexts"); -var Database_1 = require("../../../database/Database"); -var canonical_json_1 = __importDefault(require("canonical-json")); -var react_2 = __importDefault(require("react")); -var GanttChart_1 = require("react-library/lib/GanttChart"); -var moment_1 = __importDefault(require("moment")); -var immer_1 = require("immer"); -var localization_1 = require("../../localization"); +const react_1 = require("react"); +const contexts_1 = require("../../../contexts"); +const Database_1 = require("../../../database/Database"); +const canonical_json_1 = __importDefault(require("canonical-json")); +const react_2 = __importDefault(require("react")); +const GanttChart_1 = require("react-library/lib/GanttChart"); +const moment_1 = __importDefault(require("moment")); +const immer_1 = require("immer"); +const localization_1 = require("../../localization"); function GanttChartInstance(props) { - var _this = this; - var block = props.block, ctx = props.ctx; - var blockDef = block.blockDef; - var rowsetCV = ctx.contextVars.find(function (cv) { return cv.id == blockDef.rowsetContextVarId; }); - var rowCV = block.createRowContextVar(rowsetCV); + const { block, ctx } = props; + const blockDef = block.blockDef; + const rowsetCV = ctx.contextVars.find(cv => cv.id == blockDef.rowsetContextVarId); + const rowCV = block.createRowContextVar(rowsetCV); /** Incremented when database changed */ - var dbChanged = Database_1.useDatabaseChangeListener(ctx.database); - var table = rowsetCV.table; + const dbChanged = Database_1.useDatabaseChangeListener(ctx.database); + const table = rowsetCV.table; // Determine type of order column - var orderType = ctx.schema.getColumn(table, blockDef.rowOrderColumn).type; + const orderType = ctx.schema.getColumn(table, blockDef.rowOrderColumn).type; /** Creates a query */ - var createQuery = function () { + const createQuery = () => { // Create query - var query = { + const query = { select: { id: { type: "id", table: table }, label: blockDef.rowLabelExpr, @@ -89,21 +50,14 @@ function GanttChartInstance(props) { return query; }; // Query data - var performQuery = function () { return __awaiter(_this, void 0, void 0, function () { - var rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4 /*yield*/, ctx.database.query(createQuery(), ctx.contextVars, contexts_1.getFilteredContextVarValues(ctx))]; - case 1: - rows = _a.sent(); - setRows(rows); - return [2 /*return*/]; - } - }); - }); }; - var _a = react_1.useState(), rows = _a[0], setRows = _a[1]; + const performQuery = () => __awaiter(this, void 0, void 0, function* () { + // Perform actual query + const rows = yield ctx.database.query(createQuery(), ctx.contextVars, contexts_1.getFilteredContextVarValues(ctx)); + setRows(rows); + }); + const [rows, setRows] = react_1.useState(); // Perform query when database changed, or if context var values change - react_1.useEffect(function () { + react_1.useEffect(() => { performQuery(); }, [dbChanged, canonical_json_1.default(contexts_1.getFilteredContextVarValues(ctx))]); // Show spinner if not loaded @@ -118,130 +72,114 @@ function GanttChartInstance(props) { : blockDef.barColor || "#68cdee"; } // Create chart rows - var chartRows = createChartRows({ queryRows: rows, getColor: getRowColor, prefixNumber: blockDef.autoNumberRows || false }); + const chartRows = createChartRows({ queryRows: rows, getColor: getRowColor, prefixNumber: blockDef.autoNumberRows || false }); /** Create instance ctx for a clicked row */ function createRowInstanceCtx(row) { - var _a; - var innerContextVars = ctx.contextVars.concat(rowCV); + const innerContextVars = ctx.contextVars.concat(rowCV); // Row context variable value - var cvvalue = row.id; - return __assign(__assign({}, ctx), { contextVars: innerContextVars, contextVarValues: __assign(__assign({}, ctx.contextVarValues), (_a = {}, _a[rowCV.id] = cvvalue, _a)) }); + const cvvalue = row.id; + return Object.assign(Object.assign({}, ctx), { contextVars: innerContextVars, contextVarValues: Object.assign(Object.assign({}, ctx.contextVarValues), { [rowCV.id]: cvvalue }) }); } /** Move a row logically down */ - var handleMoveRowDown = function (index) { - var chartRow = chartRows[index]; - var _loop_1 = function (i) { + const handleMoveRowDown = (index) => { + const chartRow = chartRows[index]; + // Find next sibling + for (let i = index + 1; i < chartRows.length; i++) { // If up a level, ignore if (chartRows[i].level < chartRow.level) { - return { value: void 0 }; + return; } // If same level, use this one if (chartRows[i].level == chartRow.level) { // Swap orders - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); - var otherRow = rows.find(function (r) { return r.id == chartRows[i].id; }); - var txn = ctx.database.transaction(); + const myRow = rows.find(r => r.id == chartRow.id); + const otherRow = rows.find(r => r.id == chartRows[i].id); + const txn = ctx.database.transaction(); txn.updateRow(table, myRow.id, { order: otherRow.order }); txn.updateRow(table, otherRow.id, { order: myRow.order }); txn.commit(); - return { value: void 0 }; + return; } - }; - // Find next sibling - for (var i = index + 1; i < chartRows.length; i++) { - var state_1 = _loop_1(i); - if (typeof state_1 === "object") - return state_1.value; } }; - var handleMoveRowUp = function (index) { - var chartRow = chartRows[index]; - var _loop_2 = function (i) { + const handleMoveRowUp = (index) => { + const chartRow = chartRows[index]; + // Find previous sibling + for (let i = index - 1; i >= 0; i--) { // If up a level, ignore if (chartRows[i].level < chartRow.level) { - return { value: void 0 }; + return; } // If same level, use this one if (chartRows[i].level == chartRow.level) { // Swap orders - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); - var otherRow = rows.find(function (r) { return r.id == chartRows[i].id; }); - var txn = ctx.database.transaction(); + const myRow = rows.find(r => r.id == chartRow.id); + const otherRow = rows.find(r => r.id == chartRows[i].id); + const txn = ctx.database.transaction(); txn.updateRow(table, myRow.id, { order: otherRow.order }); txn.updateRow(table, otherRow.id, { order: myRow.order }); txn.commit(); - return { value: void 0 }; + return; } - }; - // Find previous sibling - for (var i = index - 1; i >= 0; i--) { - var state_2 = _loop_2(i); - if (typeof state_2 === "object") - return state_2.value; } }; - var handleMoveRowLeft = function (index) { - var chartRow = chartRows[index]; - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); + const handleMoveRowLeft = (index) => { + const chartRow = chartRows[index]; + const myRow = rows.find(r => r.id == chartRow.id); // Find parent - var parentRow = rows.find(function (r) { return r.id == myRow.parent; }); - var txn = ctx.database.transaction(); + const parentRow = rows.find(r => r.id == myRow.parent); + const txn = ctx.database.transaction(); // Set own parent to parent's parent and and set order to parent + 1 txn.updateRow(table, myRow.id, { parent: parentRow.parent, order: parentRow.order + 1 }); // Decrement order of all siblings after self - for (var _i = 0, rows_1 = rows; _i < rows_1.length; _i++) { - var r = rows_1[_i]; + for (const r of rows) { if (r.parent == myRow.parent && r.order > myRow.order) { txn.updateRow(table, r.id, { order: r.order - 1 }); } } // Increment order of all siblings after parent - for (var _a = 0, rows_2 = rows; _a < rows_2.length; _a++) { - var r = rows_2[_a]; + for (const r of rows) { if (r.parent == parentRow.parent && r.order > parentRow.order) { txn.updateRow(table, r.id, { order: r.order + 1 }); } } txn.commit(); }; - var handleMoveRowRight = function (index) { - var chartRow = chartRows[index]; - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); + const handleMoveRowRight = (index) => { + const chartRow = chartRows[index]; + const myRow = rows.find(r => r.id == chartRow.id); // Find new parent (previous row) - var parentRow = rows.find(function (r) { return r.id == chartRows[index - 1].id; }); - var txn = ctx.database.transaction(); + const parentRow = rows.find(r => r.id == chartRows[index - 1].id); + const txn = ctx.database.transaction(); // Set own parent to previous row's parent and set order to 0 txn.updateRow(table, myRow.id, { parent: parentRow.id, order: 0 }); // Decrement order of all siblings after parent - for (var _i = 0, rows_3 = rows; _i < rows_3.length; _i++) { - var r = rows_3[_i]; + for (const r of rows) { if (r.parent == parentRow.parent && r.order > parentRow.order) { txn.updateRow(table, r.id, { order: r.order - 1 }); } } txn.commit(); }; - var handleInsertChildRow = function (index) { - var chartRow = chartRows[index]; - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); + const handleInsertChildRow = (index) => { + const chartRow = chartRows[index]; + const myRow = rows.find(r => r.id == chartRow.id); // Determine max order of child rows - var order = 0; - for (var _i = 0, rows_4 = rows; _i < rows_4.length; _i++) { - var r = rows_4[_i]; + let order = 0; + for (const r of rows) { if (r.parent == myRow.id && r.order >= order) { order = r.order + 1; } } handleAddRow(myRow.id, order); }; - var handleInsertRowAbove = function (index) { - var chartRow = chartRows[index]; - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); + const handleInsertRowAbove = (index) => { + const chartRow = chartRows[index]; + const myRow = rows.find(r => r.id == chartRow.id); // Make room for new row - var txn = ctx.database.transaction(); + const txn = ctx.database.transaction(); // Increment order of all siblings including and after self - for (var _i = 0, rows_5 = rows; _i < rows_5.length; _i++) { - var r = rows_5[_i]; + for (const r of rows) { if (r.parent == myRow.parent && r.order >= myRow.order) { txn.updateRow(table, r.id, { order: r.order + 1 }); } @@ -249,14 +187,13 @@ function GanttChartInstance(props) { txn.commit(); handleAddRow(myRow.parent, myRow.order); }; - var handleInsertRowBelow = function (index) { - var chartRow = chartRows[index]; - var myRow = rows.find(function (r) { return r.id == chartRow.id; }); + const handleInsertRowBelow = (index) => { + const chartRow = chartRows[index]; + const myRow = rows.find(r => r.id == chartRow.id); // Make room for new row - var txn = ctx.database.transaction(); + const txn = ctx.database.transaction(); // Increment order of all siblings after self - for (var _i = 0, rows_6 = rows; _i < rows_6.length; _i++) { - var r = rows_6[_i]; + for (const r of rows) { if (r.parent == myRow.parent && r.order > myRow.order) { txn.updateRow(table, r.id, { order: r.order + 1 }); } @@ -264,18 +201,18 @@ function GanttChartInstance(props) { txn.commit(); handleAddRow(myRow.parent, myRow.order + 1); }; - var handleRowClick = function (chartRowIndex) { + const handleRowClick = (chartRowIndex) => { // Lookup row - var row = rows.find(function (r) { return r.id == chartRows[chartRowIndex].id; }); + const row = rows.find(r => r.id == chartRows[chartRowIndex].id); // Create context with variables - var rowClickAction = ctx.actionLibrary.createAction(blockDef.rowClickAction); + const rowClickAction = ctx.actionLibrary.createAction(blockDef.rowClickAction); rowClickAction.performAction(createRowInstanceCtx(row)); }; - var handleAddRow = function (parent, order) { + const handleAddRow = (parent, order) => { // Create context with additional variables - var innerCtx = immer_1.produce(ctx, function (draft) { - var rowOrderContextVar = block.createAddRowOrderContextVar(rowsetCV); - var rowParentContextVar = block.createAddRowParentContextVar(rowsetCV); + const innerCtx = immer_1.produce(ctx, draft => { + const rowOrderContextVar = block.createAddRowOrderContextVar(rowsetCV); + const rowParentContextVar = block.createAddRowParentContextVar(rowsetCV); draft.contextVars.push(rowOrderContextVar); draft.contextVars.push(rowParentContextVar); draft.contextVarValues[rowOrderContextVar.id] = { type: "literal", valueType: "number", value: order }; @@ -283,7 +220,7 @@ function GanttChartInstance(props) { }); ctx.actionLibrary.createAction(blockDef.addRowAction).performAction(innerCtx); }; - var handleRemoveRow = function (chartRowIndex) { + const handleRemoveRow = (chartRowIndex) => { // Confirm if confirm message if (blockDef.removeConfirmMessage) { if (!confirm(localization_1.localize(blockDef.removeConfirmMessage, ctx.locale))) { @@ -291,13 +228,12 @@ function GanttChartInstance(props) { } } // Delete recursively - var txn = ctx.database.transaction(); + const txn = ctx.database.transaction(); function deleteDescendants(rowId) { // Lookup row - var row = rows.find(function (r) { return r.id == rowId; }); + const row = rows.find(r => r.id == rowId); // Delete any children - for (var _i = 0, _a = rows; _i < _a.length; _i++) { - var child = _a[_i]; + for (const child of rows) { if (child.parent == row.id) { deleteDescendants(child.id); } @@ -309,12 +245,11 @@ function GanttChartInstance(props) { }; /** Append row to bottom of chart */ function handleAppendRow() { - var order = null; + let order = null; // Add order as next number of ordered column if type is number if (orderType == "number") { order = 0; - for (var _i = 0, _a = rows; _i < _a.length; _i++) { - var row = _a[_i]; + for (const row of rows) { if (!row.parent && row.order >= order) { order = row.order + 1; } @@ -322,15 +257,15 @@ function GanttChartInstance(props) { } handleAddRow(null, order); } - var startDate; - var endDate; + let startDate; + let endDate; // Use override if present if (blockDef.startDate) { startDate = blockDef.startDate; } else { // Go earliest with a buffer - var minStartDate = rows.reduce(function (acc, row) { return !acc || (row.startDate && row.startDate < acc) ? row.startDate : acc; }, null); + const minStartDate = rows.reduce((acc, row) => !acc || (row.startDate && row.startDate < acc) ? row.startDate : acc, null); if (minStartDate) { startDate = moment_1.default(minStartDate, "YYYY-MM-DD").subtract(1, "month").format("YYYY-MM-DD"); } @@ -345,7 +280,7 @@ function GanttChartInstance(props) { } else { // Go earliest with a buffer - var maxEndDate = rows.reduce(function (acc, row) { return !acc || (row.endDate && row.endDate > acc) ? row.endDate : acc; }, null); + const maxEndDate = rows.reduce((acc, row) => !acc || (row.endDate && row.endDate > acc) ? row.endDate : acc, null); if (maxEndDate) { endDate = moment_1.default(maxEndDate, "YYYY-MM-DD").add(1, "month").format("YYYY-MM-DD"); } @@ -354,8 +289,8 @@ function GanttChartInstance(props) { endDate = moment_1.default().endOf("year").format("YYYY-MM-DD"); } } - var isOrdered = blockDef.rowOrderColumn != null; - var isHierarchical = blockDef.rowParentColumn != null; + const isOrdered = blockDef.rowOrderColumn != null; + const isHierarchical = blockDef.rowParentColumn != null; return react_2.default.createElement(GanttChart_1.GanttChart, { rows: chartRows, startDate: startDate, endDate: endDate, onMoveRowDown: isOrdered ? handleMoveRowDown : undefined, onMoveRowUp: isOrdered ? handleMoveRowUp : undefined, onMoveRowLeft: isOrdered && isHierarchical ? handleMoveRowLeft : undefined, onMoveRowRight: isOrdered && isHierarchical ? handleMoveRowRight : undefined, onInsertChildRow: isOrdered && isHierarchical ? handleInsertChildRow : undefined, onInsertRowAbove: isOrdered && isHierarchical ? handleInsertRowAbove : undefined, onInsertRowBelow: isOrdered && isHierarchical ? handleInsertRowBelow : undefined, onRowClick: blockDef.rowClickAction ? handleRowClick : undefined, onAddRow: blockDef.addRowAction ? handleAppendRow : undefined, addRowLabel: blockDef.addRowLabel ? [react_2.default.createElement("i", { className: "fa fa-plus" }), " ", localization_1.localize(blockDef.addRowLabel, ctx.locale)] : undefined, onRemoveRow: blockDef.allowRemove ? handleRemoveRow : undefined, T: ctx.T }); } exports.GanttChartInstance = GanttChartInstance; @@ -366,23 +301,23 @@ exports.GanttChartInstance = GanttChartInstance; * prefixNumber adds 1.1, 1.2.3, etc before label */ function createChartRows(options) { - var chartRows = []; + const chartRows = []; /** Add all rows, sorted, that have this as a parent */ function addRows(parent, level, prefix) { - var childRows = options.queryRows.filter(function (r) { return r.parent == parent; }); + const childRows = options.queryRows.filter(r => r.parent == parent); // Sort by order - childRows.sort(function (a, b) { return a.order > b.order ? 1 : -1; }); + childRows.sort((a, b) => a.order > b.order ? 1 : -1); // Add each row, then add its children - childRows.forEach(function (row, index) { + childRows.forEach((row, index) => { chartRows.push({ id: row.id, color: options.getColor(row), level: level, startDate: row.startDate, endDate: row.endDate, - label: options.prefixNumber ? "" + prefix + (index + 1) + ". " + row.label || "" : row.label || "" + label: options.prefixNumber ? `${prefix}${index + 1}. ${row.label}` || "" : row.label || "" }); - addRows(row.id, level + 1, "" + prefix + (index + 1) + "."); + addRows(row.id, level + 1, `${prefix}${index + 1}.`); }); } addRows(null, 0, ""); diff --git a/lib/widgets/blocks/ganttChart/GanttChartInstance.test.js b/lib/widgets/blocks/ganttChart/GanttChartInstance.test.js index 9db98666..54327d76 100644 --- a/lib/widgets/blocks/ganttChart/GanttChartInstance.test.js +++ b/lib/widgets/blocks/ganttChart/GanttChartInstance.test.js @@ -1,19 +1,19 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var GanttChartInstance_1 = require("./GanttChartInstance"); -test("sorts simple list", function () { +const GanttChartInstance_1 = require("./GanttChartInstance"); +test("sorts simple list", () => { // Simple rows - var queryRows = [ + const queryRows = [ { id: "1", order: 1, label: "A" }, { id: "3", order: 3, label: "C" }, { id: "2", order: 2, label: "B" }, ]; - var chartRows = GanttChartInstance_1.createChartRows({ queryRows: queryRows, getColor: function () { return "red"; }, prefixNumber: false }); - expect(chartRows.map(function (r) { return r.id; })).toEqual(["1", "2", "3"]); + const chartRows = GanttChartInstance_1.createChartRows({ queryRows, getColor: () => "red", prefixNumber: false }); + expect(chartRows.map(r => r.id)).toEqual(["1", "2", "3"]); }); -test("sorts nested list", function () { +test("sorts nested list", () => { // Simple rows - var queryRows = [ + const queryRows = [ { id: "1ba", order: 1, parent: "1b", label: "ABA" }, { id: "1", order: 1, label: "A" }, { id: "3", order: 3, label: "C" }, @@ -21,10 +21,10 @@ test("sorts nested list", function () { { id: "1b", order: 2, parent: "1", label: "AB" }, { id: "1a", order: 1, parent: "1", label: "AA" } ]; - var chartRows = GanttChartInstance_1.createChartRows({ queryRows: queryRows, getColor: function () { return "red"; }, prefixNumber: true }); - expect(chartRows.map(function (r) { return r.id; })).toEqual(["1", "1a", "1b", "1ba", "2", "3"]); - expect(chartRows.map(function (r) { return r.level; })).toEqual([0, 1, 1, 2, 0, 0]); - expect(chartRows.map(function (r) { return r.label; })).toEqual([ + const chartRows = GanttChartInstance_1.createChartRows({ queryRows, getColor: () => "red", prefixNumber: true }); + expect(chartRows.map(r => r.id)).toEqual(["1", "1a", "1b", "1ba", "2", "3"]); + expect(chartRows.map(r => r.level)).toEqual([0, 1, 1, 2, 0, 0]); + expect(chartRows.map(r => r.label)).toEqual([ "1. A", "1.1. AA", "1.2. AB", diff --git a/lib/widgets/blocks/header.js b/lib/widgets/blocks/header.js index 19c2900d..4e066d42 100644 --- a/lib/widgets/blocks/header.js +++ b/lib/widgets/blocks/header.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,37 +23,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HeaderBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var HeaderBlock = /** @class */ (function (_super) { - __extends(HeaderBlock, _super); - function HeaderBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - HeaderBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +class HeaderBlock extends blocks_1.Block { + getChildren(contextVars) { return this.blockDef.child ? [{ blockDef: this.blockDef.child, contextVars: contextVars }] : []; - }; - HeaderBlock.prototype.validate = function () { return null; }; - HeaderBlock.prototype.processChildren = function (action) { - var child = action(this.blockDef.child); - return immer_1.default(this.blockDef, function (draft) { + } + validate() { return null; } + processChildren(action) { + const child = action(this.blockDef.child); + return immer_1.default(this.blockDef, draft => { draft.child = child; }); - }; - HeaderBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleAdd = function (addedBlockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleAdd = (addedBlockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.child = addedBlockDef; return b; }), addedBlockDef.id); }; return (React.createElement("div", { className: "header-block" }, props.renderChildBlock(props, this.blockDef.child, handleAdd))); - }; - HeaderBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return (React.createElement("div", { className: "header-block" }, props.renderChildBlock(props, this.blockDef.child))); - }; - return HeaderBlock; -}(blocks_1.Block)); + } +} exports.HeaderBlock = HeaderBlock; diff --git a/lib/widgets/blocks/horizontal.js b/lib/widgets/blocks/horizontal.js index 7ad8bcb7..d6f6ab0e 100644 --- a/lib/widgets/blocks/horizontal.js +++ b/lib/widgets/blocks/horizontal.js @@ -1,44 +1,23 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HorizontalBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var immer_1 = __importDefault(require("immer")); -var react_1 = __importDefault(require("react")); -var blocks_1 = require("../blocks"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var propertyEditors_1 = require("../propertyEditors"); -var AutoSizeComponent_1 = __importDefault(require("react-library/lib/AutoSizeComponent")); -var HorizontalBlock = /** @class */ (function (_super) { - __extends(HorizontalBlock, _super); - function HorizontalBlock() { - return _super !== null && _super.apply(this, arguments) || this; +const lodash_1 = __importDefault(require("lodash")); +const immer_1 = __importDefault(require("immer")); +const react_1 = __importDefault(require("react")); +const blocks_1 = require("../blocks"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const propertyEditors_1 = require("../propertyEditors"); +const AutoSizeComponent_1 = __importDefault(require("react-library/lib/AutoSizeComponent")); +class HorizontalBlock extends blocks_1.Block { + get id() { return this.blockDef.id; } + getChildren(contextVars) { + return this.blockDef.items.map(bd => ({ blockDef: bd, contextVars: contextVars })); } - Object.defineProperty(HorizontalBlock.prototype, "id", { - get: function () { return this.blockDef.id; }, - enumerable: false, - configurable: true - }); - HorizontalBlock.prototype.getChildren = function (contextVars) { - return this.blockDef.items.map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; - HorizontalBlock.prototype.validate = function () { return null; }; - HorizontalBlock.prototype.canonicalize = function () { + validate() { return null; } + canonicalize() { // Remove if zero items if (this.blockDef.items.length === 0) { return null; @@ -48,43 +27,40 @@ var HorizontalBlock = /** @class */ (function (_super) { return this.blockDef.items[0]; } // Flatten out nested horizontal blocks - if (this.blockDef.items.some(function (bd) { return bd.type == "horizontal"; })) { + if (this.blockDef.items.some(bd => bd.type == "horizontal")) { // Create list of items - var newItems_1 = []; - for (var _i = 0, _a = this.blockDef.items; _i < _a.length; _i++) { - var item = _a[_i]; + let newItems = []; + for (const item of this.blockDef.items) { if (item.type == "horizontal") { - newItems_1 = newItems_1.concat(item.items); + newItems = newItems.concat(item.items); } else { - newItems_1.push(item); + newItems.push(item); } } - return immer_1.default(this.blockDef, function (draft) { - draft.items = newItems_1; + return immer_1.default(this.blockDef, (draft) => { + draft.items = newItems; }); } return this.blockDef; - }; - HorizontalBlock.prototype.processChildren = function (action) { - var newItems = []; - for (var _i = 0, _a = this.blockDef.items; _i < _a.length; _i++) { - var item = _a[_i]; - var newItem = action(item); + } + processChildren(action) { + const newItems = []; + for (const item of this.blockDef.items) { + const newItem = action(item); if (newItem) { newItems.push(newItem); } } // Apply action to all children, discarding null ones - return immer_1.default(this.blockDef, function (draft) { draft.items = newItems; }); - }; - HorizontalBlock.prototype.renderBlock = function (children, width) { - var _this = this; - var align = this.blockDef.align || "justify"; - var columnWidths = this.blockDef.columnWidths || []; - var responsiveBreaks = this.blockDef.responsiveBreaks || []; + return immer_1.default(this.blockDef, draft => { draft.items = newItems; }); + } + renderBlock(children, width) { + const align = this.blockDef.align || "justify"; + const columnWidths = this.blockDef.columnWidths || []; + const responsiveBreaks = this.blockDef.responsiveBreaks || []; // Determine alignment (vertical) - var alignItems = "start"; + let alignItems = "start"; if (this.blockDef.verticalAlign == "middle") { alignItems = "center"; } @@ -92,23 +68,23 @@ var HorizontalBlock = /** @class */ (function (_super) { alignItems = "end"; } // Break items into rows based on responsive breaks - var rows = []; - var rowItems = []; - var rowColumns = []; - var addRow = function () { + const rows = []; + let rowItems = []; + let rowColumns = []; + const addRow = () => { // Create CSS grid with style - var containerStyle = { + const containerStyle = { display: "grid", gridGap: 5, gridTemplateColumns: rowColumns.join(" "), - justifyContent: _this.blockDef.align, - alignItems: alignItems + justifyContent: this.blockDef.align, + alignItems }; - rows.push(react_1.default.createElement("div", { style: containerStyle }, rowItems.map(function (child, index) { return react_1.default.createElement(react_1.default.Fragment, { key: index }, child); }))); + rows.push(react_1.default.createElement("div", { style: containerStyle }, rowItems.map((child, index) => react_1.default.createElement(react_1.default.Fragment, { key: index }, child)))); rowItems = []; rowColumns = []; }; - for (var index = 0; index < children.length; index++) { + for (let index = 0; index < children.length; index++) { // Determine if break before if (index > 0 && responsiveBreaks[index - 1] && responsiveBreaks[index - 1] > width) { // Add break @@ -120,55 +96,43 @@ var HorizontalBlock = /** @class */ (function (_super) { } addRow(); return react_1.default.createElement("div", null, rows); - }; - HorizontalBlock.prototype.renderDesign = function (props) { - var _this = this; - return (react_1.default.createElement(AutoSizeComponent_1.default, { injectWidth: true }, function (size) { return (react_1.default.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, _this.renderBlock(_this.blockDef.items.map(function (childBlock) { return props.renderChildBlock(props, childBlock); }), size.width))); })); - }; - HorizontalBlock.prototype.renderInstance = function (props) { - var _this = this; - return (react_1.default.createElement(AutoSizeComponent_1.default, { injectWidth: true }, function (size) { return _this.renderBlock(_this.blockDef.items.map(function (childBlockDef) { return props.renderChildBlock(props, childBlockDef); }), size.width); })); - }; - HorizontalBlock.prototype.renderEditor = function (props) { - var _this = this; - var align = this.blockDef.align || "justify"; + } + renderDesign(props) { + return (react_1.default.createElement(AutoSizeComponent_1.default, { injectWidth: true }, size => (react_1.default.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, this.renderBlock(this.blockDef.items.map(childBlock => props.renderChildBlock(props, childBlock)), size.width))))); + } + renderInstance(props) { + return (react_1.default.createElement(AutoSizeComponent_1.default, { injectWidth: true }, size => this.renderBlock(this.blockDef.items.map(childBlockDef => props.renderChildBlock(props, childBlockDef)), size.width))); + } + renderEditor(props) { + const align = this.blockDef.align || "justify"; return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Horizontal Alignment" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "align" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value || "justify", onChange: onChange, options: [ - { value: "justify", label: react_1.default.createElement("i", { className: "fa fa-align-justify" }) }, - { value: "left", label: react_1.default.createElement("i", { className: "fa fa-align-left" }) }, - { value: "center", label: react_1.default.createElement("i", { className: "fa fa-align-center" }) }, - { value: "right", label: react_1.default.createElement("i", { className: "fa fa-align-right" }) } - ] }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "align" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value || "justify", onChange: onChange, options: [ + { value: "justify", label: react_1.default.createElement("i", { className: "fa fa-align-justify" }) }, + { value: "left", label: react_1.default.createElement("i", { className: "fa fa-align-left" }) }, + { value: "center", label: react_1.default.createElement("i", { className: "fa fa-align-center" }) }, + { value: "right", label: react_1.default.createElement("i", { className: "fa fa-align-right" }) } + ] }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Vertical Alignment" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "verticalAlign" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value || "top", onChange: onChange, options: [ - { value: "top", label: "Top" }, - { value: "middle", label: "Middle" }, - { value: "bottom", label: "Bottom" } - ] }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "verticalAlign" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value || "top", onChange: onChange, options: [ + { value: "top", label: "Top" }, + { value: "middle", label: "Middle" }, + { value: "bottom", label: "Bottom" } + ] }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Column Widths" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columnWidths" }, function (value, onChange) { - return react_1.default.createElement(ColumnWidthsEditor, { numColumns: _this.blockDef.items.length, defaultWidth: align == "justify" ? "1fr" : "auto", columnWidths: value || [], onChange: onChange }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columnWidths" }, (value, onChange) => react_1.default.createElement(ColumnWidthsEditor, { numColumns: this.blockDef.items.length, defaultWidth: align == "justify" ? "1fr" : "auto", columnWidths: value || [], onChange: onChange }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Responsive Breaks" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "responsiveBreaks" }, function (value, onChange) { - return react_1.default.createElement(ResponsiveBreaksEditor, { numBreaks: _this.blockDef.items.length - 1, breaks: value || [], onChange: onChange }); - })))); - }; - HorizontalBlock.prototype.getLabel = function () { return ""; }; - return HorizontalBlock; -}(blocks_1.Block)); + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "responsiveBreaks" }, (value, onChange) => react_1.default.createElement(ResponsiveBreaksEditor, { numBreaks: this.blockDef.items.length - 1, breaks: value || [], onChange: onChange }))))); + } + getLabel() { return ""; } +} exports.HorizontalBlock = HorizontalBlock; -var ColumnWidthsEditor = function (props) { - return react_1.default.createElement("ul", { className: "list-group" }, lodash_1.default.range(props.numColumns).map(function (colIndex) { +const ColumnWidthsEditor = (props) => { + return react_1.default.createElement("ul", { className: "list-group" }, lodash_1.default.range(props.numColumns).map((colIndex) => { return react_1.default.createElement("li", { className: "list-group-item", key: colIndex }, - react_1.default.createElement(ColumnWidthEditor, { label: "#" + (colIndex + 1) + ":", columnWidth: props.columnWidths[colIndex] || props.defaultWidth, onChange: function (width) { return props.onChange(immer_1.default(props.columnWidths, function (draft) { + react_1.default.createElement(ColumnWidthEditor, { label: `#${colIndex + 1}:`, columnWidth: props.columnWidths[colIndex] || props.defaultWidth, onChange: width => props.onChange(immer_1.default(props.columnWidths, draft => { draft[colIndex] = width; - })); } })); + })) })); })); }; function ColumnWidthEditor(props) { @@ -197,12 +161,12 @@ function ColumnWidthEditor(props) { { value: "minmax(min-content, 800px)", label: "800px" } ] })); } -var ResponsiveBreaksEditor = function (props) { - return react_1.default.createElement("ul", { className: "list-group" }, lodash_1.default.range(props.numBreaks).map(function (breakIndex) { +const ResponsiveBreaksEditor = (props) => { + return react_1.default.createElement("ul", { className: "list-group" }, lodash_1.default.range(props.numBreaks).map((breakIndex) => { return react_1.default.createElement("li", { className: "list-group-item", key: breakIndex }, - react_1.default.createElement(ResponsiveBreakEditor, { label: breakIndex + 1 + " / " + (breakIndex + 2) + ":", width: props.breaks[breakIndex] || null, onChange: function (width) { return props.onChange(immer_1.default(props.breaks, function (draft) { + react_1.default.createElement(ResponsiveBreakEditor, { label: `${breakIndex + 1} / ${breakIndex + 2}:`, width: props.breaks[breakIndex] || null, onChange: width => props.onChange(immer_1.default(props.breaks, draft => { draft[breakIndex] = width; - })); } })); + })) })); })); }; function ResponsiveBreakEditor(props) { diff --git a/lib/widgets/blocks/horizontal.test.js b/lib/widgets/blocks/horizontal.test.js index 16b9dcde..fed672d3 100644 --- a/lib/widgets/blocks/horizontal.test.js +++ b/lib/widgets/blocks/horizontal.test.js @@ -1,20 +1,20 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var horizontal_1 = require("./horizontal"); -it("canonicalizes single item", function () { - var hbd = { +const horizontal_1 = require("./horizontal"); +it("canonicalizes single item", () => { + const hbd = { type: "horizontal", id: "a", items: [ { id: "b", type: "text", text: null } ] }; - var hbd2 = new horizontal_1.HorizontalBlock(hbd).canonicalize(); + const hbd2 = new horizontal_1.HorizontalBlock(hbd).canonicalize(); // Should collapse expect(hbd2).toEqual(hbd.items[0]); }); -it("canonicalizes nested items", function () { - var hbd = { +it("canonicalizes nested items", () => { + const hbd = { type: "horizontal", id: "a", items: [ @@ -25,7 +25,7 @@ it("canonicalizes nested items", function () { { id: "d", type: "text", text: null } ] }; - var hbd2 = new horizontal_1.HorizontalBlock(hbd).canonicalize(); + const hbd2 = new horizontal_1.HorizontalBlock(hbd).canonicalize(); // Should collapse expect(hbd2).toEqual({ type: "horizontal", @@ -37,8 +37,8 @@ it("canonicalizes nested items", function () { ] }); }); -it("canonicalizes good item as self", function () { - var hbd = { +it("canonicalizes good item as self", () => { + const hbd = { type: "horizontal", id: "a", items: [ @@ -46,7 +46,7 @@ it("canonicalizes good item as self", function () { { id: "c", type: "text", text: null } ] }; - var hbd2 = new horizontal_1.HorizontalBlock(hbd).canonicalize(); + const hbd2 = new horizontal_1.HorizontalBlock(hbd).canonicalize(); // Should collapse expect(hbd).toBe(hbd2); }); diff --git a/lib/widgets/blocks/image.js b/lib/widgets/blocks/image.js index 445846b0..999f062b 100644 --- a/lib/widgets/blocks/image.js +++ b/lib/widgets/blocks/image.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,33 +23,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ImageBlock = void 0; -var React = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const immer_1 = __importDefault(require("immer")); /** Simple static image block */ -var ImageBlock = /** @class */ (function (_super) { - __extends(ImageBlock, _super); - function ImageBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ImageBlock.prototype.validate = function (designCtx) { +class ImageBlock extends LeafBlock_1.default { + validate(designCtx) { if (!this.blockDef.url) { return "URL required"; } - var error; + let error; // Validate action if (this.blockDef.clickActionDef) { - var action = designCtx.actionLibrary.createAction(this.blockDef.clickActionDef); + const action = designCtx.actionLibrary.createAction(this.blockDef.clickActionDef); error = action.validate(designCtx); if (error) { return error; } } return null; - }; - ImageBlock.prototype.renderImage = function (locale, handleClick) { + } + renderImage(locale, handleClick) { if (!this.blockDef.url) { return React.createElement("i", { className: "fa fa-picture-o" }); } @@ -73,9 +56,9 @@ var ImageBlock = /** @class */ (function (_super) { else { url = this.blockDef.url; } - var divStyle = {}; - var imageStyle = {}; - var sizeMode = this.blockDef.sizeMode || "normal"; + const divStyle = {}; + const imageStyle = {}; + const sizeMode = this.blockDef.sizeMode || "normal"; if (sizeMode == "normal") { imageStyle.maxWidth = "100%"; } @@ -89,24 +72,22 @@ var ImageBlock = /** @class */ (function (_super) { divStyle.textAlign = this.blockDef.align; return (React.createElement("div", { onClick: handleClick, style: divStyle }, React.createElement("img", { src: url, style: imageStyle }))); - }; - ImageBlock.prototype.renderDesign = function (props) { + } + renderDesign(props) { return this.renderImage(props.locale); - }; - ImageBlock.prototype.renderInstance = function (instanceCtx) { - var _this = this; - var handleClick = function () { + } + renderInstance(instanceCtx) { + const handleClick = () => { // Run action - if (_this.blockDef.clickActionDef) { - var action = instanceCtx.actionLibrary.createAction(_this.blockDef.clickActionDef); + if (this.blockDef.clickActionDef) { + const action = instanceCtx.actionLibrary.createAction(this.blockDef.clickActionDef); action.performAction(instanceCtx); } }; return this.renderImage(instanceCtx.locale, handleClick); - }; - ImageBlock.prototype.renderEditor = function (props) { - var _this = this; - var locales = [ + } + renderEditor(props) { + const locales = [ "en", "fr", "es", @@ -120,31 +101,27 @@ var ImageBlock = /** @class */ (function (_super) { "bn", "am" ]; - var localizedUrls = this.blockDef.localizedUrls || {}; + const localizedUrls = this.blockDef.localizedUrls || {}; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "URL" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "url" }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "url" }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Size Mode" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "sizeMode" }, function (value, onChange) { - return React.createElement(bootstrap_1.Select, { value: value || "normal", onChange: onChange, options: [ - { value: "normal", label: "Normal" }, - { value: "fullwidth", label: "Full width" }, - { value: "banner", label: "Banner" } - ] }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "sizeMode" }, (value, onChange) => React.createElement(bootstrap_1.Select, { value: value || "normal", onChange: onChange, options: [ + { value: "normal", label: "Normal" }, + { value: "fullwidth", label: "Full width" }, + { value: "banner", label: "Banner" } + ] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Alignment" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "align" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value || "left", onChange: onChange, options: [ - { value: "left", label: React.createElement("i", { className: "fa fa-align-left" }) }, - { value: "center", label: React.createElement("i", { className: "fa fa-align-center" }) }, - { value: "right", label: React.createElement("i", { className: "fa fa-align-right" }) }, - ] }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "align" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "left", onChange: onChange, options: [ + { value: "left", label: React.createElement("i", { className: "fa fa-align-left" }) }, + { value: "center", label: React.createElement("i", { className: "fa fa-align-center" }) }, + { value: "right", label: React.createElement("i", { className: "fa fa-align-right" }) }, + ] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "When image clicked" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "clickActionDef" }, function (value, onChange) { return (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: props })); })), - React.createElement(propertyEditors_1.LabeledProperty, { label: "Locale-specific URL overrides" }, locales.map(function (locale) { - var onChange = function (url) { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (bd) { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "clickActionDef" }, (value, onChange) => (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: props })))), + React.createElement(propertyEditors_1.LabeledProperty, { label: "Locale-specific URL overrides" }, locales.map(locale => { + const onChange = (url) => { + props.store.replaceBlock(immer_1.default(this.blockDef, bd => { if (url) { bd.localizedUrls = bd.localizedUrls || {}; bd.localizedUrls[locale] = url; @@ -158,7 +135,6 @@ var ImageBlock = /** @class */ (function (_super) { return React.createElement(propertyEditors_1.LabeledProperty, { label: locale }, React.createElement(bootstrap_1.TextInput, { value: localizedUrls[locale], onChange: onChange, emptyNull: true })); })))); - }; - return ImageBlock; -}(LeafBlock_1.default)); + } +} exports.ImageBlock = ImageBlock; diff --git a/lib/widgets/blocks/labeled.js b/lib/widgets/blocks/labeled.js index cbf99461..d8391ed7 100644 --- a/lib/widgets/blocks/labeled.js +++ b/lib/widgets/blocks/labeled.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,71 +23,63 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LabeledBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var localization_1 = require("../localization"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var LabeledBlock = /** @class */ (function (_super) { - __extends(LabeledBlock, _super); - function LabeledBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - LabeledBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const localization_1 = require("../localization"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +class LabeledBlock extends blocks_1.Block { + getChildren(contextVars) { return this.blockDef.child ? [{ blockDef: this.blockDef.child, contextVars: contextVars }] : []; - }; - LabeledBlock.prototype.validate = function () { return null; }; - LabeledBlock.prototype.processChildren = function (action) { - var child = action(this.blockDef.child); - return immer_1.default(this.blockDef, function (draft) { + } + validate() { return null; } + processChildren(action) { + const child = action(this.blockDef.child); + return immer_1.default(this.blockDef, draft => { draft.child = child; }); - }; - LabeledBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleAdd = function (addedBlockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleAdd = (addedBlockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.child = addedBlockDef; return b; }), addedBlockDef.id); }; - var labelText = localization_1.localize(this.blockDef.label, props.locale); - var hintText = localization_1.localize(this.blockDef.hint, props.locale); - var helpText = localization_1.localize(this.blockDef.help, props.locale); + const labelText = localization_1.localize(this.blockDef.label, props.locale); + const hintText = localization_1.localize(this.blockDef.hint, props.locale); + const helpText = localization_1.localize(this.blockDef.help, props.locale); return this.blockDef.layout == "horizontal" ? React.createElement(HorizLabeledControl, { designMode: true, labelText: labelText || "Label", hintText: hintText, helpText: helpText, requiredStar: this.blockDef.requiredStar }, props.renderChildBlock(props, this.blockDef.child, handleAdd)) : React.createElement(StackedLabeledControl, { labelText: labelText || "Label", hintText: hintText, helpText: helpText, requiredStar: this.blockDef.requiredStar }, props.renderChildBlock(props, this.blockDef.child, handleAdd)); - }; - LabeledBlock.prototype.renderInstance = function (props) { - var labelText = localization_1.localize(this.blockDef.label, props.locale); - var hintText = localization_1.localize(this.blockDef.hint, props.locale); - var helpText = localization_1.localize(this.blockDef.help, props.locale); + } + renderInstance(props) { + const labelText = localization_1.localize(this.blockDef.label, props.locale); + const hintText = localization_1.localize(this.blockDef.hint, props.locale); + const helpText = localization_1.localize(this.blockDef.help, props.locale); return this.blockDef.layout == "horizontal" ? React.createElement(HorizLabeledControl, { labelText: labelText || "Label", hintText: hintText, helpText: helpText, requiredStar: this.blockDef.requiredStar }, props.renderChildBlock(props, this.blockDef.child)) : React.createElement(StackedLabeledControl, { labelText: labelText, hintText: hintText, helpText: helpText, requiredStar: this.blockDef.requiredStar }, props.renderChildBlock(props, this.blockDef.child)); - }; - LabeledBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Label" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "label" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "label" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Hint" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "hint" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "hint" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Help" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "help" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "requiredStar" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Show required star"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "help" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "requiredStar" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Show required star")), React.createElement(propertyEditors_1.LabeledProperty, { label: "Layout" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "layout" }, function (value, onChange) { - return React.createElement(bootstrap_1.Toggle, { value: value || "stacked", onChange: onChange, options: [ - { value: "stacked", label: "Stacked" }, - { value: "horizontal", label: "Horizontal" } - ] }); - })))); - }; - return LabeledBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "layout" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "stacked", onChange: onChange, options: [ + { value: "stacked", label: "Stacked" }, + { value: "horizontal", label: "Horizontal" } + ] }))))); + } +} exports.LabeledBlock = LabeledBlock; function StackedLabeledControl(props) { return React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, diff --git a/lib/widgets/blocks/panel.js b/lib/widgets/blocks/panel.js index 70deb8ac..3a75813a 100644 --- a/lib/widgets/blocks/panel.js +++ b/lib/widgets/blocks/panel.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,66 +23,59 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PanelBlock = void 0; -var React = __importStar(require("react")); -var _ = __importStar(require("lodash")); -var blocks_1 = require("../blocks"); -var immer_1 = __importDefault(require("immer")); -var PanelBlock = /** @class */ (function (_super) { - __extends(PanelBlock, _super); - function PanelBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - PanelBlock.prototype.getChildren = function (contextVars) { +const React = __importStar(require("react")); +const _ = __importStar(require("lodash")); +const blocks_1 = require("../blocks"); +const immer_1 = __importDefault(require("immer")); +class PanelBlock extends blocks_1.Block { + getChildren(contextVars) { // Get for all cells - return _.compact([this.blockDef.mainContent, this.blockDef.headerContent, this.blockDef.footerContent]).map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; - PanelBlock.prototype.validate = function () { return null; }; - PanelBlock.prototype.processChildren = function (action) { - var _this = this; - return immer_1.default(this.blockDef, function (draft) { - draft.mainContent = action(_this.blockDef.mainContent); - if (_this.blockDef.headerContent) { - draft.headerContent = action(_this.blockDef.headerContent); + return _.compact([this.blockDef.mainContent, this.blockDef.headerContent, this.blockDef.footerContent]).map(bd => ({ blockDef: bd, contextVars: contextVars })); + } + validate() { return null; } + processChildren(action) { + return immer_1.default(this.blockDef, (draft) => { + draft.mainContent = action(this.blockDef.mainContent); + if (this.blockDef.headerContent) { + draft.headerContent = action(this.blockDef.headerContent); } - if (_this.blockDef.footerContent) { - draft.footerContent = action(_this.blockDef.footerContent); + if (this.blockDef.footerContent) { + draft.footerContent = action(this.blockDef.footerContent); } }); - }; - PanelBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSetMainContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleSetMainContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.mainContent = blockDef; }), blockDef.id); }; - var handleSetHeaderContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const handleSetHeaderContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.headerContent = blockDef; }), blockDef.id); }; - var handleSetFooterContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const handleSetFooterContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.footerContent = blockDef; }), blockDef.id); }; - var mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent, handleSetMainContent); - var headerContentNode = this.blockDef.headerContent !== undefined ? props.renderChildBlock(props, this.blockDef.headerContent, handleSetHeaderContent) : null; - var footerContentNode = this.blockDef.footerContent !== undefined ? props.renderChildBlock(props, this.blockDef.footerContent, handleSetFooterContent) : null; + const mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent, handleSetMainContent); + const headerContentNode = this.blockDef.headerContent !== undefined ? props.renderChildBlock(props, this.blockDef.headerContent, handleSetHeaderContent) : null; + const footerContentNode = this.blockDef.footerContent !== undefined ? props.renderChildBlock(props, this.blockDef.footerContent, handleSetFooterContent) : null; return React.createElement(PanelComponent, { header: headerContentNode, main: mainContentNode, footer: footerContentNode }); - }; - PanelBlock.prototype.renderInstance = function (props) { - var mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent); - var headerContentNode = props.renderChildBlock(props, this.blockDef.headerContent || null); - var footerContentNode = props.renderChildBlock(props, this.blockDef.footerContent || null); + } + renderInstance(props) { + const mainContentNode = props.renderChildBlock(props, this.blockDef.mainContent); + const headerContentNode = props.renderChildBlock(props, this.blockDef.headerContent || null); + const footerContentNode = props.renderChildBlock(props, this.blockDef.footerContent || null); return React.createElement(PanelComponent, { header: headerContentNode, main: mainContentNode, footer: footerContentNode }); - }; - PanelBlock.prototype.renderEditor = function (props) { - var _this = this; - var showHeader = function () { props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { headerContent: null })); }; - var hideHeader = function () { props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { headerContent: undefined })); }; - var showFooter = function () { props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { footerContent: null })); }; - var hideFooter = function () { props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { footerContent: undefined })); }; + } + renderEditor(props) { + const showHeader = () => { props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { headerContent: null })); }; + const hideHeader = () => { props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { headerContent: undefined })); }; + const showFooter = () => { props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { footerContent: null })); }; + const hideFooter = () => { props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { footerContent: undefined })); }; return (React.createElement("div", null, React.createElement("div", null, this.blockDef.headerContent === undefined ? React.createElement("button", { className: "btn btn-link", onClick: showHeader }, "Show Header") @@ -114,11 +83,10 @@ var PanelBlock = /** @class */ (function (_super) { React.createElement("div", null, this.blockDef.footerContent === undefined ? React.createElement("button", { className: "btn btn-link", onClick: showFooter }, "Show Footer") : React.createElement("button", { className: "btn btn-link", onClick: hideFooter }, "Hide Footer")))); - }; - return PanelBlock; -}(blocks_1.Block)); + } +} exports.PanelBlock = PanelBlock; -var PanelComponent = function (props) { +const PanelComponent = (props) => { return (React.createElement("div", { className: "panel panel-default" }, props.header ? React.createElement("div", { className: "panel-heading" }, props.header) diff --git a/lib/widgets/blocks/print.js b/lib/widgets/blocks/print.js index ea0a3243..7236a0d3 100644 --- a/lib/widgets/blocks/print.js +++ b/lib/widgets/blocks/print.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,33 +23,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PrintBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var react_1 = require("react"); -var react_dom_1 = require("react-dom"); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var PrintBlock = /** @class */ (function (_super) { - __extends(PrintBlock, _super); - function PrintBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - PrintBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const react_1 = require("react"); +const react_dom_1 = require("react-dom"); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +class PrintBlock extends blocks_1.Block { + getChildren(contextVars) { return this.blockDef.content ? [{ blockDef: this.blockDef.content, contextVars: contextVars }] : []; - }; - PrintBlock.prototype.validate = function () { return null; }; - PrintBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + validate() { return null; } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; - PrintBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleAdd = function (addedBlockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleAdd = (addedBlockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = addedBlockDef; return b; }), addedBlockDef.id); @@ -83,27 +54,24 @@ var PrintBlock = /** @class */ (function (_super) { React.createElement("button", { type: "button", className: "btn btn-link" }, React.createElement("i", { className: "fa fa-print" }))), props.renderChildBlock(props, this.blockDef.content, handleAdd))); - }; - PrintBlock.prototype.renderInstance = function (ctx) { + } + renderInstance(ctx) { return React.createElement(PrintInstance, { ctx: ctx, blockDef: this.blockDef }); - }; - PrintBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Paper Size" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "paperSize" }, function (value, onChange) { - return React.createElement(bootstrap_1.Select, { value: value || "letter-portrait", onChange: onChange, options: [ - { value: "letter-portrait", label: "Letter (portrait)" }, - { value: "letter-landscape", label: "Letter (landscape)" } - ] }); - })))); - }; - return PrintBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "paperSize" }, (value, onChange) => React.createElement(bootstrap_1.Select, { value: value || "letter-portrait", onChange: onChange, options: [ + { value: "letter-portrait", label: "Letter (portrait)" }, + { value: "letter-landscape", label: "Letter (landscape)" } + ] }))))); + } +} exports.PrintBlock = PrintBlock; /** Instance which shows the print button and a preview */ -var PrintInstance = function (props) { - var _a = react_1.useState(false), printing = _a[0], setPrinting = _a[1]; - var handleClick = function () { +const PrintInstance = (props) => { + const [printing, setPrinting] = react_1.useState(false); + const handleClick = () => { setPrinting(true); }; return (React.createElement("div", null, @@ -111,36 +79,36 @@ var PrintInstance = function (props) { React.createElement("button", { type: "button", className: "btn btn-link", onClick: handleClick }, React.createElement("i", { className: "fa fa-print" }))), props.ctx.renderChildBlock(props.ctx, props.blockDef.content), - printing ? React.createElement(ExecutePrintInstance, { blockDef: props.blockDef, ctx: props.ctx, onComplete: function () { return setPrinting(false); } }) : null)); + printing ? React.createElement(ExecutePrintInstance, { blockDef: props.blockDef, ctx: props.ctx, onComplete: () => setPrinting(false) }) : null)); }; /** Component which is displayed which creates the element to print in a portal, * waits for it to finish loading, executes the print and does a callback */ -var ExecutePrintInstance = function (props) { +const ExecutePrintInstance = (props) => { /** Keep track of number of pending queries */ - var pendingQueriesRef = react_1.useRef(0); + const pendingQueriesRef = react_1.useRef(0); /** Keep track of number of total queries */ - var totalQueriesRef = react_1.useRef(0); + const totalQueriesRef = react_1.useRef(0); /** Query status string */ - var _a = react_1.useState(""), statusString = _a[0], setStatusString = _a[1]; + const [statusString, setStatusString] = react_1.useState(""); /** Create tracking database and data source to make context that tracks query requests */ - var printCtx = react_1.useMemo(function () { - var onStartQuery = function () { + const printCtx = react_1.useMemo(() => { + const onStartQuery = () => { pendingQueriesRef.current = pendingQueriesRef.current + 1; totalQueriesRef.current = totalQueriesRef.current + 1; - setStatusString(totalQueriesRef.current - pendingQueriesRef.current + " / " + totalQueriesRef.current); + setStatusString(`${totalQueriesRef.current - pendingQueriesRef.current} / ${totalQueriesRef.current}`); }; - var onEndQuery = function () { + const onEndQuery = () => { pendingQueriesRef.current = pendingQueriesRef.current - 1; - setStatusString(totalQueriesRef.current - pendingQueriesRef.current + " / " + totalQueriesRef.current); + setStatusString(`${totalQueriesRef.current - pendingQueriesRef.current} / ${totalQueriesRef.current}`); }; - return __assign(__assign({}, props.ctx), { database: new TrackingDatabase(props.ctx.database, onStartQuery, onEndQuery), dataSource: props.ctx.dataSource ? new TrackingDataSource(props.ctx.dataSource, onStartQuery, onEndQuery) : undefined }); + return Object.assign(Object.assign({}, props.ctx), { database: new TrackingDatabase(props.ctx.database, onStartQuery, onEndQuery), dataSource: props.ctx.dataSource ? new TrackingDataSource(props.ctx.dataSource, onStartQuery, onEndQuery) : undefined }); }, []); // Create printable element - var printElem = react_1.useMemo(function () { - var paperSize = props.blockDef.paperSize || "letter-portait"; + const printElem = react_1.useMemo(() => { + const paperSize = props.blockDef.paperSize || "letter-portait"; // Create element at 96 dpi (usual for browsers) and 7.5" across (letter - 0.5" each side). 1440 is double, so scale down - var width = 1440; + let width = 1440; if (paperSize == "letter-landscape") { width = 1920; } @@ -148,26 +116,79 @@ var ExecutePrintInstance = function (props) { React.createElement("div", { style: { width: width } }, printCtx.renderChildBlock(printCtx, props.blockDef.content))); }, [printCtx]); // Perform print after delay of waiting for no queries - react_1.useEffect(function () { + react_1.useEffect(() => { // Repeatedly check pending queries - var interval = setInterval(function () { + const interval = setInterval(() => { // If no queries, print after cancelling intervals if (pendingQueriesRef.current == 0) { clearInterval(interval); // Extra delay to ensure finished rendering - setTimeout(function () { + setTimeout(() => { window.print(); props.onComplete(); }, 3000); } }, 3000); - return function () { clearInterval(interval); }; + return () => { clearInterval(interval); }; }, []); // Create size css string - var sizeCss = (props.blockDef.paperSize || "letter-portait") == "letter-portait" ? "8.5in 11in" : "11in 8.5in landscape"; + const sizeCss = (props.blockDef.paperSize || "letter-portait") == "letter-portait" ? "8.5in 11in" : "11in 8.5in landscape"; // Fragment that contains CSS, splash screen and element to print - var printFragment = React.createElement(React.Fragment, null, - React.createElement("style", null, "\n @media print {\n /* Hide body and get rid of margins */\n body {\n visibility: hidden;\n margin: 0;\n padding: 0;\n opacity: 100%\n }\n\n /* Hide all children of body */\n body > * {\n display: none;\n }\n\n /* Setup special region */\n #react_element_printer {\n display: block !important;\n visibility: visible;\n }\n }\n\n @media screen {\n /* REMOVED: Don't show when not printing. Caused c3 problems */\n /*#react_element_printer {\n visibility: hidden;\n }*/\n }\n\n @page {\n size: " + sizeCss + "; \n margin: 0.5in 0.5in 0.5in 0.5in; \n }\n\n #react_element_printer_splash {\n display: flex; \n align-items: center;\n justify-content: center; \n position: fixed; \n left: 0;\n top: 0;\n z-index: 9999;\n width: 100%;\n height: 100%;\n overflow: visible; \n background-color: rgba(255,255,255,0.8);\n }\n\n @media print {\n #react_element_printer_splash {\n display: none;\n }\n }\n "), + const printFragment = React.createElement(React.Fragment, null, + React.createElement("style", null, ` + @media print { + /* Hide body and get rid of margins */ + body { + visibility: hidden; + margin: 0; + padding: 0; + opacity: 100% + } + + /* Hide all children of body */ + body > * { + display: none; + } + + /* Setup special region */ + #react_element_printer { + display: block !important; + visibility: visible; + } + } + + @media screen { + /* REMOVED: Don't show when not printing. Caused c3 problems */ + /*#react_element_printer { + visibility: hidden; + }*/ + } + + @page { + size: ${sizeCss}; + margin: 0.5in 0.5in 0.5in 0.5in; + } + + #react_element_printer_splash { + display: flex; + align-items: center; + justify-content: center; + position: fixed; + left: 0; + top: 0; + z-index: 9999; + width: 100%; + height: 100%; + overflow: visible; + background-color: rgba(255,255,255,0.8); + } + + @media print { + #react_element_printer_splash { + display: none; + } + } + `), React.createElement("div", { id: "react_element_printer" }, printElem), React.createElement("div", { id: "react_element_printer_splash" }, React.createElement("div", { style: { fontSize: 30, width: "50%" } }, @@ -180,68 +201,62 @@ var ExecutePrintInstance = function (props) { }; /** Database that proxies another database but calls callback whenever a query is started or ended. * Allows tracking of when queries have gone idle */ -var TrackingDatabase = /** @class */ (function () { - function TrackingDatabase(database, onStartQuery, onEndQuery) { +class TrackingDatabase { + constructor(database, onStartQuery, onEndQuery) { this.database = database; this.onStartQuery = onStartQuery; this.onEndQuery = onEndQuery; } - TrackingDatabase.prototype.query = function (options, contextVars, filteredContextVarValues) { - var _this = this; + query(options, contextVars, filteredContextVarValues) { // Notify of query this.onStartQuery(); - return new Promise(function (resolve, reject) { - _this.database.query(options, contextVars, filteredContextVarValues).then(function (rows) { + return new Promise((resolve, reject) => { + this.database.query(options, contextVars, filteredContextVarValues).then((rows) => { resolve(rows); - }).catch(function (reason) { reject(reason); }).finally(function () { - _this.onEndQuery(); + }).catch((reason) => { reject(reason); }).finally(() => { + this.onEndQuery(); }); }); - }; - TrackingDatabase.prototype.addChangeListener = function (changeListener) { + } + addChangeListener(changeListener) { // Do nothing as printing should not update dynamically - }; - TrackingDatabase.prototype.removeChangeListener = function (changeListener) { + } + removeChangeListener(changeListener) { // Do nothing as printing should not update dynamically - }; - TrackingDatabase.prototype.transaction = function () { + } + transaction() { return this.database.transaction(); - }; - return TrackingDatabase; -}()); + } +} /** Data source that proxies another data source but calls callback whenever a query is performed. * Allows tracking of when queries have gone idle */ -var TrackingDataSource = /** @class */ (function (_super) { - __extends(TrackingDataSource, _super); - function TrackingDataSource(dataSource, onStartQuery, onEndQuery) { - var _this = _super.call(this) || this; - _this.dataSource = dataSource; - _this.onStartQuery = onStartQuery; - _this.onEndQuery = onEndQuery; - return _this; +class TrackingDataSource extends mwater_expressions_1.DataSource { + constructor(dataSource, onStartQuery, onEndQuery) { + super(); + this.dataSource = dataSource; + this.onStartQuery = onStartQuery; + this.onEndQuery = onEndQuery; } /** Performs a single query. Calls cb with (error, rows) */ - TrackingDataSource.prototype.performQuery = function (query, cb) { - var _this = this; + performQuery(query, cb) { this.onStartQuery(); - this.dataSource.performQuery(query, function (error, rows) { - _this.onEndQuery(); + this.dataSource.performQuery(query, (error, rows) => { + this.onEndQuery(); cb(error, rows); }); - }; + } /** Get the url to download an image (by id from an image or imagelist column) Height, if specified, is minimum height needed. May return larger image Can be used to upload by posting to this url */ - TrackingDataSource.prototype.getImageUrl = function (imageId, height) { + getImageUrl(imageId, height) { return this.dataSource.getImageUrl(imageId, height); - }; + } // Clears the cache if possible with this data source - TrackingDataSource.prototype.clearCache = function () { + clearCache() { this.dataSource.clearCache(); - }; + } // Get the cache expiry time in ms from epoch. No cached items before this time will be used. 0 for no cache limit. // Useful for knowing when cache has been cleared, as it will be set to time of clearing. - TrackingDataSource.prototype.getCacheExpiry = function () { return this.dataSource.getCacheExpiry(); }; - return TrackingDataSource; -}(mwater_expressions_1.DataSource)); + getCacheExpiry() { return this.dataSource.getCacheExpiry(); } +} diff --git a/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.js b/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.js index 1f5509bd..7dea13e6 100644 --- a/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.js +++ b/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -46,58 +22,55 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var mwater_expressions_1 = require("mwater-expressions"); -var lodash_1 = __importDefault(require("lodash")); -var localization_1 = require("../../localization"); -var contexts_1 = require("../../../contexts"); -var blocks_1 = require("../../blocks"); +const React = __importStar(require("react")); +const mwater_expressions_1 = require("mwater-expressions"); +const lodash_1 = __importDefault(require("lodash")); +const localization_1 = require("../../localization"); +const contexts_1 = require("../../../contexts"); +const blocks_1 = require("../../blocks"); /** Instance of a query table */ -var QueryRepeatBlockInstance = /** @class */ (function (_super) { - __extends(QueryRepeatBlockInstance, _super); - function QueryRepeatBlockInstance(props) { - var _this = _super.call(this, props) || this; +class QueryRepeatBlockInstance extends React.Component { + constructor(props) { + super(props); /** Change listener to refresh database */ - _this.handleChange = function () { - _this.performQuery(); + this.handleChange = () => { + this.performQuery(); }; - _this.state = { refreshing: false }; - return _this; + this.state = { refreshing: false }; } - QueryRepeatBlockInstance.prototype.componentDidMount = function () { + componentDidMount() { this.props.instanceCtx.database.addChangeListener(this.handleChange); this.performQuery(); - }; - QueryRepeatBlockInstance.prototype.componentDidUpdate = function (prevProps) { + } + componentDidUpdate(prevProps) { // Redo query if changed - var newQueryOptions = this.createQuery(); + const newQueryOptions = this.createQuery(); if (!lodash_1.default.isEqual(newQueryOptions, this.queryOptions) || !lodash_1.default.isEqual(this.props.instanceCtx.contextVarValues, prevProps.instanceCtx.contextVarValues)) { this.performQuery(); } - }; - QueryRepeatBlockInstance.prototype.componentWillUnmount = function () { + } + componentWillUnmount() { this.props.instanceCtx.database.removeChangeListener(this.handleChange); - }; - QueryRepeatBlockInstance.prototype.createQuery = function () { - var _this = this; - var rips = this.props.instanceCtx; - var block = this.props.block; + } + createQuery() { + const rips = this.props.instanceCtx; + const block = this.props.block; // Get expressions - var rowsetCV = rips.contextVars.find(function (cv) { return cv.id === block.blockDef.rowsetContextVarId; }); - var rowExprs = block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); - var rowsetCVValue = rips.contextVarValues[rowsetCV.id]; + const rowsetCV = rips.contextVars.find(cv => cv.id === block.blockDef.rowsetContextVarId); + const rowExprs = block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); + const rowsetCVValue = rips.contextVarValues[rowsetCV.id]; // Create where - var where = { + const where = { type: "op", op: "and", table: rowsetCV.table, - exprs: lodash_1.default.compact([rowsetCVValue].concat(lodash_1.default.map(rips.getFilters(rowsetCV.id), function (f) { return f.expr; }))) + exprs: lodash_1.default.compact([rowsetCVValue].concat(lodash_1.default.map(rips.getFilters(rowsetCV.id), f => f.expr))) }; // Add own where if (block.blockDef.where) { where.exprs.push(block.blockDef.where); } - var queryOptions = { + let queryOptions = { select: {}, from: rowsetCV.table, where: where.exprs.length > 0 ? where : null, @@ -112,48 +85,45 @@ var QueryRepeatBlockInstance = /** @class */ (function (_super) { queryOptions.orderBy.push({ expr: { type: "id", table: rowsetCV.table }, dir: "asc" }); // Add expressions queryOptions.select.id = { type: "id", table: rowsetCV.table }; - rowExprs.forEach(function (expr, index) { + rowExprs.forEach((expr, index) => { queryOptions.select["e" + index] = expr; }); // The context variable that represents the row has a value which changes with each row // so replace it with { type: "id" ...} expression so that it evaluates as the row id - queryOptions = mapObject(queryOptions, function (input) { - if (input && input.type == "variable" && input.variableId == _this.props.block.getRowContextVarId()) { + queryOptions = mapObject(queryOptions, (input) => { + if (input && input.type == "variable" && input.variableId == this.props.block.getRowContextVarId()) { return { type: "id", table: queryOptions.from }; } return input; }); return queryOptions; - }; - QueryRepeatBlockInstance.prototype.performQuery = function () { - var _this = this; - var queryOptions = this.createQuery(); + } + performQuery() { + const queryOptions = this.createQuery(); this.queryOptions = queryOptions; // Mark as refreshing this.setState({ refreshing: true }); - this.props.instanceCtx.database.query(queryOptions, this.props.instanceCtx.contextVars, contexts_1.getFilteredContextVarValues(this.props.instanceCtx)).then(function (rows) { + this.props.instanceCtx.database.query(queryOptions, this.props.instanceCtx.contextVars, contexts_1.getFilteredContextVarValues(this.props.instanceCtx)).then(rows => { // Check if still relevant - if (lodash_1.default.isEqual(queryOptions, _this.createQuery())) { - _this.setState({ rows: rows, refreshing: false }); + if (lodash_1.default.isEqual(queryOptions, this.createQuery())) { + this.setState({ rows, refreshing: false }); } - }).catch(function (error) { - _this.setState({ error: error }); + }).catch(error => { + this.setState({ error: error }); }); - }; - QueryRepeatBlockInstance.prototype.createRowInstanceCtx = function (rowIndex) { - var _a; - var _this = this; - var rips = this.props.instanceCtx; + } + createRowInstanceCtx(rowIndex) { + const rips = this.props.instanceCtx; // Row context variable - var rowsetCV = this.props.instanceCtx.contextVars.find(function (cv) { return cv.id === _this.props.block.blockDef.rowsetContextVarId; }); - var rowcv = this.props.block.createRowContextVar(rowsetCV); + const rowsetCV = this.props.instanceCtx.contextVars.find(cv => cv.id === this.props.block.blockDef.rowsetContextVarId); + const rowcv = this.props.block.createRowContextVar(rowsetCV); // TODO move out of here to be faster - var rowExprs = this.props.block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); - var innerContextVars = rips.contextVars.concat(rowcv); + const rowExprs = this.props.block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); + const innerContextVars = rips.contextVars.concat(rowcv); // Row context variable value - var cvvalue = this.props.block.getRowContextVarValue(this.state.rows[rowIndex], rowExprs, this.props.instanceCtx.schema, rowsetCV, innerContextVars); - var innerContextVarValues = __assign(__assign({}, rips.contextVarValues), (_a = {}, _a[rowcv.id] = cvvalue, _a)); - return __assign(__assign({}, rips), { contextVars: innerContextVars, contextVarValues: innerContextVarValues, getContextVarExprValue: function (cvid, expr) { + const cvvalue = this.props.block.getRowContextVarValue(this.state.rows[rowIndex], rowExprs, this.props.instanceCtx.schema, rowsetCV, innerContextVars); + const innerContextVarValues = Object.assign(Object.assign({}, rips.contextVarValues), { [rowcv.id]: cvvalue }); + return Object.assign(Object.assign({}, rips), { contextVars: innerContextVars, contextVarValues: innerContextVarValues, getContextVarExprValue: (cvid, expr) => { // Null expression has null value if (!expr) { return null; @@ -171,11 +141,11 @@ var QueryRepeatBlockInstance = /** @class */ (function (_super) { return rips.getContextVarExprValue(cvid, expr); } // Look up expression - var exprIndex = rowExprs.findIndex(function (rowExpr) { return lodash_1.default.isEqual(expr, rowExpr); }); - return _this.state.rows[rowIndex]["e" + exprIndex]; + const exprIndex = rowExprs.findIndex(rowExpr => lodash_1.default.isEqual(expr, rowExpr)); + return this.state.rows[rowIndex]["e" + exprIndex]; } }); - }; - QueryRepeatBlockInstance.prototype.renderSeparator = function () { + } + renderSeparator() { switch (this.props.block.blockDef.separator) { case "none": return null; @@ -184,11 +154,11 @@ var QueryRepeatBlockInstance = /** @class */ (function (_super) { case "solid_line": return React.createElement("hr", null); } - }; - QueryRepeatBlockInstance.prototype.renderRow = function (row, rowIndex) { - var orientation = this.props.block.blockDef.orientation || "vertical"; - var horizontalSpacing = this.props.block.blockDef.horizontalSpacing != null ? this.props.block.blockDef.horizontalSpacing : 5; - var rowRIProps = this.createRowInstanceCtx(rowIndex); + } + renderRow(row, rowIndex) { + const orientation = this.props.block.blockDef.orientation || "vertical"; + const horizontalSpacing = this.props.block.blockDef.horizontalSpacing != null ? this.props.block.blockDef.horizontalSpacing : 5; + const rowRIProps = this.createRowInstanceCtx(rowIndex); if (orientation == "vertical") { return (React.createElement("div", { key: row.id }, rowIndex > 0 ? this.renderSeparator() : null, @@ -197,9 +167,8 @@ var QueryRepeatBlockInstance = /** @class */ (function (_super) { else { return (React.createElement("div", { key: row.id, style: { display: "inline-block", verticalAlign: "top", marginLeft: rowIndex > 0 ? horizontalSpacing : 0 } }, rowRIProps.renderChildBlock(rowRIProps, this.props.block.blockDef.content))); } - }; - QueryRepeatBlockInstance.prototype.renderRows = function () { - var _this = this; + } + renderRows() { if (this.state.error) { // TODO localize return React.createElement("div", { className: "alert alert-danger" }, "Error loading data"); @@ -211,11 +180,11 @@ var QueryRepeatBlockInstance = /** @class */ (function (_super) { if (this.state.rows.length === 0 && this.props.block.blockDef.noRowsMessage) { return React.createElement("div", { style: { fontStyle: "italic" } }, localization_1.localize(this.props.block.blockDef.noRowsMessage, this.props.instanceCtx.locale)); } - return this.state.rows.map(function (row, rowIndex) { return _this.renderRow(row, rowIndex); }); - }; - QueryRepeatBlockInstance.prototype.render = function () { - var riProps = this.props.instanceCtx; - var style = { + return this.state.rows.map((row, rowIndex) => this.renderRow(row, rowIndex)); + } + render() { + const riProps = this.props.instanceCtx; + const style = { marginTop: 5 }; // Fade if refreshing @@ -223,23 +192,22 @@ var QueryRepeatBlockInstance = /** @class */ (function (_super) { style.opacity = 0.6; } return (React.createElement("div", null, this.renderRows())); - }; - return QueryRepeatBlockInstance; -}(React.Component)); + } +} exports.default = QueryRepeatBlockInstance; /** Replace every part of an object, including array members * replacer should return input to leave unchanged */ -var mapObject = function (obj, replacer) { +const mapObject = (obj, replacer) => { obj = replacer(obj); if (!obj) { return obj; } if (lodash_1.default.isArray(obj)) { - return lodash_1.default.map(obj, function (item) { return mapObject(item, replacer); }); + return lodash_1.default.map(obj, (item) => mapObject(item, replacer)); } if (lodash_1.default.isObject(obj)) { - return lodash_1.default.mapValues(obj, function (item) { return mapObject(item, replacer); }); + return lodash_1.default.mapValues(obj, (item) => mapObject(item, replacer)); } return obj; }; diff --git a/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.test.js b/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.test.js index 736b4c37..f0f71a87 100644 --- a/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.test.js +++ b/lib/widgets/blocks/queryRepeat/QueryRepeatBlockInstance.test.js @@ -1,15 +1,4 @@ "use strict"; -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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,19 +22,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var enzyme_1 = require("enzyme"); -var React = __importStar(require("react")); -var queryRepeat_1 = require("./queryRepeat"); -var QueryRepeatBlockInstance_1 = __importDefault(require("./QueryRepeatBlockInstance")); -var schema_1 = __importDefault(require("../../../__fixtures__/schema")); -var BlockFactory_1 = __importDefault(require("../../BlockFactory")); -var mockDatabase_1 = __importDefault(require("../../../__fixtures__/mockDatabase")); +const enzyme_1 = require("enzyme"); +const React = __importStar(require("react")); +const queryRepeat_1 = require("./queryRepeat"); +const QueryRepeatBlockInstance_1 = __importDefault(require("./QueryRepeatBlockInstance")); +const schema_1 = __importDefault(require("../../../__fixtures__/schema")); +const BlockFactory_1 = __importDefault(require("../../BlockFactory")); +const mockDatabase_1 = __importDefault(require("../../../__fixtures__/mockDatabase")); // Outer context vars -var rowsetCV = { id: "cv1", type: "rowset", name: "", table: "t1" }; -var contextVars = [rowsetCV]; -var schema = schema_1.default(); -var exprText = { type: "field", table: "t1", column: "text" }; -var qrbd = { +const rowsetCV = { id: "cv1", type: "rowset", name: "", table: "t1" }; +const contextVars = [rowsetCV]; +const schema = schema_1.default(); +const exprText = { type: "field", table: "t1", column: "text" }; +const qrbd = { id: "123", type: "queryRepeat", separator: "solid_line", @@ -55,11 +44,11 @@ var qrbd = { limit: 10, where: null }; -var createBlock = new BlockFactory_1.default().createBlock; -var qtb = new queryRepeat_1.QueryRepeatBlock(qrbd); -var rips; -var database; -beforeEach(function () { +const createBlock = new BlockFactory_1.default().createBlock; +const qtb = new queryRepeat_1.QueryRepeatBlock(qrbd); +let rips; +let database; +beforeEach(() => { database = mockDatabase_1.default(); rips = { createBlock: createBlock, @@ -70,7 +59,7 @@ beforeEach(function () { pageStack: {}, // Simple filter contextVarValues: { cv1: { type: "field", table: "t1", column: "boolean" } }, - getFilters: function () { return []; }, + getFilters: () => [], setFilter: jest.fn(), locale: "en", onSelectContextVar: jest.fn(), @@ -78,14 +67,14 @@ beforeEach(function () { dataSource: {}, renderChildBlock: jest.fn(), widgetLibrary: { widgets: {} }, - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => () => { }, + T: (str) => str }; }); -test("creates query", function () { +test("creates query", () => { database.query.mockResolvedValue([]); - var inst = enzyme_1.mount(React.createElement(QueryRepeatBlockInstance_1.default, { block: qtb, instanceCtx: rips })); - var queryOptions = database.query.mock.calls[0][0]; + const inst = enzyme_1.mount(React.createElement(QueryRepeatBlockInstance_1.default, { block: qtb, instanceCtx: rips })); + const queryOptions = database.query.mock.calls[0][0]; expect(queryOptions).toEqual({ select: { id: { type: "id", table: "t1" }, @@ -102,14 +91,14 @@ test("creates query", function () { limit: 10 }); }); -test("adds filters, orderBy and where", function () { +test("adds filters, orderBy and where", () => { database.query.mockResolvedValue([]); - rips.getFilters = function () { return [{ id: "f1", expr: { type: "literal", valueType: "boolean", value: true } }]; }; - var qtb = createBlock(__assign(__assign({}, qrbd), { where: { type: "literal", valueType: "boolean", value: false }, orderBy: [ + rips.getFilters = () => [{ id: "f1", expr: { type: "literal", valueType: "boolean", value: true } }]; + const qtb = createBlock(Object.assign(Object.assign({}, qrbd), { where: { type: "literal", valueType: "boolean", value: false }, orderBy: [ { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } ] })); - var inst = enzyme_1.mount(React.createElement(QueryRepeatBlockInstance_1.default, { block: qtb, instanceCtx: rips })); - var queryOptions = database.query.mock.calls[0][0]; + const inst = enzyme_1.mount(React.createElement(QueryRepeatBlockInstance_1.default, { block: qtb, instanceCtx: rips })); + const queryOptions = database.query.mock.calls[0][0]; expect(queryOptions).toEqual({ select: { id: { type: "id", table: "t1" }, @@ -133,11 +122,11 @@ test("adds filters, orderBy and where", function () { limit: 10 }); }); -test("injects context variables", function () { +test("injects context variables", () => { database.query.mockResolvedValue([]); - var inst = enzyme_1.mount(React.createElement(QueryRepeatBlockInstance_1.default, { block: qtb, instanceCtx: rips })); + const inst = enzyme_1.mount(React.createElement(QueryRepeatBlockInstance_1.default, { block: qtb, instanceCtx: rips })); inst.setState({ rows: [{ id: "r1", e0: "abc" }] }); - var rowRips = inst.instance().createRowInstanceCtx(0); + const rowRips = inst.instance().createRowInstanceCtx(0); expect(rowRips.contextVarValues["123_row"]).toBe("r1"); expect(rowRips.getContextVarExprValue("123_row", exprText)).toBe("abc"); }); diff --git a/lib/widgets/blocks/queryRepeat/queryRepeat.js b/lib/widgets/blocks/queryRepeat/queryRepeat.js index 77af5c20..b000a678 100644 --- a/lib/widgets/blocks/queryRepeat/queryRepeat.js +++ b/lib/widgets/blocks/queryRepeat/queryRepeat.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,23 +23,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryRepeatBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var QueryRepeatBlockInstance_1 = __importDefault(require("./QueryRepeatBlockInstance")); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var QueryRepeatBlock = /** @class */ (function (_super) { - __extends(QueryRepeatBlock, _super); - function QueryRepeatBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - QueryRepeatBlock.prototype.getChildren = function (contextVars) { - var _this = this; +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const QueryRepeatBlockInstance_1 = __importDefault(require("./QueryRepeatBlockInstance")); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +class QueryRepeatBlock extends blocks_1.Block { + getChildren(contextVars) { // Get rowset context variable - var rowsetCV = contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); + const rowsetCV = contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); if (this.blockDef.content) { return [{ blockDef: this.blockDef.content, @@ -71,16 +42,15 @@ var QueryRepeatBlock = /** @class */ (function (_super) { }]; } return []; - }; - QueryRepeatBlock.prototype.validate = function (options) { - var _this = this; + } + validate(options) { // Validate rowset - var rowsetCV = options.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + const rowsetCV = options.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return "Rowset required"; } - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - var error; + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + let error; // Validate where error = exprValidator.validateExpr(this.blockDef.where, { table: rowsetCV.table }); if (error) { @@ -88,73 +58,70 @@ var QueryRepeatBlock = /** @class */ (function (_super) { } // TODO Validate order by return null; - }; - QueryRepeatBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { draft.content = content; }); - }; + } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); + } /** Create the context variable used */ - QueryRepeatBlock.prototype.createRowContextVar = function (rowsetCV) { - return { id: this.getRowContextVarId(), name: "Table row of " + rowsetCV.name, type: "row", table: rowsetCV.table }; - }; - QueryRepeatBlock.prototype.getRowContextVarId = function () { + createRowContextVar(rowsetCV) { + return { id: this.getRowContextVarId(), name: `Table row of ${rowsetCV.name}`, type: "row", table: rowsetCV.table }; + } + getRowContextVarId() { return this.blockDef.id + "_row"; - }; + } /** Get list of expressions used in a row by content blocks */ - QueryRepeatBlock.prototype.getRowExprs = function (contextVars, ctx) { - var _this = this; - var rowsetCV = contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + getRowExprs(contextVars, ctx) { + const rowsetCV = contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return []; } - var exprs = []; - var rowCV = this.createRowContextVar(rowsetCV); + let exprs = []; + const rowCV = this.createRowContextVar(rowsetCV); // Get expressions for content if (this.blockDef.content) { - exprs = exprs.concat(ctx.createBlock(this.blockDef.content).getSubtreeContextVarExprs(rowCV, __assign(__assign({}, ctx), { contextVars: contextVars.concat([rowCV]) }))); + exprs = exprs.concat(ctx.createBlock(this.blockDef.content).getSubtreeContextVarExprs(rowCV, Object.assign(Object.assign({}, ctx), { contextVars: contextVars.concat([rowCV]) }))); } return exprs; - }; - QueryRepeatBlock.prototype.getContextVarExprs = function () { + } + getContextVarExprs() { return []; - }; + } /** * Get the value of the row context variable for a specific row. * Row should have fields e0, e1, etc. to represent expressions. If singleRow mode, should have id field * contextVars: includes rowsetCV and row one */ - QueryRepeatBlock.prototype.getRowContextVarValue = function (row, rowExprs, schema, rowsetCV, contextVars) { + getRowContextVarValue(row, rowExprs, schema, rowsetCV, contextVars) { return row.id; - }; - QueryRepeatBlock.prototype.renderDesign = function (props) { - var _this = this; - var setContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const setContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default(b => { b.content = blockDef; }), blockDef.id); }; - var rowsetCV = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); - var contentProps = props; + const rowsetCV = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); + let contentProps = props; // Add context variable if knowable if (rowsetCV) { - contentProps = __assign(__assign({}, contentProps), { contextVars: props.contextVars.concat([this.createRowContextVar(rowsetCV)]) }); + contentProps = Object.assign(Object.assign({}, contentProps), { contextVars: props.contextVars.concat([this.createRowContextVar(rowsetCV)]) }); } return (props.renderChildBlock(contentProps, this.blockDef.content, setContent)); - }; - QueryRepeatBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement(QueryRepeatBlockInstance_1.default, { block: this, instanceCtx: props }); - }; - QueryRepeatBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { // Get rowset context variable - var rowsetCV = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var rowCV = rowsetCV ? this.createRowContextVar(rowsetCV) : null; - var separatorOptions = [ + const rowsetCV = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const rowCV = rowsetCV ? this.createRowContextVar(rowsetCV) : null; + const separatorOptions = [ { value: "none", label: "None" }, { value: "solid_line", label: "Solid Line" }, { value: "page_break", label: "Page Break" } ]; - var horizontalSpacingOptions = [ + const horizontalSpacingOptions = [ { value: 0, label: "None" }, { value: 5, label: "5 pixels" }, { value: 10, label: "10 pixels" }, @@ -162,30 +129,27 @@ var QueryRepeatBlock = /** @class */ (function (_super) { ]; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Repeat direction" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "orientation" }, function (value, onChange) { return React.createElement(bootstrap_1.Toggle, { value: value || "vertical", onChange: onChange, options: [{ value: "vertical", label: "Vertical" }, { value: "horizontal", label: "Horizontal" }] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "orientation" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "vertical", onChange: onChange, options: [{ value: "vertical", label: "Vertical" }, { value: "horizontal", label: "Horizontal" }] }))), (this.blockDef.orientation || "vertical") == "vertical" ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Separator" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "separator" }, function (value, onChange) { return React.createElement(bootstrap_1.Select, { value: value, onChange: onChange, options: separatorOptions }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "separator" }, (value, onChange) => React.createElement(bootstrap_1.Select, { value: value, onChange: onChange, options: separatorOptions }))) : React.createElement(propertyEditors_1.LabeledProperty, { label: "Spacing" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "horizontalSpacing" }, function (value, onChange) { return React.createElement(bootstrap_1.Select, { value: value != null ? value : 5, onChange: onChange, options: horizontalSpacingOptions }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "horizontalSpacing" }, (value, onChange) => React.createElement(bootstrap_1.Select, { value: value != null ? value : 5, onChange: onChange, options: horizontalSpacingOptions }))), rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "where" }, function (value, onChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["boolean"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "where" }, (value, onChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["boolean"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })))) : null, rowCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Ordering" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "orderBy" }, function (value, onChange) { - return React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: rowsetCV.table }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "orderBy" }, (value, onChange) => React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: rowsetCV.table }))) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Maximum rows" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "limit" }, function (value, onChange) { return React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: false }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "limit" }, (value, onChange) => React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: false }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Message to display when no rows" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "noRowsMessage" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })))); - }; - return QueryRepeatBlock; -}(blocks_1.Block)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "noRowsMessage" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))))); + } +} exports.QueryRepeatBlock = QueryRepeatBlock; diff --git a/lib/widgets/blocks/queryRepeat/queryRepeat.test.js b/lib/widgets/blocks/queryRepeat/queryRepeat.test.js index c44f296c..1405b30a 100644 --- a/lib/widgets/blocks/queryRepeat/queryRepeat.test.js +++ b/lib/widgets/blocks/queryRepeat/queryRepeat.test.js @@ -1,26 +1,15 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var queryRepeat_1 = require("./queryRepeat"); -var schema_1 = __importDefault(require("../../../__fixtures__/schema")); -var BlockFactory_1 = __importDefault(require("../../BlockFactory")); +const queryRepeat_1 = require("./queryRepeat"); +const schema_1 = __importDefault(require("../../../__fixtures__/schema")); +const BlockFactory_1 = __importDefault(require("../../BlockFactory")); // Outer context vars -var rowsetCV = { id: "cv1", type: "rowset", name: "CV1", table: "t1" }; -var contextVars = [rowsetCV]; -var qrbd = { +const rowsetCV = { id: "cv1", type: "rowset", name: "CV1", table: "t1" }; +const contextVars = [rowsetCV]; +const qrbd = { id: "123", type: "queryRepeat", separator: "solid_line", @@ -30,10 +19,10 @@ var qrbd = { limit: 10, where: null }; -var createBlock = new BlockFactory_1.default().createBlock; -var qrb = new queryRepeat_1.QueryRepeatBlock(qrbd); -var schema = schema_1.default(); -test("gets row cv", function () { +const createBlock = new BlockFactory_1.default().createBlock; +const qrb = new queryRepeat_1.QueryRepeatBlock(qrbd); +const schema = schema_1.default(); +test("gets row cv", () => { expect(qrb.createRowContextVar(rowsetCV)).toEqual({ id: "123_row", name: "Table row of CV1", @@ -41,13 +30,13 @@ test("gets row cv", function () { table: "t1" }); }); -test("gets row cv value", function () { +test("gets row cv value", () => { expect(qrb.getRowContextVarValue({ id: "123" }, [], schema, rowsetCV, contextVars)).toEqual("123"); }); -test("gets row expressions", function () { +test("gets row expressions", () => { // Create single expression in contents - var expr = { type: "field", table: "t1", column: "text" }; - var qrbd2 = __assign(__assign({}, qrbd), { content: { type: "expression", id: "re1", contextVarId: "123_row", expr: expr } }); - var qrb = new queryRepeat_1.QueryRepeatBlock(qrbd2); + const expr = { type: "field", table: "t1", column: "text" }; + const qrbd2 = Object.assign(Object.assign({}, qrbd), { content: { type: "expression", id: "re1", contextVarId: "123_row", expr: expr } }); + const qrb = new queryRepeat_1.QueryRepeatBlock(qrbd2); expect(qrb.getRowExprs(contextVars, { createBlock: createBlock })).toEqual([expr]); }); diff --git a/lib/widgets/blocks/queryTable/QueryTableBlockInstance.js b/lib/widgets/blocks/queryTable/QueryTableBlockInstance.js index 015b3109..4f0a6bd4 100644 --- a/lib/widgets/blocks/queryTable/QueryTableBlockInstance.js +++ b/lib/widgets/blocks/queryTable/QueryTableBlockInstance.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -43,78 +19,75 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -var React = __importStar(require("react")); -var queryTable_1 = require("./queryTable"); -var mwater_expressions_1 = require("mwater-expressions"); -var _ = __importStar(require("lodash")); -var localization_1 = require("../../localization"); -var contexts_1 = require("../../../contexts"); -var blocks_1 = require("../../blocks"); +const React = __importStar(require("react")); +const queryTable_1 = require("./queryTable"); +const mwater_expressions_1 = require("mwater-expressions"); +const _ = __importStar(require("lodash")); +const localization_1 = require("../../localization"); +const contexts_1 = require("../../../contexts"); +const blocks_1 = require("../../blocks"); /** Instance of a query table */ -var QueryTableBlockInstance = /** @class */ (function (_super) { - __extends(QueryTableBlockInstance, _super); - function QueryTableBlockInstance(props) { - var _this = _super.call(this, props) || this; +class QueryTableBlockInstance extends React.Component { + constructor(props) { + super(props); /** Change listener to refresh database */ - _this.handleChange = function () { - _this.performQuery(); + this.handleChange = () => { + this.performQuery(); }; - _this.handleShowMore = function () { - _this.setState({ limit: _this.state.limit + _this.props.block.blockDef.limit }); + this.handleShowMore = () => { + this.setState({ limit: this.state.limit + this.props.block.blockDef.limit }); }; // First column with initial ordering sets the initial ordering - var columnOrderIndex = null; - var columnOrderDir = "asc"; - var blockDef = _this.props.block.blockDef; - for (var colIndex = 0; colIndex < blockDef.contents.length; colIndex++) { + let columnOrderIndex = null; + let columnOrderDir = "asc"; + const blockDef = this.props.block.blockDef; + for (let colIndex = 0; colIndex < blockDef.contents.length; colIndex++) { if (blockDef.columnInfos && blockDef.columnInfos[colIndex] && blockDef.columnInfos[colIndex].orderExpr && blockDef.columnInfos[colIndex].initialOrderDir) { columnOrderIndex = colIndex; columnOrderDir = blockDef.columnInfos[colIndex].initialOrderDir; } } - _this.state = { + this.state = { refreshing: false, - columnOrderIndex: columnOrderIndex, - columnOrderDir: columnOrderDir, + columnOrderIndex, + columnOrderDir, limit: props.block.blockDef.limit, moreRowsAvail: false }; - return _this; } - QueryTableBlockInstance.prototype.componentDidMount = function () { + componentDidMount() { this.props.instanceCtx.database.addChangeListener(this.handleChange); this.performQuery(); - }; - QueryTableBlockInstance.prototype.componentDidUpdate = function (prevProps) { + } + componentDidUpdate(prevProps) { // Redo query if changed - var newQueryOptions = this.createQuery(); + const newQueryOptions = this.createQuery(); if (!_.isEqual(newQueryOptions, this.queryOptions) || !_.isEqual(this.props.instanceCtx.contextVarValues, prevProps.instanceCtx.contextVarValues)) { this.performQuery(); } - }; - QueryTableBlockInstance.prototype.componentWillUnmount = function () { + } + componentWillUnmount() { this.props.instanceCtx.database.removeChangeListener(this.handleChange); - }; - QueryTableBlockInstance.prototype.createQuery = function () { - var _this = this; - var rips = this.props.instanceCtx; - var block = this.props.block; + } + createQuery() { + const rips = this.props.instanceCtx; + const block = this.props.block; // Get expressions - var rowsetCV = rips.contextVars.find(function (cv) { return cv.id === block.blockDef.rowsetContextVarId; }); - var rowExprs = block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); - var rowsetCVValue = rips.contextVarValues[rowsetCV.id]; + const rowsetCV = rips.contextVars.find(cv => cv.id === block.blockDef.rowsetContextVarId); + const rowExprs = block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); + const rowsetCVValue = rips.contextVarValues[rowsetCV.id]; // Create where - var where = { + const where = { type: "op", op: "and", table: rowsetCV.table, - exprs: _.compact([rowsetCVValue].concat(_.map(rips.getFilters(rowsetCV.id), function (f) { return f.expr; }))) + exprs: _.compact([rowsetCVValue].concat(_.map(rips.getFilters(rowsetCV.id), f => f.expr))) }; // Add own where if (block.blockDef.where) { where.exprs.push(block.blockDef.where); } - var queryOptions = { + let queryOptions = { select: {}, from: rowsetCV.table, where: where.exprs.length > 0 ? where : null, @@ -138,7 +111,7 @@ var QueryTableBlockInstance = /** @class */ (function (_super) { if (block.blockDef.mode === "singleRow") { queryOptions.select.id = { type: "id", table: rowsetCV.table }; } - rowExprs.forEach(function (expr, index) { + rowExprs.forEach((expr, index) => { queryOptions.select["e" + index] = expr; }); // Add count to ensure that query is aggregate @@ -147,50 +120,47 @@ var QueryTableBlockInstance = /** @class */ (function (_super) { } // The context variable that represents the row has a value which changes with each row // so replace it with { type: "id" ...} expression so that it evaluates as the row id - queryOptions = mapObject(queryOptions, function (input) { - if (input && input.type == "variable" && input.variableId == _this.props.block.getRowContextVarId()) { + queryOptions = mapObject(queryOptions, (input) => { + if (input && input.type == "variable" && input.variableId == this.props.block.getRowContextVarId()) { return { type: "id", table: queryOptions.from }; } return input; }); return queryOptions; - }; - QueryTableBlockInstance.prototype.performQuery = function () { - var _this = this; - var queryOptions = this.createQuery(); + } + performQuery() { + const queryOptions = this.createQuery(); this.queryOptions = queryOptions; // Mark as refreshing this.setState({ refreshing: true }); - this.props.instanceCtx.database.query(queryOptions, this.props.instanceCtx.contextVars, contexts_1.getFilteredContextVarValues(this.props.instanceCtx)).then(function (rows) { + this.props.instanceCtx.database.query(queryOptions, this.props.instanceCtx.contextVars, contexts_1.getFilteredContextVarValues(this.props.instanceCtx)).then(rows => { // Check if still relevant - if (_.isEqual(queryOptions, _this.createQuery())) { + if (_.isEqual(queryOptions, this.createQuery())) { // Take limit of rows - var limitedRows = _this.state.limit != null ? _.take(rows, _this.state.limit) : rows; - _this.setState({ + const limitedRows = this.state.limit != null ? _.take(rows, this.state.limit) : rows; + this.setState({ rows: limitedRows, refreshing: false, // If soft limit and more available, show that - moreRowsAvail: (_this.props.block.blockDef.limitType || "soft") == "soft" && rows.length > limitedRows.length + moreRowsAvail: (this.props.block.blockDef.limitType || "soft") == "soft" && rows.length > limitedRows.length }); } - }).catch(function (error) { - _this.setState({ error: error }); + }).catch(error => { + this.setState({ error: error }); }); - }; - QueryTableBlockInstance.prototype.createRowInstanceCtx = function (rowIndex) { - var _a; - var _this = this; - var rips = this.props.instanceCtx; + } + createRowInstanceCtx(rowIndex) { + const rips = this.props.instanceCtx; // Row context variable - var rowsetCV = this.props.instanceCtx.contextVars.find(function (cv) { return cv.id === _this.props.block.blockDef.rowsetContextVarId; }); - var rowcv = this.props.block.createRowContextVar(rowsetCV); + const rowsetCV = this.props.instanceCtx.contextVars.find(cv => cv.id === this.props.block.blockDef.rowsetContextVarId); + const rowcv = this.props.block.createRowContextVar(rowsetCV); // TODO move out of here to be faster - var rowExprs = this.props.block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); - var innerContextVars = rips.contextVars.concat(rowcv); + const rowExprs = this.props.block.getRowExprs(this.props.instanceCtx.contextVars, this.props.instanceCtx); + const innerContextVars = rips.contextVars.concat(rowcv); // Row context variable value - var cvvalue = this.props.block.getRowContextVarValue(this.state.rows[rowIndex], rowExprs, this.props.instanceCtx.schema, rowsetCV, innerContextVars, contexts_1.getFilteredContextVarValues(this.props.instanceCtx)[rowsetCV.id]); - var innerContextVarValues = __assign(__assign({}, rips.contextVarValues), (_a = {}, _a[rowcv.id] = cvvalue, _a)); - return __assign(__assign({}, rips), { contextVars: innerContextVars, contextVarValues: innerContextVarValues, getContextVarExprValue: function (cvid, expr) { + const cvvalue = this.props.block.getRowContextVarValue(this.state.rows[rowIndex], rowExprs, this.props.instanceCtx.schema, rowsetCV, innerContextVars, contexts_1.getFilteredContextVarValues(this.props.instanceCtx)[rowsetCV.id]); + const innerContextVarValues = Object.assign(Object.assign({}, rips.contextVarValues), { [rowcv.id]: cvvalue }); + return Object.assign(Object.assign({}, rips), { contextVars: innerContextVars, contextVarValues: innerContextVarValues, getContextVarExprValue: (cvid, expr) => { // Null expression has null value if (!expr) { return null; @@ -208,50 +178,48 @@ var QueryTableBlockInstance = /** @class */ (function (_super) { return rips.getContextVarExprValue(cvid, expr); } // Look up expression - var exprIndex = rowExprs.findIndex(function (rowExpr) { return _.isEqual(expr, rowExpr); }); - return _this.state.rows[rowIndex]["e" + exprIndex]; - }, getFilters: function (cvid) { + const exprIndex = rowExprs.findIndex(rowExpr => _.isEqual(expr, rowExpr)); + return this.state.rows[rowIndex]["e" + exprIndex]; + }, getFilters: (cvid) => { // If this creates a rowset, it has no filters as it can't be filtered if (cvid == rowcv.id) { return []; } return rips.getFilters(cvid); - }, setFilter: function (cvid, filter) { + }, setFilter: (cvid, filter) => { // Can't set filter for rowset if (cvid == rowcv.id) { throw new Error("Can't set filter for query table rowset"); } rips.setFilter(cvid, filter); } }); - }; - QueryTableBlockInstance.prototype.renderRow = function (row, rowIndex) { - var _this = this; - var rowRIProps = this.createRowInstanceCtx(rowIndex); - var handleRowClick = function () { + } + renderRow(row, rowIndex) { + const rowRIProps = this.createRowInstanceCtx(rowIndex); + const handleRowClick = () => { // Run action - if (_this.props.block.blockDef.rowClickAction) { - var actionDef = _this.props.block.blockDef.rowClickAction; - var action = _this.props.instanceCtx.actionLibrary.createAction(actionDef); - action.performAction(__assign({}, rowRIProps)); + if (this.props.block.blockDef.rowClickAction) { + const actionDef = this.props.block.blockDef.rowClickAction; + const action = this.props.instanceCtx.actionLibrary.createAction(actionDef); + action.performAction(Object.assign({}, rowRIProps)); } }; // Use row id if possible, otherwise just the index - var rowKey = this.props.block.blockDef.mode == "singleRow" ? row.id : rowIndex; + const rowKey = this.props.block.blockDef.mode == "singleRow" ? row.id : rowIndex; // Show pointer if works on click - var rowStyle = {}; + const rowStyle = {}; if (this.props.block.blockDef.rowClickAction) { rowStyle.cursor = "pointer"; } - var getColumnVerticalAlign = function (colIndex) { - var columnInfos = _this.props.block.blockDef.columnInfos; + const getColumnVerticalAlign = (colIndex) => { + const columnInfos = this.props.block.blockDef.columnInfos; return columnInfos && columnInfos[colIndex] ? columnInfos[colIndex].verticalAlign || "top" : "top"; }; - return (React.createElement("tr", { key: rowKey, style: rowStyle }, this.props.block.blockDef.contents.map(function (b, colIndex) { + return (React.createElement("tr", { key: rowKey, style: rowStyle }, this.props.block.blockDef.contents.map((b, colIndex) => { return (React.createElement("td", { key: colIndex, onClick: handleRowClick, style: { verticalAlign: getColumnVerticalAlign(colIndex) } }, rowRIProps.renderChildBlock(rowRIProps, b))); }))); - }; - QueryTableBlockInstance.prototype.renderRows = function () { - var _this = this; + } + renderRows() { if (this.state.error) { // TODO localize return (React.createElement("tr", { key: "error" }, @@ -267,55 +235,53 @@ var QueryTableBlockInstance = /** @class */ (function (_super) { return (React.createElement("tr", { key: "norows" }, React.createElement("td", { key: "norows", colSpan: this.props.block.blockDef.contents.length, style: { fontStyle: "italic" } }, localization_1.localize(this.props.block.blockDef.noRowsMessage, this.props.instanceCtx.locale)))); } - return this.state.rows.map(function (row, rowIndex) { return _this.renderRow(row, rowIndex); }); - }; + return this.state.rows.map((row, rowIndex) => this.renderRow(row, rowIndex)); + } /** Render one header of the table */ - QueryTableBlockInstance.prototype.renderHeader = function (header, index) { - var _this = this; - var riProps = this.props.instanceCtx; - var blockDef = this.props.block.blockDef; - var renderOrder = function () { + renderHeader(header, index) { + const riProps = this.props.instanceCtx; + const blockDef = this.props.block.blockDef; + const renderOrder = () => { if (!blockDef.columnInfos || !blockDef.columnInfos[index] || !blockDef.columnInfos[index].orderExpr) { return null; } - var handleOrderClick = function () { + const handleOrderClick = () => { // Get current order - var currentOrder = _this.state.columnOrderIndex == index ? _this.state.columnOrderDir : null; + const currentOrder = this.state.columnOrderIndex == index ? this.state.columnOrderDir : null; if (currentOrder == "asc") { - _this.setState({ columnOrderDir: "desc" }); + this.setState({ columnOrderDir: "desc" }); } else if (currentOrder == "desc") { - _this.setState({ columnOrderIndex: null }); + this.setState({ columnOrderIndex: null }); } else { - _this.setState({ columnOrderDir: "asc", columnOrderIndex: index }); + this.setState({ columnOrderDir: "asc", columnOrderIndex: index }); } }; // If not sorted - if (_this.state.columnOrderIndex != index) { + if (this.state.columnOrderIndex != index) { return React.createElement("div", { key: "order", style: { float: "right", color: "#CCC", cursor: "pointer" }, onClick: handleOrderClick }, React.createElement("i", { className: "fa fa-sort fa-fw" })); } - return React.createElement("div", { key: "order", style: { float: "right", cursor: "pointer" }, onClick: handleOrderClick }, _this.state.columnOrderDir == "asc" ? React.createElement("i", { className: "fa fa-sort-asc fa-fw" }) : React.createElement("i", { className: "fa fa-sort-desc fa-fw" })); + return React.createElement("div", { key: "order", style: { float: "right", cursor: "pointer" }, onClick: handleOrderClick }, this.state.columnOrderDir == "asc" ? React.createElement("i", { className: "fa fa-sort-asc fa-fw" }) : React.createElement("i", { className: "fa fa-sort-desc fa-fw" })); }; return React.createElement("th", { key: index }, renderOrder(), riProps.renderChildBlock(riProps, header)); - }; + } /** Render the show more rows at bottom */ - QueryTableBlockInstance.prototype.renderShowMore = function () { + renderShowMore() { if (!this.state.moreRowsAvail) { return null; } return React.createElement("tr", { key: "showMore" }, React.createElement("td", { colSpan: this.props.block.blockDef.contents.length }, React.createElement("a", { style: { cursor: "pointer" }, onClick: this.handleShowMore }, this.props.instanceCtx.T("Show more...")))); - }; - QueryTableBlockInstance.prototype.render = function () { - var _this = this; - var blockDef = this.props.block.blockDef; - var divStyle = {}; - var tableStyle = { + } + render() { + const blockDef = this.props.block.blockDef; + const divStyle = {}; + const tableStyle = { marginTop: 5, }; if (queryTable_1.getFixedWidth(this.props.block.blockDef)) { @@ -326,7 +292,7 @@ var QueryTableBlockInstance = /** @class */ (function (_super) { if (this.state.refreshing) { tableStyle.opacity = 0.6; } - var className = "table"; + let className = "table"; switch (blockDef.borders || "horizontal") { case "all": className += " table-bordered"; @@ -349,40 +315,39 @@ var QueryTableBlockInstance = /** @class */ (function (_super) { } return (React.createElement("div", { style: divStyle }, React.createElement("table", { className: className, style: tableStyle }, - React.createElement("colgroup", null, blockDef.contents.map(function (b, colIndex) { + React.createElement("colgroup", null, blockDef.contents.map((b, colIndex) => { // Determine width - var columnInfos = blockDef.columnInfos; - var width = columnInfos && columnInfos[colIndex] ? columnInfos[colIndex].columnWidth || "auto" : "auto"; + const columnInfos = blockDef.columnInfos; + const width = columnInfos && columnInfos[colIndex] ? columnInfos[colIndex].columnWidth || "auto" : "auto"; return React.createElement("col", { key: colIndex, style: { width: width } }); })), !blockDef.hideHeaders ? React.createElement("thead", null, - React.createElement("tr", { key: "header" }, blockDef.headers.map(function (b, index) { return _this.renderHeader(b, index); }))) + React.createElement("tr", { key: "header" }, blockDef.headers.map((b, index) => this.renderHeader(b, index)))) : null, React.createElement("tbody", null, this.renderRows(), this.renderShowMore()), blockDef.footers ? React.createElement("tfoot", null, - React.createElement("tr", null, blockDef.footers.map(function (b, index) { return React.createElement("td", { key: index }, _this.props.instanceCtx.renderChildBlock(_this.props.instanceCtx, b)); }))) + React.createElement("tr", null, blockDef.footers.map((b, index) => React.createElement("td", { key: index }, this.props.instanceCtx.renderChildBlock(this.props.instanceCtx, b))))) : null))); - }; - return QueryTableBlockInstance; -}(React.Component)); + } +} exports.default = QueryTableBlockInstance; /** Replace every part of an object, including array members * replacer should return input to leave unchanged */ -var mapObject = function (obj, replacer) { +const mapObject = (obj, replacer) => { obj = replacer(obj); if (!obj) { return obj; } if (_.isArray(obj)) { - return _.map(obj, function (item) { return mapObject(item, replacer); }); + return _.map(obj, (item) => mapObject(item, replacer)); } if (_.isObject(obj)) { - return _.mapValues(obj, function (item) { return mapObject(item, replacer); }); + return _.mapValues(obj, (item) => mapObject(item, replacer)); } return obj; }; diff --git a/lib/widgets/blocks/queryTable/QueryTableBlockInstance.test.js b/lib/widgets/blocks/queryTable/QueryTableBlockInstance.test.js index 1bc3a50b..b9102feb 100644 --- a/lib/widgets/blocks/queryTable/QueryTableBlockInstance.test.js +++ b/lib/widgets/blocks/queryTable/QueryTableBlockInstance.test.js @@ -1,15 +1,4 @@ "use strict"; -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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,19 +22,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var enzyme_1 = require("enzyme"); -var React = __importStar(require("react")); -var queryTable_1 = require("./queryTable"); -var QueryTableBlockInstance_1 = __importDefault(require("./QueryTableBlockInstance")); -var schema_1 = __importDefault(require("../../../__fixtures__/schema")); -var BlockFactory_1 = __importDefault(require("../../BlockFactory")); -var mockDatabase_1 = __importDefault(require("../../../__fixtures__/mockDatabase")); +const enzyme_1 = require("enzyme"); +const React = __importStar(require("react")); +const queryTable_1 = require("./queryTable"); +const QueryTableBlockInstance_1 = __importDefault(require("./QueryTableBlockInstance")); +const schema_1 = __importDefault(require("../../../__fixtures__/schema")); +const BlockFactory_1 = __importDefault(require("../../BlockFactory")); +const mockDatabase_1 = __importDefault(require("../../../__fixtures__/mockDatabase")); // Outer context vars -var rowsetCV = { id: "cv1", type: "rowset", name: "", table: "t1" }; -var contextVars = [rowsetCV]; -var schema = schema_1.default(); -var exprText = { type: "field", table: "t1", column: "text" }; -var qtbdSingle = { +const rowsetCV = { id: "cv1", type: "rowset", name: "", table: "t1" }; +const contextVars = [rowsetCV]; +const schema = schema_1.default(); +const exprText = { type: "field", table: "t1", column: "text" }; +const qtbdSingle = { id: "123", type: "queryTable", mode: "singleRow", @@ -57,11 +46,11 @@ var qtbdSingle = { where: null, rowClickAction: null }; -var createBlock = new BlockFactory_1.default().createBlock; -var qtbSingle = new queryTable_1.QueryTableBlock(qtbdSingle); -var rips; -var database; -beforeEach(function () { +const createBlock = new BlockFactory_1.default().createBlock; +const qtbSingle = new queryTable_1.QueryTableBlock(qtbdSingle); +let rips; +let database; +beforeEach(() => { database = mockDatabase_1.default(); rips = { createBlock: createBlock, @@ -72,7 +61,7 @@ beforeEach(function () { pageStack: {}, // Simple filter contextVarValues: { cv1: { type: "field", table: "t1", column: "boolean" } }, - getFilters: function () { return []; }, + getFilters: () => [], setFilter: jest.fn(), locale: "en", onSelectContextVar: jest.fn(), @@ -80,15 +69,15 @@ beforeEach(function () { dataSource: {}, renderChildBlock: jest.fn(), widgetLibrary: { widgets: {} }, - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => () => { }, + T: (str) => str }; }); // single: -test("creates query", function () { +test("creates query", () => { database.query.mockResolvedValue([]); - var inst = enzyme_1.mount(React.createElement(QueryTableBlockInstance_1.default, { block: qtbSingle, instanceCtx: rips })); - var queryOptions = database.query.mock.calls[0][0]; + const inst = enzyme_1.mount(React.createElement(QueryTableBlockInstance_1.default, { block: qtbSingle, instanceCtx: rips })); + const queryOptions = database.query.mock.calls[0][0]; expect(queryOptions).toEqual({ select: { id: { type: "id", table: "t1" }, @@ -105,14 +94,14 @@ test("creates query", function () { limit: 11 }); }); -test("adds filters, orderBy and where", function () { +test("adds filters, orderBy and where", () => { database.query.mockResolvedValue([]); - rips.getFilters = function () { return [{ id: "f1", expr: { type: "literal", valueType: "boolean", value: true } }]; }; - var qtb = createBlock(__assign(__assign({}, qtbdSingle), { where: { type: "literal", valueType: "boolean", value: false }, orderBy: [ + rips.getFilters = () => [{ id: "f1", expr: { type: "literal", valueType: "boolean", value: true } }]; + const qtb = createBlock(Object.assign(Object.assign({}, qtbdSingle), { where: { type: "literal", valueType: "boolean", value: false }, orderBy: [ { expr: { type: "field", table: "t1", column: "number" }, dir: "desc" } ] })); - var inst = enzyme_1.mount(React.createElement(QueryTableBlockInstance_1.default, { block: qtb, instanceCtx: rips })); - var queryOptions = database.query.mock.calls[0][0]; + const inst = enzyme_1.mount(React.createElement(QueryTableBlockInstance_1.default, { block: qtb, instanceCtx: rips })); + const queryOptions = database.query.mock.calls[0][0]; expect(queryOptions).toEqual({ select: { id: { type: "id", table: "t1" }, @@ -136,11 +125,11 @@ test("adds filters, orderBy and where", function () { limit: 11 }); }); -test("injects context variables", function () { +test("injects context variables", () => { database.query.mockResolvedValue([]); - var inst = enzyme_1.mount(React.createElement(QueryTableBlockInstance_1.default, { block: qtbSingle, instanceCtx: rips })); + const inst = enzyme_1.mount(React.createElement(QueryTableBlockInstance_1.default, { block: qtbSingle, instanceCtx: rips })); inst.setState({ rows: [{ id: "r1", e0: "abc" }] }); - var rowRips = inst.instance().createRowInstanceCtx(0); + const rowRips = inst.instance().createRowInstanceCtx(0); expect(rowRips.contextVarValues["123_row"]).toBe("r1"); expect(rowRips.getContextVarExprValue("123_row", exprText)).toBe("abc"); }); diff --git a/lib/widgets/blocks/queryTable/queryTable.js b/lib/widgets/blocks/queryTable/queryTable.js index f088a0f4..011011e4 100644 --- a/lib/widgets/blocks/queryTable/queryTable.js +++ b/lib/widgets/blocks/queryTable/queryTable.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,47 +23,40 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFixedWidth = exports.QueryTableBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var _ = __importStar(require("lodash")); -var blocks_1 = require("../../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var QueryTableBlockInstance_1 = __importDefault(require("./QueryTableBlockInstance")); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var uuid_1 = __importDefault(require("uuid")); -var QueryTableBlock = /** @class */ (function (_super) { - __extends(QueryTableBlock, _super); - function QueryTableBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - QueryTableBlock.prototype.getChildren = function (contextVars) { - var _this = this; +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const _ = __importStar(require("lodash")); +const blocks_1 = require("../../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const QueryTableBlockInstance_1 = __importDefault(require("./QueryTableBlockInstance")); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const uuid_1 = __importDefault(require("uuid")); +class QueryTableBlock extends blocks_1.Block { + getChildren(contextVars) { // Get rowset context variable - var rowsetCV = contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var headerChildren = _.compact(this.blockDef.headers).map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - var contentChildren = _.compact(this.blockDef.contents).map(function (bd) { return ({ blockDef: bd, contextVars: rowsetCV ? contextVars.concat(_this.createRowContextVar(rowsetCV)) : contextVars }); }); - var footerChildren = _.compact(this.blockDef.footers || []).map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); + const rowsetCV = contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const headerChildren = _.compact(this.blockDef.headers).map(bd => ({ blockDef: bd, contextVars: contextVars })); + const contentChildren = _.compact(this.blockDef.contents).map(bd => ({ blockDef: bd, contextVars: rowsetCV ? contextVars.concat(this.createRowContextVar(rowsetCV)) : contextVars })); + const footerChildren = _.compact(this.blockDef.footers || []).map(bd => ({ blockDef: bd, contextVars: contextVars })); return headerChildren.concat(contentChildren).concat(footerChildren); - }; - QueryTableBlock.prototype.validate = function (designCtx) { - var _this = this; + } + validate(designCtx) { // Validate rowset - var rowsetCV = designCtx.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + const rowsetCV = designCtx.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return "Rowset required"; } - var exprValidator = new mwater_expressions_1.ExprValidator(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); - var error; + const exprValidator = new mwater_expressions_1.ExprValidator(designCtx.schema, blocks_1.createExprVariables(designCtx.contextVars)); + let error; // Validate where error = exprValidator.validateExpr(this.blockDef.where, { table: rowsetCV.table, types: ["boolean"] }); if (error) { return error; } // Validate orderBy - for (var _i = 0, _a = this.blockDef.orderBy || []; _i < _a.length; _i++) { - var orderBy = _a[_i]; + for (const orderBy of this.blockDef.orderBy || []) { error = exprValidator.validateExpr(orderBy.expr, { table: rowsetCV.table }); if (error) { return error; @@ -95,125 +64,122 @@ var QueryTableBlock = /** @class */ (function (_super) { } // Validate action if (this.blockDef.rowClickAction) { - var action = designCtx.actionLibrary.createAction(this.blockDef.rowClickAction); + const action = designCtx.actionLibrary.createAction(this.blockDef.rowClickAction); // Create row context variable - var rowCV = this.createRowContextVar(rowsetCV); - error = action.validate(__assign(__assign({}, designCtx), { contextVars: designCtx.contextVars.concat(rowCV) })); + const rowCV = this.createRowContextVar(rowsetCV); + error = action.validate(Object.assign(Object.assign({}, designCtx), { contextVars: designCtx.contextVars.concat(rowCV) })); if (error) { return error; } } return null; - }; - QueryTableBlock.prototype.processChildren = function (action) { - var headers = this.blockDef.headers.map(function (b) { return action(b); }); - var contents = this.blockDef.contents.map(function (b) { return action(b); }); - var footers = this.blockDef.footers ? this.blockDef.footers.map(function (b) { return action(b); }) : undefined; - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const headers = this.blockDef.headers.map(b => action(b)); + const contents = this.blockDef.contents.map(b => action(b)); + const footers = this.blockDef.footers ? this.blockDef.footers.map(b => action(b)) : undefined; + return immer_1.default(this.blockDef, draft => { draft.headers = headers; draft.contents = contents; draft.footers = footers; }); - }; + } /** Create the context variable used */ - QueryTableBlock.prototype.createRowContextVar = function (rowsetCV) { + createRowContextVar(rowsetCV) { switch (this.blockDef.mode) { case "singleRow": - return { id: this.getRowContextVarId(), name: "Table row of " + rowsetCV.name, type: "row", table: rowsetCV.table }; + return { id: this.getRowContextVarId(), name: `Table row of ${rowsetCV.name}`, type: "row", table: rowsetCV.table }; case "multiRow": - return { id: this.getRowContextVarId(), name: "Table row rowset of " + rowsetCV.name, type: "rowset", table: rowsetCV.table }; + return { id: this.getRowContextVarId(), name: `Table row rowset of ${rowsetCV.name}`, type: "rowset", table: rowsetCV.table }; } throw new Error("Unknown mode"); - }; - QueryTableBlock.prototype.getRowContextVarId = function () { + } + getRowContextVarId() { switch (this.blockDef.mode) { case "singleRow": return this.blockDef.id + "_row"; case "multiRow": return this.blockDef.id + "_rowset"; } - }; + } /** Get list of expressions used in a row by content blocks */ - QueryTableBlock.prototype.getRowExprs = function (contextVars, ctx) { - var _this = this; - var rowsetCV = contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + getRowExprs(contextVars, ctx) { + const rowsetCV = contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return []; } - var exprs = []; - var rowCV = this.createRowContextVar(rowsetCV); + let exprs = []; + const rowCV = this.createRowContextVar(rowsetCV); // Get expressions for all content blocks - for (var _i = 0, _a = this.blockDef.contents; _i < _a.length; _i++) { - var contentBlockDef = _a[_i]; + for (const contentBlockDef of this.blockDef.contents) { if (contentBlockDef) { - exprs = exprs.concat(ctx.createBlock(contentBlockDef).getSubtreeContextVarExprs(rowCV, __assign(__assign({}, ctx), { contextVars: contextVars.concat([rowCV]) }))); + exprs = exprs.concat(ctx.createBlock(contentBlockDef).getSubtreeContextVarExprs(rowCV, Object.assign(Object.assign({}, ctx), { contextVars: contextVars.concat([rowCV]) }))); } } return exprs; - }; + } /** * Get the value of the row context variable for a specific row. * Row should have fields e0, e1, etc. to represent expressions. If singleRow mode, should have id field * contextVars: includes rowsetCV and row one */ - QueryTableBlock.prototype.getRowContextVarValue = function (row, rowExprs, schema, rowsetCV, contextVars, rowsetContextVarValue) { + getRowContextVarValue(row, rowExprs, schema, rowsetCV, contextVars, rowsetContextVarValue) { switch (this.blockDef.mode) { case "singleRow": return row.id; case "multiRow": - var exprUtils_1 = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)); + const exprUtils = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)); // Create "and" filter - var ands_1 = []; + const ands = []; // Add overall rowset filter if (rowsetContextVarValue) { - ands_1.push(rowsetContextVarValue); + ands.push(rowsetContextVarValue); } - rowExprs.forEach(function (expr, index) { - if (exprUtils_1.getExprAggrStatus(expr) === "individual") { - ands_1.push({ + rowExprs.forEach((expr, index) => { + if (exprUtils.getExprAggrStatus(expr) === "individual") { + ands.push({ type: "op", op: "=", table: rowsetCV.table, exprs: [ expr, - { type: "literal", valueType: exprUtils_1.getExprType(expr), value: row["e" + index] } + { type: "literal", valueType: exprUtils.getExprType(expr), value: row["e" + index] } ] }); } }); - return (ands_1.length > 0) ? { type: "op", op: "and", table: rowsetCV.table, exprs: ands_1 } : null; + return (ands.length > 0) ? { type: "op", op: "and", table: rowsetCV.table, exprs: ands } : null; } - }; - QueryTableBlock.prototype.renderDesign = function (props) { - var _this = this; - var setHeader = function (index, blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const setHeader = (index, blockDef) => { + props.store.alterBlock(this.id, immer_1.default(b => { b.headers[index] = blockDef; }), blockDef.id); }; - var setContent = function (index, blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const setContent = (index, blockDef) => { + props.store.alterBlock(this.id, immer_1.default(b => { b.contents[index] = blockDef; }), blockDef.id); }; - var setFooter = function (index, blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + const setFooter = (index, blockDef) => { + props.store.alterBlock(this.id, immer_1.default(b => { b.footers[index] = blockDef; }), blockDef.id); }; - var rowsetCV = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); - var contentProps = props; + const rowsetCV = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); + let contentProps = props; // Add context variable if knowable if (rowsetCV) { - contentProps = __assign(__assign({}, contentProps), { contextVars: props.contextVars.concat([this.createRowContextVar(rowsetCV)]) }); + contentProps = Object.assign(Object.assign({}, contentProps), { contextVars: props.contextVars.concat([this.createRowContextVar(rowsetCV)]) }); } - var divStyle = {}; - var tableStyle = {}; + const divStyle = {}; + const tableStyle = {}; if (getFixedWidth(this.blockDef)) { tableStyle.width = getFixedWidth(this.blockDef); divStyle.overflowX = "auto"; } - var className = "table"; + let className = "table"; switch (this.blockDef.borders || "horizontal") { case "all": className += " table-bordered"; @@ -230,121 +196,114 @@ var QueryTableBlock = /** @class */ (function (_super) { if (this.blockDef.striped) { className += " table-striped"; } - var getColumnVerticalAlign = function (colIndex) { - var columnInfos = _this.blockDef.columnInfos; + const getColumnVerticalAlign = (colIndex) => { + const columnInfos = this.blockDef.columnInfos; return columnInfos && columnInfos[colIndex] ? columnInfos[colIndex].verticalAlign || "top" : "top"; }; return (React.createElement("div", { style: divStyle }, React.createElement("table", { className: className, style: tableStyle }, - React.createElement("colgroup", null, this.blockDef.contents.map(function (b, colIndex) { + React.createElement("colgroup", null, this.blockDef.contents.map((b, colIndex) => { // Determine width - var columnInfos = _this.blockDef.columnInfos; - var width = columnInfos && columnInfos[colIndex] ? columnInfos[colIndex].columnWidth || "auto" : "auto"; + const columnInfos = this.blockDef.columnInfos; + const width = columnInfos && columnInfos[colIndex] ? columnInfos[colIndex].columnWidth || "auto" : "auto"; return React.createElement("col", { key: colIndex, style: { width: width } }); })), !this.blockDef.hideHeaders ? React.createElement("thead", null, - React.createElement("tr", { key: "header" }, this.blockDef.headers.map(function (b, index) { + React.createElement("tr", { key: "header" }, this.blockDef.headers.map((b, index) => { return React.createElement("th", { key: index }, props.renderChildBlock(props, b, setHeader.bind(null, index))); }))) : null, React.createElement("tbody", null, - React.createElement("tr", { key: "child" }, this.blockDef.contents.map(function (b, index) { + React.createElement("tr", { key: "child" }, this.blockDef.contents.map((b, index) => { return React.createElement("td", { key: index, style: { verticalAlign: getColumnVerticalAlign(index) } }, props.renderChildBlock(contentProps, b, setContent.bind(null, index))); }))), this.blockDef.footers ? React.createElement("tfoot", null, - React.createElement("tr", { key: "footer" }, this.blockDef.footers.map(function (b, index) { + React.createElement("tr", { key: "footer" }, this.blockDef.footers.map((b, index) => { return React.createElement("td", { key: index }, props.renderChildBlock(props, b, setFooter.bind(null, index))); }))) : null))); - }; - QueryTableBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement(QueryTableBlockInstance_1.default, { block: this, instanceCtx: props }); - }; - QueryTableBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { // Get rowset context variable - var rowsetCV = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); - var rowCV = rowsetCV ? this.createRowContextVar(rowsetCV) : null; - var handleAddColumn = function () { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (b) { - setLength(b.contents, _this.blockDef.contents.length + 1); - setLength(b.headers, _this.blockDef.contents.length + 1); + const rowsetCV = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); + const rowCV = rowsetCV ? this.createRowContextVar(rowsetCV) : null; + const handleAddColumn = () => { + props.store.replaceBlock(immer_1.default(this.blockDef, b => { + setLength(b.contents, this.blockDef.contents.length + 1); + setLength(b.headers, this.blockDef.contents.length + 1); if (b.footers) { - setLength(b.footers, _this.blockDef.contents.length + 1); + setLength(b.footers, this.blockDef.contents.length + 1); } b.headers[b.headers.length - 1] = { id: uuid_1.default.v4(), type: "text", text: { _base: "en", en: "Header" }, style: "div" }; b.columnInfos = b.columnInfos || []; - setLength(b.columnInfos, _this.blockDef.contents.length + 1); + setLength(b.columnInfos, this.blockDef.contents.length + 1); })); }; // Remove last column - var handleRemoveColumn = function () { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (b) { + const handleRemoveColumn = () => { + props.store.replaceBlock(immer_1.default(this.blockDef, b => { if (b.contents.length > 1) { - setLength(b.contents, _this.blockDef.contents.length - 1); - setLength(b.headers, _this.blockDef.contents.length - 1); + setLength(b.contents, this.blockDef.contents.length - 1); + setLength(b.headers, this.blockDef.contents.length - 1); if (b.footers) { - setLength(b.footers, _this.blockDef.contents.length - 1); + setLength(b.footers, this.blockDef.contents.length - 1); } b.columnInfos = b.columnInfos || []; - setLength(b.columnInfos, _this.blockDef.contents.length - 1); + setLength(b.columnInfos, this.blockDef.contents.length - 1); } })); }; - var handleAddFooters = function () { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (b) { + const handleAddFooters = () => { + props.store.replaceBlock(immer_1.default(this.blockDef, b => { b.footers = []; - setLength(b.footers, _this.blockDef.contents.length); + setLength(b.footers, this.blockDef.contents.length); })); }; - var handleRemoveFooters = function () { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (b) { + const handleRemoveFooters = () => { + props.store.replaceBlock(immer_1.default(this.blockDef, b => { delete b.footers; })); }; return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Mode" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "mode" }, function (value, onChange) { return React.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [{ value: "singleRow", label: "One item per row" }, { value: "multiRow", label: "Multiple item per row" }] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "mode" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value, onChange: onChange, options: [{ value: "singleRow", label: "One item per row" }, { value: "multiRow", label: "Multiple item per row" }] }))), rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "where" }, function (value, onChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["boolean"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "where" }, (value, onChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, types: ["boolean"], variables: blocks_1.createExprVariables(props.contextVars), table: rowsetCV.table })))) : null, rowCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Ordering" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "orderBy" }, function (value, onChange) { - return React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: rowsetCV.table }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "orderBy" }, (value, onChange) => React.createElement(propertyEditors_1.OrderByArrayEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: rowsetCV.table }))) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Maximum rows" }, React.createElement("div", null, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "limit" }, function (value, onChange) { - return React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: false, style: { display: "inline-block" } }); - }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "limit" }, (value, onChange) => React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: false, style: { display: "inline-block" } })), this.blockDef.limit != null ? - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "limitType" }, function (value, onChange) { - return React.createElement("div", { style: { paddingLeft: 10, display: "inline-block" } }, - React.createElement(bootstrap_1.Checkbox, { value: value != "hard", onChange: function (v) { return onChange(v !== false ? "soft" : "hard"); } }, "Enable 'Show More...'")); - }) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "limitType" }, (value, onChange) => React.createElement("div", { style: { paddingLeft: 10, display: "inline-block" } }, + React.createElement(bootstrap_1.Checkbox, { value: value != "hard", onChange: v => onChange(v !== false ? "soft" : "hard") }, "Enable 'Show More...'"))) : null)), rowCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "When row clicked" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowClickAction" }, function (value, onChange) { return (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: __assign(__assign({}, props), { contextVars: props.contextVars.concat(rowCV) }) })); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowClickAction" }, (value, onChange) => (React.createElement(propertyEditors_1.ActionDefEditor, { value: value, onChange: onChange, designCtx: Object.assign(Object.assign({}, props), { contextVars: props.contextVars.concat(rowCV) }) })))) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Message to display when no rows" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "noRowsMessage" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "hideHeaders" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Hide Headers"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "noRowsMessage" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "hideHeaders" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Hide Headers")), React.createElement(propertyEditors_1.LabeledProperty, { label: "Borders" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "borders" }, function (value, onChange) { return React.createElement(bootstrap_1.Toggle, { value: value || "horizontal", onChange: onChange, options: [{ value: "none", label: "None" }, { value: "horizontal", label: "Horizontal" }, { value: "all", label: "All" }] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "borders" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "horizontal", onChange: onChange, options: [{ value: "none", label: "None" }, { value: "horizontal", label: "Horizontal" }, { value: "all", label: "All" }] }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Padding" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "padding" }, function (value, onChange) { return React.createElement(bootstrap_1.Toggle, { value: value || "normal", onChange: onChange, options: [{ value: "normal", label: "Normal" }, { value: "compact", label: "Compact" }] }); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "striped" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Striped"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "padding" }, (value, onChange) => React.createElement(bootstrap_1.Toggle, { value: value || "normal", onChange: onChange, options: [{ value: "normal", label: "Normal" }, { value: "compact", label: "Compact" }] }))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "striped" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Striped")), rowCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Columns" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columnInfos" }, function (value, onChange) { return React.createElement(ColumnInfosEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: rowCV.table, numColumns: _this.blockDef.contents.length, variables: blocks_1.createExprVariables(props.contextVars) }); })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "columnInfos" }, (value, onChange) => React.createElement(ColumnInfosEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: rowCV.table, numColumns: this.blockDef.contents.length, variables: blocks_1.createExprVariables(props.contextVars) }))) : null, React.createElement("div", null, React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddColumn }, @@ -357,41 +316,40 @@ var QueryTableBlock = /** @class */ (function (_super) { React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleRemoveFooters }, "Remove Footer") : React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddFooters }, "Add Footer"))); - }; - return QueryTableBlock; -}(blocks_1.Block)); + } +} exports.QueryTableBlock = QueryTableBlock; /** Edits column info */ -var ColumnInfosEditor = function (props) { - var handleOrderExprChange = function (colIndex, expr) { - props.onChange(immer_1.default(props.value || [], function (draft) { +const ColumnInfosEditor = (props) => { + const handleOrderExprChange = (colIndex, expr) => { + props.onChange(immer_1.default(props.value || [], draft => { // Make sure exists draft[colIndex] = draft[colIndex] || { orderExpr: null, initialOrderDir: null }; draft[colIndex].orderExpr = expr; })); }; - var handleInitialOrderDirChange = function (colIndex, initialOrderDir) { - props.onChange(immer_1.default(props.value || [], function (draft) { + const handleInitialOrderDirChange = (colIndex, initialOrderDir) => { + props.onChange(immer_1.default(props.value || [], draft => { // Make sure exists draft[colIndex] = draft[colIndex] || { orderExpr: null, initialOrderDir: null }; draft[colIndex].initialOrderDir = initialOrderDir; })); }; - var handleColumnWidthChange = function (colIndex, columnWidth) { - props.onChange(immer_1.default(props.value || [], function (draft) { + const handleColumnWidthChange = (colIndex, columnWidth) => { + props.onChange(immer_1.default(props.value || [], draft => { // Make sure exists draft[colIndex] = draft[colIndex] || { orderExpr: null, initialOrderDir: null }; draft[colIndex].columnWidth = columnWidth; })); }; - var handleVerticalAlignChange = function (colIndex, verticalAlign) { - props.onChange(immer_1.default(props.value || [], function (draft) { + const handleVerticalAlignChange = (colIndex, verticalAlign) => { + props.onChange(immer_1.default(props.value || [], draft => { // Make sure exists draft[colIndex] = draft[colIndex] || { orderExpr: null, initialOrderDir: null }; draft[colIndex].verticalAlign = verticalAlign; })); }; - return React.createElement("ul", { className: "list-group" }, _.map(_.range(props.numColumns), function (colIndex) { + return React.createElement("ul", { className: "list-group" }, _.map(_.range(props.numColumns), colIndex => { return React.createElement("li", { className: "list-group-item", key: colIndex }, React.createElement(propertyEditors_1.LabeledProperty, { label: "Sort Icons", hint: "Allow dynamic sorting if present", key: "sort" }, React.createElement("div", { style: { display: "inline-block", paddingLeft: 5, paddingRight: 10 } }, @@ -416,16 +374,16 @@ function setLength(arr, length) { arr.splice(length, arr.length - length); } if (arr.length < length) { - var toAdd = length - arr.length; - for (var i = 0; i < toAdd; i++) { + const toAdd = length - arr.length; + for (let i = 0; i < toAdd; i++) { arr.push(null); } } } /** Determine if table is fixed width and if it is, return the width in pixels */ function getFixedWidth(blockDef) { - if (blockDef.columnInfos && blockDef.columnInfos.every(function (ci) { return ci && ci.columnWidth && ci.columnWidth.match(/[0-9]+px/); })) { - return _.sum(blockDef.columnInfos.map(function (ci) { return parseFloat(ci.columnWidth); })); + if (blockDef.columnInfos && blockDef.columnInfos.every(ci => ci && ci.columnWidth && ci.columnWidth.match(/[0-9]+px/))) { + return _.sum(blockDef.columnInfos.map(ci => parseFloat(ci.columnWidth))); } return null; } diff --git a/lib/widgets/blocks/queryTable/queryTable.test.js b/lib/widgets/blocks/queryTable/queryTable.test.js index 11adbbbf..af015ca5 100644 --- a/lib/widgets/blocks/queryTable/queryTable.test.js +++ b/lib/widgets/blocks/queryTable/queryTable.test.js @@ -1,26 +1,15 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var queryTable_1 = require("./queryTable"); -var schema_1 = __importDefault(require("../../../__fixtures__/schema")); -var BlockFactory_1 = __importDefault(require("../../BlockFactory")); +const queryTable_1 = require("./queryTable"); +const schema_1 = __importDefault(require("../../../__fixtures__/schema")); +const BlockFactory_1 = __importDefault(require("../../BlockFactory")); // Outer context vars -var rowsetCV = { id: "cv1", type: "rowset", name: "CV1", table: "t1" }; -var contextVars = [rowsetCV]; -var qtbdSingle = { +const rowsetCV = { id: "cv1", type: "rowset", name: "CV1", table: "t1" }; +const contextVars = [rowsetCV]; +const qtbdSingle = { id: "123", type: "queryTable", mode: "singleRow", @@ -32,9 +21,9 @@ var qtbdSingle = { where: null, rowClickAction: null }; -var createBlock = new BlockFactory_1.default().createBlock; -var qtbSingle = new queryTable_1.QueryTableBlock(qtbdSingle); -var qtbdMultiple = { +const createBlock = new BlockFactory_1.default().createBlock; +const qtbSingle = new queryTable_1.QueryTableBlock(qtbdSingle); +const qtbdMultiple = { id: "123", type: "queryTable", mode: "multiRow", @@ -46,9 +35,9 @@ var qtbdMultiple = { where: null, rowClickAction: null }; -var qtbMultiple = new queryTable_1.QueryTableBlock(qtbdMultiple); -var schema = schema_1.default(); -test("gets single row cv", function () { +const qtbMultiple = new queryTable_1.QueryTableBlock(qtbdMultiple); +const schema = schema_1.default(); +test("gets single row cv", () => { expect(qtbSingle.createRowContextVar(rowsetCV)).toEqual({ id: "123_row", name: "Table row of CV1", @@ -56,7 +45,7 @@ test("gets single row cv", function () { table: "t1" }); }); -test("gets multiple row cv", function () { +test("gets multiple row cv", () => { expect(qtbMultiple.createRowContextVar(rowsetCV)).toEqual({ id: "123_rowset", name: "Table row rowset of CV1", @@ -64,12 +53,12 @@ test("gets multiple row cv", function () { table: "t1" }); }); -test("gets single row cv value", function () { +test("gets single row cv value", () => { expect(qtbSingle.getRowContextVarValue({ id: "123" }, [], schema, rowsetCV, contextVars, null)).toEqual("123"); }); -test("gets multiple row cv value", function () { +test("gets multiple row cv value", () => { // One non-aggregate, one aggregate - var exprs = [ + const exprs = [ { type: "field", table: "t1", column: "text" }, { type: "op", table: "t1", op: "count", exprs: [] } ]; @@ -83,10 +72,10 @@ test("gets multiple row cv value", function () { ] }); }); -test("gets row expressions", function () { +test("gets row expressions", () => { // Create single expression in contents - var expr = { type: "field", table: "t1", column: "text" }; - var qtbd = __assign(__assign({}, qtbdSingle), { contents: [{ type: "expression", id: "re1", contextVarId: "123_row", expr: expr }] }); - var qtb = new queryTable_1.QueryTableBlock(qtbd); + const expr = { type: "field", table: "t1", column: "text" }; + const qtbd = Object.assign(Object.assign({}, qtbdSingle), { contents: [{ type: "expression", id: "re1", contextVarId: "123_row", expr: expr }] }); + const qtb = new queryTable_1.QueryTableBlock(qtbd); expect(qtb.getRowExprs(contextVars, { createBlock: createBlock })).toEqual([expr]); }); diff --git a/lib/widgets/blocks/row.js b/lib/widgets/blocks/row.js index 278a99c5..94bb0578 100644 --- a/lib/widgets/blocks/row.js +++ b/lib/widgets/blocks/row.js @@ -1,75 +1,47 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RowBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var react_1 = __importDefault(require("react")); -var blocks_1 = require("../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var propertyEditors_1 = require("../propertyEditors"); -var localization_1 = require("../localization"); -var react_2 = require("react"); -var contexts_1 = require("../../contexts"); -var RowBlock = /** @class */ (function (_super) { - __extends(RowBlock, _super); - function RowBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - RowBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const react_1 = __importDefault(require("react")); +const blocks_1 = require("../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const propertyEditors_1 = require("../propertyEditors"); +const localization_1 = require("../localization"); +const react_2 = require("react"); +const contexts_1 = require("../../contexts"); +class RowBlock extends blocks_1.Block { + getChildren(contextVars) { if (this.blockDef.content) { - var contextVar = this.createContextVar(); + const contextVar = this.createContextVar(); return [{ blockDef: this.blockDef.content, contextVars: contextVar ? contextVars.concat([contextVar]) : contextVars }]; } return []; - }; - RowBlock.prototype.createContextVar = function () { + } + createContextVar() { if (this.blockDef.table) { return { type: "row", id: this.blockDef.id, name: this.blockDef.name || "Unnamed", table: this.blockDef.table }; } return null; - }; - RowBlock.prototype.getContextVarExprs = function (contextVar, ctx) { + } + getContextVarExprs(contextVar, ctx) { if (this.blockDef.idContextVarExpr && contextVar.id == this.blockDef.idContextVarExpr.contextVarId) { return [this.blockDef.idContextVarExpr.expr]; } return []; - }; - RowBlock.prototype.validate = function (options) { - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - var error; + } + validate(options) { + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + let error; if (!this.blockDef.table) { return "Missing table"; } - var mode = this.blockDef.mode || "filter"; + const mode = this.blockDef.mode || "filter"; // Validate filter if (mode == "filter") { error = exprValidator.validateExpr(this.blockDef.filter || null, { table: this.blockDef.table, types: ["boolean"] }); @@ -77,8 +49,7 @@ var RowBlock = /** @class */ (function (_super) { return error; } // Validate orderBy - for (var _i = 0, _a = this.blockDef.filterOrderBy || []; _i < _a.length; _i++) { - var orderBy = _a[_i]; + for (const orderBy of this.blockDef.filterOrderBy || []) { error = exprValidator.validateExpr(orderBy.expr, { table: this.blockDef.table }); if (error) { return error; @@ -104,90 +75,78 @@ var RowBlock = /** @class */ (function (_super) { } } return null; - }; - RowBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; - RowBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSetContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleSetContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = blockDef; return b; }), blockDef.id); }; // Create props for child - var contextVar = this.createContextVar(); - var contentProps = props; + const contextVar = this.createContextVar(); + let contentProps = props; // Add context variable if knowable if (contextVar) { - contentProps = __assign(__assign({}, contentProps), { contextVars: props.contextVars.concat([contextVar]) }); + contentProps = Object.assign(Object.assign({}, contentProps), { contextVars: props.contextVars.concat([contextVar]) }); } - var contentNode = props.renderChildBlock(contentProps, this.blockDef.content, handleSetContent); + const contentNode = props.renderChildBlock(contentProps, this.blockDef.content, handleSetContent); return (react_1.default.createElement("div", { style: { paddingTop: 5, paddingBottom: 5, border: "dashed 1px #CCC" } }, contentNode)); - }; - RowBlock.prototype.renderInstance = function (props) { - var contextVar = this.createContextVar(); + } + renderInstance(props) { + const contextVar = this.createContextVar(); return react_1.default.createElement(RowInstance, { contextVar: contextVar, blockDef: this.blockDef, instanceProps: props }); - }; - RowBlock.prototype.renderEditor = function (props) { - var _this = this; - var handleTableChange = function (tableId) { - var table = props.schema.getTable(tableId); - props.store.replaceBlock(immer_1.default(_this.blockDef, function (bd) { + } + renderEditor(props) { + const handleTableChange = (tableId) => { + const table = props.schema.getTable(tableId); + props.store.replaceBlock(immer_1.default(this.blockDef, (bd) => { bd.table = tableId; bd.name = bd.name || localization_1.localize(table.name); })); }; - var mode = this.blockDef.mode || "filter"; + const mode = this.blockDef.mode || "filter"; return (react_1.default.createElement("div", null, react_1.default.createElement("h3", null, "Row"), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Table" }, react_1.default.createElement(propertyEditors_1.TableSelect, { schema: props.schema, locale: props.locale, value: this.blockDef.table || null, onChange: handleTableChange })), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Name" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "name" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange, placeholder: "Unnamed" }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "name" }, (value, onChange) => react_1.default.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange, placeholder: "Unnamed" }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Mode", key: "mode" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "mode" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value || "filter", onChange: onChange, options: [ - { value: "filter", label: "By Filter" }, - { value: "id", label: "By ID" } - ] }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "mode" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value || "filter", onChange: onChange, options: [ + { value: "filter", label: "By Filter" }, + { value: "id", label: "By ID" } + ] }))), this.blockDef.table && mode == "filter" ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Filter" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filter" }, function (value, onChange) { - return react_1.default.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: _this.blockDef.table, variables: blocks_1.createExprVariables(props.contextVars) }); - })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filter" }, (value, onChange) => react_1.default.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: this.blockDef.table, variables: blocks_1.createExprVariables(props.contextVars) }))) : null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Filter Order", key: "filterOrderBy", hint: "If filter matches more than one row, first one is taken" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filterOrderBy" }, function (value, onChange) { - return react_1.default.createElement(propertyEditors_1.OrderByArrayEditor, { value: value || [], onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: _this.blockDef.table }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filterOrderBy" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.OrderByArrayEditor, { value: value || [], onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars, table: this.blockDef.table }))), this.blockDef.table && mode == "id" ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "ID of row" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idContextVarExpr" }, function (value, onChange) { - return react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, contextVarId: value ? value.contextVarId : null, expr: value ? value.expr : null, onChange: function (contextVarId, expr) { - onChange({ contextVarId: contextVarId, expr: expr }); - }, schema: props.schema, dataSource: props.dataSource, idTable: _this.blockDef.table, types: ["id"] }); - })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "idContextVarExpr" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, contextVarId: value ? value.contextVarId : null, expr: value ? value.expr : null, onChange: (contextVarId, expr) => { + onChange({ contextVarId, expr }); + }, schema: props.schema, dataSource: props.dataSource, idTable: this.blockDef.table, types: ["id"] }))) : null)); - }; - return RowBlock; -}(blocks_1.Block)); + } +} exports.RowBlock = RowBlock; -var RowInstance = function (props) { - var _a; - var blockDef = props.blockDef, instanceProps = props.instanceProps, contextVar = props.contextVar; - var db = instanceProps.database; - var table = contextVar.table; - var _b = react_2.useState(null), error = _b[0], setError = _b[1]; - var _c = react_2.useState(true), loading = _c[0], setLoading = _c[1]; - var _d = react_2.useState(), id = _d[0], setId = _d[1]; - var mode = blockDef.mode || "filter"; - react_2.useEffect(function () { +const RowInstance = (props) => { + const { blockDef, instanceProps, contextVar } = props; + const db = instanceProps.database; + const table = contextVar.table; + const [error, setError] = react_2.useState(null); + const [loading, setLoading] = react_2.useState(true); + const [id, setId] = react_2.useState(); + const mode = blockDef.mode || "filter"; + react_2.useEffect(() => { if (mode == "filter") { // Query to get match db.query({ @@ -197,7 +156,7 @@ var RowInstance = function (props) { orderBy: blockDef.filterOrderBy || undefined, limit: 1 }, instanceProps.contextVars, contexts_1.getFilteredContextVarValues(instanceProps)) - .then(function (rows) { + .then((rows) => { if (rows.length > 0) { setId(rows[0].id); } @@ -206,14 +165,14 @@ var RowInstance = function (props) { } setLoading(false); }) - .catch(function (err) { + .catch(err => { setError(err); setLoading(false); }); } else { // Just set id from context var - var exprValue = instanceProps.getContextVarExprValue(blockDef.idContextVarExpr.contextVarId, blockDef.idContextVarExpr.expr); + const exprValue = instanceProps.getContextVarExprValue(blockDef.idContextVarExpr.contextVarId, blockDef.idContextVarExpr.expr); setId(exprValue); setLoading(false); } @@ -226,7 +185,7 @@ var RowInstance = function (props) { return react_1.default.createElement("div", { className: "alert alert-danger" }, "Error loading results"); } // Inject context variable - return react_1.default.createElement(ContextVarsInjector_1.default, { injectedContextVars: [contextVar], injectedContextVarValues: (_a = {}, _a[contextVar.id] = id, _a), innerBlock: blockDef.content, instanceCtx: instanceProps }, function (instanceCtx, loading, refreshing) { + return react_1.default.createElement(ContextVarsInjector_1.default, { injectedContextVars: [contextVar], injectedContextVarValues: { [contextVar.id]: id }, innerBlock: blockDef.content, instanceCtx: instanceProps }, (instanceCtx, loading, refreshing) => { if (loading) { return react_1.default.createElement("div", { style: { color: "#AAA", textAlign: "center" } }, react_1.default.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); diff --git a/lib/widgets/blocks/rowset.js b/lib/widgets/blocks/rowset.js index d1b01fa9..ee9fe7e6 100644 --- a/lib/widgets/blocks/rowset.js +++ b/lib/widgets/blocks/rowset.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,36 +23,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RowsetBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var propertyEditors_1 = require("../propertyEditors"); -var localization_1 = require("../localization"); -var RowsetBlock = /** @class */ (function (_super) { - __extends(RowsetBlock, _super); - function RowsetBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - RowsetBlock.prototype.getChildren = function (contextVars) { +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const propertyEditors_1 = require("../propertyEditors"); +const localization_1 = require("../localization"); +class RowsetBlock extends blocks_1.Block { + getChildren(contextVars) { if (this.blockDef.content) { - var contextVar = this.createContextVar(); + const contextVar = this.createContextVar(); return [{ blockDef: this.blockDef.content, contextVars: contextVar ? contextVars.concat([contextVar]) : contextVars }]; } return []; - }; - RowsetBlock.prototype.createContextVar = function () { + } + createContextVar() { if (this.blockDef.table) { return { type: "rowset", id: this.blockDef.id, name: this.blockDef.name || "Unnamed", table: this.blockDef.table }; } return null; - }; - RowsetBlock.prototype.validate = function (options) { - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - var error; + } + validate(options) { + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + let error; if (!this.blockDef.table) { return "Missing table"; } @@ -86,49 +58,45 @@ var RowsetBlock = /** @class */ (function (_super) { return error; } return null; - }; - RowsetBlock.prototype.processChildren = function (action) { - var content = action(this.blockDef.content); - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const content = action(this.blockDef.content); + return immer_1.default(this.blockDef, draft => { draft.content = content; }); - }; - RowsetBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleSetContent = function (blockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleSetContent = (blockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.content = blockDef; return b; }), blockDef.id); }; // Create props for child - var contextVar = this.createContextVar(); - var contentProps = props; + const contextVar = this.createContextVar(); + let contentProps = props; // Add context variable if knowable if (contextVar) { - contentProps = __assign(__assign({}, contentProps), { contextVars: props.contextVars.concat([contextVar]) }); + contentProps = Object.assign(Object.assign({}, contentProps), { contextVars: props.contextVars.concat([contextVar]) }); } - var contentNode = props.renderChildBlock(contentProps, this.blockDef.content, handleSetContent); + const contentNode = props.renderChildBlock(contentProps, this.blockDef.content, handleSetContent); return (React.createElement("div", { style: { paddingTop: 5, paddingBottom: 5, border: "dashed 1px #CCC" } }, contentNode)); - }; - RowsetBlock.prototype.renderInstance = function (props) { - var _a; - var _this = this; - var contextVar = this.createContextVar(); + } + renderInstance(props) { + const contextVar = this.createContextVar(); // Inject context variable - return React.createElement(ContextVarsInjector_1.default, { injectedContextVars: [contextVar], injectedContextVarValues: (_a = {}, _a[contextVar.id] = this.blockDef.filter, _a), innerBlock: this.blockDef.content, instanceCtx: props }, function (instanceCtx, loading, refreshing) { + return React.createElement(ContextVarsInjector_1.default, { injectedContextVars: [contextVar], injectedContextVarValues: { [contextVar.id]: this.blockDef.filter }, innerBlock: this.blockDef.content, instanceCtx: props }, (instanceCtx, loading, refreshing) => { if (loading) { return React.createElement("div", { style: { color: "#AAA", textAlign: "center" } }, React.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); } - return (React.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, props.renderChildBlock(instanceCtx, _this.blockDef.content))); + return (React.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, props.renderChildBlock(instanceCtx, this.blockDef.content))); }); - }; - RowsetBlock.prototype.renderEditor = function (props) { - var _this = this; - var handleTableChange = function (tableId) { - var table = props.schema.getTable(tableId); - props.store.replaceBlock(immer_1.default(_this.blockDef, function (bd) { + } + renderEditor(props) { + const handleTableChange = (tableId) => { + const table = props.schema.getTable(tableId); + props.store.replaceBlock(immer_1.default(this.blockDef, (bd) => { bd.table = tableId; bd.name = bd.name || ("List of " + localization_1.localize(table.name)); })); @@ -138,14 +106,11 @@ var RowsetBlock = /** @class */ (function (_super) { React.createElement(propertyEditors_1.LabeledProperty, { label: "Table" }, React.createElement(propertyEditors_1.TableSelect, { schema: props.schema, locale: props.locale, value: this.blockDef.table || null, onChange: handleTableChange })), React.createElement(propertyEditors_1.LabeledProperty, { label: "Name" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "name" }, function (value, onChange) { return React.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange, placeholder: "Unnamed" }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "name" }, (value, onChange) => React.createElement(bootstrap_1.TextInput, { value: value || null, onChange: onChange, placeholder: "Unnamed" }))), this.blockDef.table ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Filter" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filter" }, function (value, onChange) { - return React.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: _this.blockDef.table, variables: blocks_1.createExprVariables(props.contextVars) }); - })) + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "filter" }, (value, onChange) => React.createElement(mwater_expressions_ui_1.FilterExprComponent, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, table: this.blockDef.table, variables: blocks_1.createExprVariables(props.contextVars) }))) : null)); - }; - return RowsetBlock; -}(blocks_1.Block)); + } +} exports.RowsetBlock = RowsetBlock; diff --git a/lib/widgets/blocks/saveCancel.js b/lib/widgets/blocks/saveCancel.js index ebf33ef3..50d2142b 100644 --- a/lib/widgets/blocks/saveCancel.js +++ b/lib/widgets/blocks/saveCancel.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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) { @@ -32,61 +8,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SaveCancelBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var uuid_1 = __importDefault(require("uuid")); -var react_1 = __importDefault(require("react")); -var immer_1 = __importDefault(require("immer")); -var blocks_1 = require("../blocks"); -var localization_1 = require("../localization"); -var propertyEditors_1 = require("../propertyEditors"); -var VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); -var ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); -var ListEditorComponent_1 = require("react-library/lib/ListEditorComponent"); +const lodash_1 = __importDefault(require("lodash")); +const uuid_1 = __importDefault(require("uuid")); +const react_1 = __importDefault(require("react")); +const immer_1 = __importDefault(require("immer")); +const blocks_1 = require("../blocks"); +const localization_1 = require("../localization"); +const propertyEditors_1 = require("../propertyEditors"); +const VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); +const ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); +const ListEditorComponent_1 = require("react-library/lib/ListEditorComponent"); /** Block that has a save/cancel button pair at bottom. Changes are only sent to the database if save is clicked. * When either is clicked, the page is closed. Has optional delete button too. */ -var SaveCancelBlock = /** @class */ (function (_super) { - __extends(SaveCancelBlock, _super); - function SaveCancelBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - SaveCancelBlock.prototype.getChildren = function (contextVars) { +class SaveCancelBlock extends blocks_1.Block { + getChildren(contextVars) { return this.blockDef.child ? [{ blockDef: this.blockDef.child, contextVars: contextVars }] : []; - }; - SaveCancelBlock.prototype.validate = function (options) { - var _this = this; + } + validate(options) { if (!this.blockDef.saveLabel) { return "Save label required"; } @@ -100,7 +44,7 @@ var SaveCancelBlock = /** @class */ (function (_super) { if (!this.blockDef.deleteLabel) { return "Delete label required"; } - var deleteCV = options.contextVars.find(function (cv) { return cv.id == _this.blockDef.deleteContextVarId; }); + const deleteCV = options.contextVars.find(cv => cv.id == this.blockDef.deleteContextVarId); if (!deleteCV) { return "Delete context variable not found"; } @@ -110,41 +54,34 @@ var SaveCancelBlock = /** @class */ (function (_super) { } // Check extras if (this.blockDef.deleteContextVarId && this.blockDef.extraDeleteContextVarIds) { - var _loop_1 = function (cvId) { - var deleteCV = options.contextVars.find(function (cv) { return cv.id == cvId; }); + for (const cvId of this.blockDef.extraDeleteContextVarIds) { + const deleteCV = options.contextVars.find(cv => cv.id == cvId); if (!deleteCV) { - return { value: "Delete context variable not found" }; + return "Delete context variable not found"; } if (deleteCV.type !== "row") { - return { value: "Delete context variable wrong type" }; + return "Delete context variable wrong type"; } - }; - for (var _i = 0, _a = this.blockDef.extraDeleteContextVarIds; _i < _a.length; _i++) { - var cvId = _a[_i]; - var state_1 = _loop_1(cvId); - if (typeof state_1 === "object") - return state_1.value; } } return null; - }; - SaveCancelBlock.prototype.processChildren = function (action) { - var child = action(this.blockDef.child); - return immer_1.default(this.blockDef, function (draft) { + } + processChildren(action) { + const child = action(this.blockDef.child); + return immer_1.default(this.blockDef, draft => { draft.child = child; }); - }; - SaveCancelBlock.prototype.renderDesign = function (props) { - var _this = this; - var handleAdd = function (addedBlockDef) { - props.store.alterBlock(_this.id, immer_1.default(function (b) { + } + renderDesign(props) { + const handleAdd = (addedBlockDef) => { + props.store.alterBlock(this.id, immer_1.default((b) => { b.child = addedBlockDef; return b; }), addedBlockDef.id); }; - var saveLabelText = localization_1.localize(this.blockDef.saveLabel, props.locale); - var cancelLabelText = localization_1.localize(this.blockDef.cancelLabel, props.locale); - var deleteLabelText = localization_1.localize(this.blockDef.deleteLabel, props.locale); + const saveLabelText = localization_1.localize(this.blockDef.saveLabel, props.locale); + const cancelLabelText = localization_1.localize(this.blockDef.cancelLabel, props.locale); + const deleteLabelText = localization_1.localize(this.blockDef.deleteLabel, props.locale); return (react_1.default.createElement("div", null, props.renderChildBlock(props, this.blockDef.child, handleAdd), react_1.default.createElement("div", { className: "save-cancel-footer" }, @@ -157,224 +94,176 @@ var SaveCancelBlock = /** @class */ (function (_super) { react_1.default.createElement("button", { type: "button", className: "btn btn-primary" }, saveLabelText), "\u00A0", react_1.default.createElement("button", { type: "button", className: "btn btn-default" }, cancelLabelText)))); - }; + } /** Special case as the inner block will have a virtual database and its own expression evaluator */ - SaveCancelBlock.prototype.getSubtreeContextVarExprs = function (contextVar, ctx) { + getSubtreeContextVarExprs(contextVar, ctx) { return []; - }; - SaveCancelBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return react_1.default.createElement(SaveCancelInstance, { instanceCtx: props, blockDef: this.blockDef }); - }; - SaveCancelBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Save Label" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "saveLabel" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "saveLabel" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Cancel Label" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "cancelLabel" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "cancelLabel" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Confirm Discard Message" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "confirmDiscardMessage" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "confirmDiscardMessage" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Optional Delete Target" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "deleteContextVarId" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["row"] }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "deleteContextVarId" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["row"] }))), this.blockDef.deleteContextVarId ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Delete Label" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "deleteLabel" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "deleteLabel" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))) : null, this.blockDef.deleteContextVarId ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Optional Confirm Delete Message" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "confirmDeleteMessage" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "confirmDeleteMessage" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))) : null, this.blockDef.deleteContextVarId ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Optional Additional Delete Targets" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "extraDeleteContextVarIds" }, function (value, onChange) { + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "extraDeleteContextVarIds" }, (value, onChange) => { function renderItem(item, index, onItemChange) { return react_1.default.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: item, onChange: onItemChange, contextVars: props.contextVars, types: ["row"] }); } - return react_1.default.createElement(ListEditorComponent_1.ListEditorComponent, { items: value || [], onItemsChange: onChange, renderItem: renderItem, addLabel: "Add", createNew: function () { return null; } }); + return react_1.default.createElement(ListEditorComponent_1.ListEditorComponent, { items: value || [], onItemsChange: onChange, renderItem: renderItem, addLabel: "Add", createNew: () => null }); })) : null)); - }; - return SaveCancelBlock; -}(blocks_1.Block)); + } +} exports.SaveCancelBlock = SaveCancelBlock; /** Instance swaps out the database for a virtual database */ -var SaveCancelInstance = /** @class */ (function (_super) { - __extends(SaveCancelInstance, _super); - function SaveCancelInstance(props) { - var _this = _super.call(this, props) || this; - _this.validate = function () { +class SaveCancelInstance extends react_1.default.Component { + constructor(props) { + super(props); + this.validate = () => { // Confirm if changes present - if (_this.state.virtualDatabase.mutations.length > 0) { - if (!confirm(localization_1.localize(_this.props.blockDef.confirmDiscardMessage, _this.props.instanceCtx.locale))) { + if (this.state.virtualDatabase.mutations.length > 0) { + if (!confirm(localization_1.localize(this.props.blockDef.confirmDiscardMessage, this.props.instanceCtx.locale))) { // Return empty string to block without message return ""; } } return null; }; - _this.handleSave = function () { return __awaiter(_this, void 0, void 0, function () { - var validationMessages, _i, _a, key, msg, err_1; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - validationMessages = []; - _i = 0, _a = Object.keys(this.validationRegistrations); - _b.label = 1; - case 1: - if (!(_i < _a.length)) return [3 /*break*/, 4]; - key = _a[_i]; - return [4 /*yield*/, this.validationRegistrations[key](validationMessages.length == 0)]; - case 2: - msg = _b.sent(); - if (msg != null) { - validationMessages.push(msg); - } - _b.label = 3; - case 3: - _i++; - return [3 /*break*/, 1]; - case 4: - if (validationMessages.length > 0) { - // "" just blocks - if (lodash_1.default.compact(validationMessages).length > 0) { - alert(lodash_1.default.compact(validationMessages).join("\n")); - } - return [2 /*return*/]; - } - this.setState({ saving: true }); - _b.label = 5; - case 5: - _b.trys.push([5, 7, , 8]); - return [4 /*yield*/, this.state.virtualDatabase.commit()]; - case 6: - _b.sent(); - return [3 /*break*/, 8]; - case 7: - err_1 = _b.sent(); - // TODO localize - alert("Unable to save changes: " + err_1.message); - this.setState({ saving: false }); - return [2 /*return*/]; - case 8: - this.setState({ saving: false, destroyed: true }); - this.props.instanceCtx.pageStack.closePage(); - return [2 /*return*/]; + this.handleSave = () => __awaiter(this, void 0, void 0, function* () { + // Validate all instances that have registered + const validationMessages = []; + for (const key of Object.keys(this.validationRegistrations)) { + const msg = yield this.validationRegistrations[key](validationMessages.length == 0); + if (msg != null) { + validationMessages.push(msg); } - }); - }); }; - _this.handleCancel = function () { - _this.state.virtualDatabase.rollback(); - _this.setState({ destroyed: true }); - _this.props.instanceCtx.pageStack.closePage(); + } + if (validationMessages.length > 0) { + // "" just blocks + if (lodash_1.default.compact(validationMessages).length > 0) { + alert(lodash_1.default.compact(validationMessages).join("\n")); + } + return; + } + this.setState({ saving: true }); + try { + yield this.state.virtualDatabase.commit(); + } + catch (err) { + // TODO localize + alert("Unable to save changes: " + err.message); + this.setState({ saving: false }); + return; + } + this.setState({ saving: false, destroyed: true }); + this.props.instanceCtx.pageStack.closePage(); + }); + this.handleCancel = () => { + this.state.virtualDatabase.rollback(); + this.setState({ destroyed: true }); + this.props.instanceCtx.pageStack.closePage(); }; - _this.handleDelete = function () { return __awaiter(_this, void 0, void 0, function () { - var blockDef, db, deleteRow, txn, _i, _a, cvId, err_2; - var _this = this; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - blockDef = this.props.blockDef; - // Confirm deletion - if (blockDef.confirmDeleteMessage && !confirm(localization_1.localize(blockDef.confirmDeleteMessage, this.props.instanceCtx.locale))) { - return [2 /*return*/]; - } - db = this.props.instanceCtx.database; - deleteRow = function (tx, contextVarId) { return __awaiter(_this, void 0, void 0, function () { - var deleteCV, rowId; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - deleteCV = this.props.instanceCtx.contextVars.find(function (cv) { return cv.id == contextVarId; }); - if (!deleteCV) { - throw new Error("Missing delete CV"); - } - rowId = this.props.instanceCtx.contextVarValues[deleteCV.id]; - if (!rowId) { - return [2 /*return*/]; - } - return [4 /*yield*/, tx.removeRow(deleteCV.table, rowId)]; - case 1: - _a.sent(); - return [2 /*return*/]; - } - }); - }); }; - _b.label = 1; - case 1: - _b.trys.push([1, 3, , 4]); - txn = db.transaction(); - deleteRow(txn, blockDef.deleteContextVarId); - if (blockDef.extraDeleteContextVarIds) { - for (_i = 0, _a = blockDef.extraDeleteContextVarIds; _i < _a.length; _i++) { - cvId = _a[_i]; - deleteRow(txn, cvId); - } - } - return [4 /*yield*/, txn.commit()]; - case 2: - _b.sent(); - return [3 /*break*/, 4]; - case 3: - err_2 = _b.sent(); - // TODO localize - alert("Unable to delete row: " + err_2.message); - return [2 /*return*/]; - case 4: - this.state.virtualDatabase.rollback(); - this.setState({ destroyed: true }); - this.props.instanceCtx.pageStack.closePage(); - return [2 /*return*/]; + this.handleDelete = () => __awaiter(this, void 0, void 0, function* () { + const blockDef = this.props.blockDef; + // Confirm deletion + if (blockDef.confirmDeleteMessage && !confirm(localization_1.localize(blockDef.confirmDeleteMessage, this.props.instanceCtx.locale))) { + return; + } + // Do actual deletion + const db = this.props.instanceCtx.database; + const deleteRow = (tx, contextVarId) => __awaiter(this, void 0, void 0, function* () { + const deleteCV = this.props.instanceCtx.contextVars.find(cv => cv.id == contextVarId); + if (!deleteCV) { + throw new Error("Missing delete CV"); } + const rowId = this.props.instanceCtx.contextVarValues[deleteCV.id]; + if (!rowId) { + return; + } + yield tx.removeRow(deleteCV.table, rowId); }); - }); }; + try { + const txn = db.transaction(); + deleteRow(txn, blockDef.deleteContextVarId); + if (blockDef.extraDeleteContextVarIds) { + for (const cvId of blockDef.extraDeleteContextVarIds) { + deleteRow(txn, cvId); + } + } + yield txn.commit(); + } + catch (err) { + // TODO localize + alert("Unable to delete row: " + err.message); + return; + } + this.state.virtualDatabase.rollback(); + this.setState({ destroyed: true }); + this.props.instanceCtx.pageStack.closePage(); + }); /** Stores the registration for validation of a child block and returns an unregister function */ - _this.registerChildForValidation = function (validate) { - var key = uuid_1.default(); - _this.validationRegistrations[key] = validate; - return function () { - delete _this.validationRegistrations[key]; + this.registerChildForValidation = (validate) => { + const key = uuid_1.default(); + this.validationRegistrations[key] = validate; + return () => { + delete this.validationRegistrations[key]; }; }; - _this.validationRegistrations = {}; - _this.state = { + this.validationRegistrations = {}; + this.state = { virtualDatabase: new VirtualDatabase_1.default(props.instanceCtx.database, props.instanceCtx.schema, props.instanceCtx.locale), destroyed: false, saving: false }; - return _this; } - SaveCancelInstance.prototype.componentDidMount = function () { + componentDidMount() { this.unregisterValidation = this.props.instanceCtx.registerForValidation(this.validate); - }; - SaveCancelInstance.prototype.componentWillUnmount = function () { + } + componentWillUnmount() { this.unregisterValidation(); - }; - SaveCancelInstance.prototype.render = function () { - var _this = this; + } + render() { if (this.state.destroyed) { return null; } - var saveLabelText = localization_1.localize(this.props.blockDef.saveLabel, this.props.instanceCtx.locale); - var cancelLabelText = localization_1.localize(this.props.blockDef.cancelLabel, this.props.instanceCtx.locale); - var deleteLabelText = localization_1.localize(this.props.blockDef.deleteLabel, this.props.instanceCtx.locale); + const saveLabelText = localization_1.localize(this.props.blockDef.saveLabel, this.props.instanceCtx.locale); + const cancelLabelText = localization_1.localize(this.props.blockDef.cancelLabel, this.props.instanceCtx.locale); + const deleteLabelText = localization_1.localize(this.props.blockDef.deleteLabel, this.props.instanceCtx.locale); // Replace renderChildBlock with function that keeps all instances for validation - var instanceCtx = __assign(__assign({}, this.props.instanceCtx), { registerForValidation: this.registerChildForValidation }); + const instanceCtx = Object.assign(Object.assign({}, this.props.instanceCtx), { registerForValidation: this.registerChildForValidation }); // Determine if row to delete - var canDelete = this.props.blockDef.deleteContextVarId != null && this.props.instanceCtx.contextVarValues[this.props.blockDef.deleteContextVarId] != null; + let canDelete = this.props.blockDef.deleteContextVarId != null && this.props.instanceCtx.contextVarValues[this.props.blockDef.deleteContextVarId] != null; if (this.props.blockDef.extraDeleteContextVarIds) { - for (var _i = 0, _a = this.props.blockDef.extraDeleteContextVarIds; _i < _a.length; _i++) { - var cvId = _a[_i]; + for (const cvId of this.props.blockDef.extraDeleteContextVarIds) { canDelete = canDelete || (cvId != null && this.props.instanceCtx.contextVarValues[cvId] != null); } } // Inject new database and re-inject all context variables. This is needed to allow computed expressions // to come from the virtual database return (react_1.default.createElement("div", null, - react_1.default.createElement(ContextVarsInjector_1.default, { injectedContextVars: instanceCtx.contextVars, injectedContextVarValues: instanceCtx.contextVarValues, innerBlock: this.props.blockDef.child, instanceCtx: __assign(__assign({}, instanceCtx), { database: this.state.virtualDatabase }) }, function (innerInstanceCtx, loading, refreshing) { + react_1.default.createElement(ContextVarsInjector_1.default, { injectedContextVars: instanceCtx.contextVars, injectedContextVarValues: instanceCtx.contextVarValues, innerBlock: this.props.blockDef.child, instanceCtx: Object.assign(Object.assign({}, instanceCtx), { database: this.state.virtualDatabase }) }, (innerInstanceCtx, loading, refreshing) => { if (loading) { return react_1.default.createElement("div", { style: { color: "#AAA", fontSize: 18, textAlign: "center" } }, react_1.default.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); } - return (react_1.default.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, innerInstanceCtx.renderChildBlock(innerInstanceCtx, _this.props.blockDef.child))); + return (react_1.default.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, innerInstanceCtx.renderChildBlock(innerInstanceCtx, this.props.blockDef.child))); }), react_1.default.createElement("div", { className: "save-cancel-footer" }, canDelete ? @@ -388,6 +277,5 @@ var SaveCancelInstance = /** @class */ (function (_super) { saveLabelText), "\u00A0", react_1.default.createElement("button", { type: "button", className: "btn btn-default", onClick: this.handleCancel, disabled: this.state.saving }, cancelLabelText)))); - }; - return SaveCancelInstance; -}(react_1.default.Component)); + } +} diff --git a/lib/widgets/blocks/saveCancel.test.js b/lib/widgets/blocks/saveCancel.test.js index d1e7e804..5b5d4644 100644 --- a/lib/widgets/blocks/saveCancel.test.js +++ b/lib/widgets/blocks/saveCancel.test.js @@ -8,55 +8,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var schema_1 = __importDefault(require("../../__fixtures__/schema")); -var saveCancel_1 = require("./saveCancel"); -var enzyme_1 = require("enzyme"); -var react_1 = __importDefault(require("react")); -var VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); -var Database_1 = require("../../database/Database"); -var BlockFactory_1 = __importDefault(require("../BlockFactory")); +const schema_1 = __importDefault(require("../../__fixtures__/schema")); +const saveCancel_1 = require("./saveCancel"); +const enzyme_1 = require("enzyme"); +const react_1 = __importDefault(require("react")); +const VirtualDatabase_1 = __importDefault(require("../../database/VirtualDatabase")); +const Database_1 = require("../../database/Database"); +const BlockFactory_1 = __importDefault(require("../BlockFactory")); // Outer context vars -var rowCV = { id: "cv1", type: "row", name: "", table: "t1" }; -var contextVars = [rowCV]; -var schema = schema_1.default(); -var createBlock = new BlockFactory_1.default().createBlock; -var rips; -var database; +const rowCV = { id: "cv1", type: "row", name: "", table: "t1" }; +const contextVars = [rowCV]; +const schema = schema_1.default(); +const createBlock = new BlockFactory_1.default().createBlock; +let rips; +let database; // Trap alerts -var alertMessages = []; -window.alert = function (msg) { return alertMessages.push(msg); }; -beforeEach(function () { +let alertMessages = []; +window.alert = (msg) => alertMessages.push(msg); +beforeEach(() => { database = new VirtualDatabase_1.default(new Database_1.NullDatabase(), schema, "en"); // Create render instance props rips = { @@ -73,22 +46,22 @@ beforeEach(function () { onSelectContextVar: jest.fn(), schema: schema, dataSource: {}, - renderChildBlock: function (props, childBlockDef) { + renderChildBlock: (props, childBlockDef) => { if (childBlockDef) { - var childBlock = createBlock(childBlockDef); + const childBlock = createBlock(childBlockDef); return childBlock.renderInstance(props); } return react_1.default.createElement("div", null); }, widgetLibrary: { widgets: {} }, - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => { return () => { }; }, + T: (str) => str }; alertMessages = []; }); -var pause = function () { return new Promise(function (resolve, reject) { return setImmediate(resolve); }); }; +const pause = () => new Promise((resolve, reject) => setImmediate(resolve)); // Create save/cancel with single required text control -var saveCancelBlockDef = { +const saveCancelBlockDef = { id: "sc1", type: "saveCancel", saveLabel: { _base: "en", en: "Save" }, @@ -104,96 +77,60 @@ var saveCancelBlockDef = { placeholder: null } }; -test("save writes to database", function () { return __awaiter(void 0, void 0, void 0, function () { - var saveCancelBlock, txn, pk, inst; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - saveCancelBlock = new saveCancel_1.SaveCancelBlock(saveCancelBlockDef); - txn = database.transaction(); - return [4 /*yield*/, txn.addRow("t1", { text: "abc" })]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 2: - _a.sent(); - rips.contextVarValues.cv1 = pk; - inst = enzyme_1.mount(saveCancelBlock.renderInstance(rips)); - // Wait for load - return [4 /*yield*/, pause()]; - case 3: - // Wait for load - _a.sent(); - inst.update(); - expect(inst.find("input").prop("value")).toBe("abc"); - // Fire on change - inst.find("input").prop("onChange")({ target: { value: "def" } }); - // Wait for load - return [4 /*yield*/, pause()]; - case 4: - // Wait for load - _a.sent(); - inst.update(); - expect(inst.find("input").prop("value")).toBe("def"); - // Blur - inst.find("input").prop("onBlur")({ target: { value: "def" } }); - // Wait for load - return [4 /*yield*/, pause()]; - case 5: - // Wait for load - _a.sent(); - inst.update(); - // Handle page close - rips.pageStack.closePage = jest.fn(); - // Call save - inst.find("button").at(0).prop("onClick")({}); - // Wait for save - return [4 /*yield*/, pause()]; - case 6: - // Wait for save - _a.sent(); - inst.update(); - expect(alertMessages.length).toBe(0); - expect(database.mutations[0].type).toBe("add"); - return [2 /*return*/]; - } - }); -}); }); -test("prevent save if required blank", function () { return __awaiter(void 0, void 0, void 0, function () { - var saveCancelBlock, txn, pk, inst, closePage; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - saveCancelBlock = new saveCancel_1.SaveCancelBlock(saveCancelBlockDef); - txn = database.transaction(); - return [4 /*yield*/, txn.addRow("t1", {})]; - case 1: - pk = _a.sent(); - return [4 /*yield*/, txn.commit()]; - case 2: - _a.sent(); - rips.contextVarValues.cv1 = pk; - inst = enzyme_1.mount(saveCancelBlock.renderInstance(rips)); - // Wait for load - return [4 /*yield*/, pause()]; - case 3: - // Wait for load - _a.sent(); - inst.update(); - expect(inst.find("input").prop("value")).toBe(""); - closePage = jest.fn(); - rips.pageStack.closePage = closePage; - // Call save - inst.find("button").at(0).prop("onClick")({}); - // Wait for save - return [4 /*yield*/, pause()]; - case 4: - // Wait for save - _a.sent(); - inst.update(); - expect(closePage.mock.calls.length).toBe(0); - expect(alertMessages).toEqual([]); - return [2 /*return*/]; - } - }); -}); }); +test("save writes to database", () => __awaiter(void 0, void 0, void 0, function* () { + const saveCancelBlock = new saveCancel_1.SaveCancelBlock(saveCancelBlockDef); + // Add row to database + const txn = database.transaction(); + const pk = yield txn.addRow("t1", { text: "abc" }); + yield txn.commit(); + rips.contextVarValues.cv1 = pk; + const inst = enzyme_1.mount(saveCancelBlock.renderInstance(rips)); + // Wait for load + yield pause(); + inst.update(); + expect(inst.find("input").prop("value")).toBe("abc"); + // Fire on change + inst.find("input").prop("onChange")({ target: { value: "def" } }); + // Wait for load + yield pause(); + inst.update(); + expect(inst.find("input").prop("value")).toBe("def"); + // Blur + inst.find("input").prop("onBlur")({ target: { value: "def" } }); + // Wait for load + yield pause(); + inst.update(); + // Handle page close + rips.pageStack.closePage = jest.fn(); + // Call save + inst.find("button").at(0).prop("onClick")({}); + // Wait for save + yield pause(); + inst.update(); + expect(alertMessages.length).toBe(0); + expect(database.mutations[0].type).toBe("add"); + // expect(transaction.updateRow.mock.calls[0][2]).toEqual({ text: "def" }) +})); +test("prevent save if required blank", () => __awaiter(void 0, void 0, void 0, function* () { + const saveCancelBlock = new saveCancel_1.SaveCancelBlock(saveCancelBlockDef); + // Add row to database + const txn = database.transaction(); + const pk = yield txn.addRow("t1", {}); + yield txn.commit(); + rips.contextVarValues.cv1 = pk; + const inst = enzyme_1.mount(saveCancelBlock.renderInstance(rips)); + // Wait for load + yield pause(); + inst.update(); + expect(inst.find("input").prop("value")).toBe(""); + // Handle page close + const closePage = jest.fn(); + rips.pageStack.closePage = closePage; + // Call save + inst.find("button").at(0).prop("onClick")({}); + // Wait for save + yield pause(); + inst.update(); + expect(closePage.mock.calls.length).toBe(0); + expect(alertMessages).toEqual([]); +})); diff --git a/lib/widgets/blocks/search/SearchBlockInstance.js b/lib/widgets/blocks/search/SearchBlockInstance.js index 7f08fa07..405881c5 100644 --- a/lib/widgets/blocks/search/SearchBlockInstance.js +++ b/lib/widgets/blocks/search/SearchBlockInstance.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,27 +20,27 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SearchControl = void 0; -var React = __importStar(require("react")); -var blocks_1 = require("../../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var localization_1 = require("../../localization"); -var react_1 = require("react"); +const React = __importStar(require("react")); +const blocks_1 = require("../../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const localization_1 = require("../../localization"); +const react_1 = require("react"); /** Search block that filters the rowset */ -var SearchBlockInstance = function (props) { - var blockDef = props.blockDef, instanceCtx = props.instanceCtx; - var _a = react_1.useState(""), searchText = _a[0], setSearchText = _a[1]; - var searchControlRef = react_1.useRef(null); +const SearchBlockInstance = (props) => { + const { blockDef, instanceCtx } = props; + const [searchText, setSearchText] = react_1.useState(""); + const searchControlRef = react_1.useRef(null); // Focus if enabled - react_1.useEffect(function () { + react_1.useEffect(() => { if (blockDef.autoFocus && searchControlRef.current) { searchControlRef.current.focus(); } }, []); - var createExprFilter = function (expr, searchText, table) { - var escapeRegex = function (s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); }; - var exprUtils = new mwater_expressions_1.ExprUtils(instanceCtx.schema, blocks_1.createExprVariables(instanceCtx.contextVars)); + const createExprFilter = (expr, searchText, table) => { + const escapeRegex = (s) => s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + const exprUtils = new mwater_expressions_1.ExprUtils(instanceCtx.schema, blocks_1.createExprVariables(instanceCtx.contextVars)); // Get type of search expression - var exprType = exprUtils.getExprType(expr); + const exprType = exprUtils.getExprType(expr); if (exprType === "text") { return { type: "op", @@ -67,7 +54,7 @@ var SearchBlockInstance = function (props) { } if (exprType === "enum") { // Find matching enums - var enumValues = exprUtils.getExprEnumValues(expr).filter(function (ev) { return localization_1.localize(ev.name, instanceCtx.locale).toLowerCase().includes(searchText.toLowerCase()); }); + const enumValues = exprUtils.getExprEnumValues(expr).filter(ev => localization_1.localize(ev.name, instanceCtx.locale).toLowerCase().includes(searchText.toLowerCase())); if (enumValues.length === 0) { return null; } @@ -77,13 +64,13 @@ var SearchBlockInstance = function (props) { table: table, exprs: [ expr, - { type: "literal", valueType: "enumset", value: enumValues.map(function (ev) { return ev.id; }) } + { type: "literal", valueType: "enumset", value: enumValues.map(ev => ev.id) } ] }; } if (exprType === "enumset") { // Find matching enums - var enumValues = exprUtils.getExprEnumValues(expr).filter(function (ev) { return localization_1.localize(ev.name, instanceCtx.locale).toLowerCase().includes(searchText.toLowerCase()); }); + const enumValues = exprUtils.getExprEnumValues(expr).filter(ev => localization_1.localize(ev.name, instanceCtx.locale).toLowerCase().includes(searchText.toLowerCase())); if (enumValues.length === 0) { return null; } @@ -93,18 +80,18 @@ var SearchBlockInstance = function (props) { table: table, exprs: [ expr, - { type: "literal", valueType: "enumset", value: enumValues.map(function (ev) { return ev.id; }) } + { type: "literal", valueType: "enumset", value: enumValues.map(ev => ev.id) } ] }; } throw new Error("Unsupported search type " + exprType); }; - var createFilter = function (searchText) { + const createFilter = (searchText) => { // Get table - var table = instanceCtx.contextVars.find(function (cv) { return cv.id === blockDef.rowsetContextVarId; }).table; + const table = instanceCtx.contextVars.find(cv => cv.id === blockDef.rowsetContextVarId).table; if (searchText) { - var searchExprs = blockDef.searchExprs.map(function (se) { return createExprFilter(se, searchText, table); }); - var expr = { + const searchExprs = blockDef.searchExprs.map(se => createExprFilter(se, searchText, table)); + const expr = { type: "op", op: "or", table: table, @@ -116,7 +103,7 @@ var SearchBlockInstance = function (props) { return { id: blockDef.id, expr: null }; } }; - var handleChange = function (value) { + const handleChange = (value) => { setSearchText(value); // Set filter instanceCtx.setFilter(blockDef.rowsetContextVarId, createFilter(value)); @@ -125,28 +112,25 @@ var SearchBlockInstance = function (props) { }; exports.default = SearchBlockInstance; /** Simple input box with magnifying glass */ -var SearchControl = /** @class */ (function (_super) { - __extends(SearchControl, _super); - function SearchControl() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.inputRef = React.createRef(); - _this.handleChange = function (ev) { - if (_this.props.onChange) { - _this.props.onChange(ev.target.value); +class SearchControl extends React.Component { + constructor() { + super(...arguments); + this.inputRef = React.createRef(); + this.handleChange = (ev) => { + if (this.props.onChange) { + this.props.onChange(ev.target.value); } }; - return _this; } - SearchControl.prototype.focus = function () { + focus() { if (this.inputRef.current) { this.inputRef.current.focus(); } - }; - SearchControl.prototype.render = function () { + } + render() { return (React.createElement("div", { style: { position: "relative", display: "inline-block", margin: 5, width: "15em" } }, React.createElement("i", { className: "fa fa-search", style: { position: "absolute", right: 8, top: 10, color: "#AAA", pointerEvents: "none" } }), React.createElement("input", { type: "text", ref: this.inputRef, className: "form-control", style: { width: "100%" }, value: this.props.value, onChange: this.handleChange, placeholder: this.props.placeholder }))); - }; - return SearchControl; -}(React.Component)); + } +} exports.SearchControl = SearchControl; diff --git a/lib/widgets/blocks/search/SearchBlockInstance.test.js b/lib/widgets/blocks/search/SearchBlockInstance.test.js index 1f4bfc6f..1007bf81 100644 --- a/lib/widgets/blocks/search/SearchBlockInstance.test.js +++ b/lib/widgets/blocks/search/SearchBlockInstance.test.js @@ -27,163 +27,109 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var SearchBlockInstance_1 = __importDefault(require("./SearchBlockInstance")); -var enzyme_1 = require("enzyme"); -var React = __importStar(require("react")); -var schema_1 = __importDefault(require("../../../__fixtures__/schema")); -var getFilter = function (blockDef, searchText) { - return new Promise(function (resolve, reject) { +const SearchBlockInstance_1 = __importDefault(require("./SearchBlockInstance")); +const enzyme_1 = require("enzyme"); +const React = __importStar(require("react")); +const schema_1 = __importDefault(require("../../../__fixtures__/schema")); +const getFilter = (blockDef, searchText) => { + return new Promise((resolve, reject) => { // Create minimal instanceCtx - var instanceCtx = { + const instanceCtx = { schema: schema_1.default(), - setFilter: function (contextVarId, filter) { + setFilter: (contextVarId, filter) => { resolve({ contextVarId: contextVarId, filter: filter }); }, contextVars: [{ id: "cv1", type: "rowset", table: "t1" }] }; - var sbi = enzyme_1.shallow(React.createElement(SearchBlockInstance_1.default, { blockDef: blockDef, instanceCtx: instanceCtx })); + const sbi = enzyme_1.shallow(React.createElement(SearchBlockInstance_1.default, { blockDef: blockDef, instanceCtx: instanceCtx })); sbi.prop("onChange")(searchText); }); }; -test("creates search on single text expression", function () { return __awaiter(void 0, void 0, void 0, function () { - var searchExprs, filter; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - searchExprs = [ - { type: "field", table: "t1", column: "text" } - ]; - return [4 /*yield*/, getFilter({ id: "s", rowsetContextVarId: "cv1", searchExprs: searchExprs, type: "search", placeholder: null }, "xyz*")]; - case 1: - filter = _a.sent(); - expect(filter).toEqual({ - contextVarId: "cv1", - filter: { - id: "s", - expr: { - type: "op", - table: "t1", - op: "or", - exprs: [ - { - type: "op", - table: "t1", - op: "~*", - exprs: [ - searchExprs[0], - { type: "literal", valueType: "text", value: "xyz\\*" } - ] - } - ] - } +test("creates search on single text expression", () => __awaiter(void 0, void 0, void 0, function* () { + const searchExprs = [ + { type: "field", table: "t1", column: "text" } + ]; + const filter = yield getFilter({ id: "s", rowsetContextVarId: "cv1", searchExprs: searchExprs, type: "search", placeholder: null }, "xyz*"); + expect(filter).toEqual({ + contextVarId: "cv1", + filter: { + id: "s", + expr: { + type: "op", + table: "t1", + op: "or", + exprs: [ + { + type: "op", + table: "t1", + op: "~*", + exprs: [ + searchExprs[0], + { type: "literal", valueType: "text", value: "xyz\\*" } + ] } - }); - return [2 /*return*/]; + ] + } } }); -}); }); -test("creates search on single enum expression", function () { return __awaiter(void 0, void 0, void 0, function () { - var searchExprs, filter; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - searchExprs = [ - { type: "field", table: "t1", column: "enum" } - ]; - return [4 /*yield*/, getFilter({ id: "s", rowsetContextVarId: "cv1", searchExprs: searchExprs, type: "search", placeholder: null }, "B")]; - case 1: - filter = _a.sent(); - expect(filter).toEqual({ - contextVarId: "cv1", - filter: { - id: "s", - expr: { - type: "op", - table: "t1", - op: "or", - exprs: [ - { - type: "op", - table: "t1", - op: "= any", - exprs: [ - searchExprs[0], - { type: "literal", valueType: "enumset", value: ["b"] } - ] - } - ] - } +})); +test("creates search on single enum expression", () => __awaiter(void 0, void 0, void 0, function* () { + const searchExprs = [ + { type: "field", table: "t1", column: "enum" } + ]; + const filter = yield getFilter({ id: "s", rowsetContextVarId: "cv1", searchExprs: searchExprs, type: "search", placeholder: null }, "B"); + expect(filter).toEqual({ + contextVarId: "cv1", + filter: { + id: "s", + expr: { + type: "op", + table: "t1", + op: "or", + exprs: [ + { + type: "op", + table: "t1", + op: "= any", + exprs: [ + searchExprs[0], + { type: "literal", valueType: "enumset", value: ["b"] } + ] } - }); - return [2 /*return*/]; + ] + } } }); -}); }); -test("creates search on single enumset expression", function () { return __awaiter(void 0, void 0, void 0, function () { - var searchExprs, filter; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - searchExprs = [ - { type: "field", table: "t1", column: "enumset" } - ]; - return [4 /*yield*/, getFilter({ id: "s", rowsetContextVarId: "cv1", searchExprs: searchExprs, type: "search", placeholder: null }, "B")]; - case 1: - filter = _a.sent(); - expect(filter).toEqual({ - contextVarId: "cv1", - filter: { - id: "s", - expr: { - type: "op", - table: "t1", - op: "or", - exprs: [ - { - type: "op", - table: "t1", - op: "intersects", - exprs: [ - searchExprs[0], - { type: "literal", valueType: "enumset", value: ["b"] } - ] - } - ] - } +})); +test("creates search on single enumset expression", () => __awaiter(void 0, void 0, void 0, function* () { + const searchExprs = [ + { type: "field", table: "t1", column: "enumset" } + ]; + const filter = yield getFilter({ id: "s", rowsetContextVarId: "cv1", searchExprs: searchExprs, type: "search", placeholder: null }, "B"); + expect(filter).toEqual({ + contextVarId: "cv1", + filter: { + id: "s", + expr: { + type: "op", + table: "t1", + op: "or", + exprs: [ + { + type: "op", + table: "t1", + op: "intersects", + exprs: [ + searchExprs[0], + { type: "literal", valueType: "enumset", value: ["b"] } + ] } - }); - return [2 /*return*/]; + ] + } } }); -}); }); +})); diff --git a/lib/widgets/blocks/search/search.js b/lib/widgets/blocks/search/search.js index 13663900..4466cb4b 100644 --- a/lib/widgets/blocks/search/search.js +++ b/lib/widgets/blocks/search/search.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,38 +23,32 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SearchBlock = void 0; -var React = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../../LeafBlock")); -var blocks_1 = require("../../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var propertyEditors_1 = require("../../propertyEditors"); -var SearchBlockInstance_1 = __importStar(require("./SearchBlockInstance")); -var ListEditor_1 = __importDefault(require("../../ListEditor")); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var localization_1 = require("../../localization"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var SearchBlock = /** @class */ (function (_super) { - __extends(SearchBlock, _super); - function SearchBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - SearchBlock.prototype.validate = function (options) { - var _this = this; +const React = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../../LeafBlock")); +const blocks_1 = require("../../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const propertyEditors_1 = require("../../propertyEditors"); +const SearchBlockInstance_1 = __importStar(require("./SearchBlockInstance")); +const ListEditor_1 = __importDefault(require("../../ListEditor")); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const localization_1 = require("../../localization"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +class SearchBlock extends LeafBlock_1.default { + validate(options) { // Validate rowset - var rowsetCV = options.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId && cv.type === "rowset"; }); + const rowsetCV = options.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { return "Rowset required"; } if (this.blockDef.searchExprs.length === 0) { return "Search expression required"; } - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - for (var _i = 0, _a = this.blockDef.searchExprs; _i < _a.length; _i++) { - var searchExpr = _a[_i]; + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + for (const searchExpr of this.blockDef.searchExprs) { if (!searchExpr) { return "Search expression required"; } - var error = void 0; + let error; // Validate expr error = exprValidator.validateExpr(searchExpr, { table: rowsetCV.table, types: ["text", "enum", "enumset"] }); if (error) { @@ -75,35 +56,33 @@ var SearchBlock = /** @class */ (function (_super) { } } return null; - }; - SearchBlock.prototype.renderDesign = function (props) { + } + renderDesign(props) { return React.createElement(SearchBlockInstance_1.SearchControl, { value: "", placeholder: localization_1.localize(this.blockDef.placeholder, props.locale) }); - }; - SearchBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement(SearchBlockInstance_1.default, { blockDef: this.blockDef, instanceCtx: props }); - }; - SearchBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { // Get rowset context variable - var rowsetCV = props.contextVars.find(function (cv) { return cv.id === _this.blockDef.rowsetContextVarId; }); + const rowsetCV = props.contextVars.find(cv => cv.id === this.blockDef.rowsetContextVarId); return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, function (value, onChange) { return React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "rowsetContextVarId" }, (value, onChange) => React.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }))), rowsetCV ? React.createElement(propertyEditors_1.LabeledProperty, { label: "Search expressions" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "searchExprs" }, function (value, onItemsChange) { - var handleAddSearchExpr = function () { + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "searchExprs" }, (value, onItemsChange) => { + const handleAddSearchExpr = () => { onItemsChange(value.concat(null)); }; return (React.createElement("div", null, - React.createElement(ListEditor_1.default, { items: value, onItemsChange: onItemsChange }, function (expr, onExprChange) { return (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: expr, schema: props.schema, dataSource: props.dataSource, onChange: onExprChange, table: rowsetCV.table, types: ["text", "enum", "enumset"], variables: blocks_1.createExprVariables(props.contextVars) })); }), + React.createElement(ListEditor_1.default, { items: value, onItemsChange: onItemsChange }, (expr, onExprChange) => (React.createElement(mwater_expressions_ui_1.ExprComponent, { value: expr, schema: props.schema, dataSource: props.dataSource, onChange: onExprChange, table: rowsetCV.table, types: ["text", "enum", "enumset"], variables: blocks_1.createExprVariables(props.contextVars) }))), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddSearchExpr }, "+ Add Expression"))); })) : null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Placeholder" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, function (value, onChange) { return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "autoFocus" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Automatically focus on load"); }))); - }; - return SearchBlock; -}(LeafBlock_1.default)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "placeholder" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "autoFocus" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Automatically focus on load")))); + } +} exports.SearchBlock = SearchBlock; diff --git a/lib/widgets/blocks/spacer.js b/lib/widgets/blocks/spacer.js index 12e3d21f..e9fb26fc 100644 --- a/lib/widgets/blocks/spacer.js +++ b/lib/widgets/blocks/spacer.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,19 +23,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SpacerBlock = void 0; -var React = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); +const React = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); /** Creates a fixed size spacer to separate blocks */ -var SpacerBlock = /** @class */ (function (_super) { - __extends(SpacerBlock, _super); - function SpacerBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - SpacerBlock.prototype.validate = function () { return null; }; - SpacerBlock.prototype.renderDesign = function (props) { - var style = { +class SpacerBlock extends LeafBlock_1.default { + validate() { return null; } + renderDesign(props) { + const style = { backgroundImage: "linear-gradient(45deg, #dddddd 8.33%, #ffffff 8.33%, #ffffff 50%, #dddddd 50%, #dddddd 58.33%, #ffffff 58.33%, #ffffff 100%)", backgroundSize: "8.49px 8.49px" }; @@ -59,9 +42,9 @@ var SpacerBlock = /** @class */ (function (_super) { style.height = this.blockDef.height + "em"; } return React.createElement("div", { style: style }); - }; - SpacerBlock.prototype.renderInstance = function (props) { - var style = {}; + } + renderInstance(props) { + const style = {}; if (this.blockDef.width) { style.width = this.blockDef.width + "em"; } @@ -69,14 +52,13 @@ var SpacerBlock = /** @class */ (function (_super) { style.height = this.blockDef.height + "em"; } return React.createElement("div", { style: style }); - }; - SpacerBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Width in ems (blank for auto)" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "width" }, function (value, onChange) { return React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: true }); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "width" }, (value, onChange) => React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: true }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Height in ems (blank for auto)" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "height" }, function (value, onChange) { return React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: true }); })))); - }; - return SpacerBlock; -}(LeafBlock_1.default)); + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "height" }, (value, onChange) => React.createElement(bootstrap_1.NumberInput, { value: value, onChange: onChange, decimal: true }))))); + } +} exports.SpacerBlock = SpacerBlock; diff --git a/lib/widgets/blocks/tabbed/TabbedDesigner.js b/lib/widgets/blocks/tabbed/TabbedDesigner.js index f4ae5661..9dc5e9e3 100644 --- a/lib/widgets/blocks/tabbed/TabbedDesigner.js +++ b/lib/widgets/blocks/tabbed/TabbedDesigner.js @@ -1,59 +1,42 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var immer_1 = __importDefault(require("immer")); -var localization_1 = require("../../localization"); -var TabbedDesigner = /** @class */ (function (_super) { - __extends(TabbedDesigner, _super); - function TabbedDesigner(props) { - var _this = _super.call(this, props) || this; +const react_1 = __importDefault(require("react")); +const immer_1 = __importDefault(require("immer")); +const localization_1 = require("../../localization"); +class TabbedDesigner extends react_1.default.Component { + constructor(props) { + super(props); /** Handle adding a block to a tab */ - _this.handleAddContent = function (tabIndex, addedBlockDef) { - _this.props.designCtx.store.alterBlock(_this.props.tabbedBlockDef.id, immer_1.default(function (b) { + this.handleAddContent = (tabIndex, addedBlockDef) => { + this.props.designCtx.store.alterBlock(this.props.tabbedBlockDef.id, immer_1.default((b) => { b.tabs[tabIndex].content = addedBlockDef; return b; }), addedBlockDef.id); }; - _this.handleSelectTab = function (index) { - _this.setState({ activeIndex: index }); + this.handleSelectTab = (index) => { + this.setState({ activeIndex: index }); }; - _this.state = { + this.state = { activeIndex: 0 }; - return _this; } - TabbedDesigner.prototype.renderTab = function (tab, index) { - var labelText = localization_1.localize(tab.label, this.props.designCtx.locale); + renderTab(tab, index) { + const labelText = localization_1.localize(tab.label, this.props.designCtx.locale); return (react_1.default.createElement("li", { className: (this.state.activeIndex === index) ? "active" : "", key: index }, react_1.default.createElement("a", { onClick: this.handleSelectTab.bind(null, index) }, labelText))); - }; - TabbedDesigner.prototype.render = function () { - var _this = this; - var activeTab = this.props.tabbedBlockDef.tabs[this.state.activeIndex]; - var activeTabContent = activeTab ? + } + render() { + const activeTab = this.props.tabbedBlockDef.tabs[this.state.activeIndex]; + const activeTabContent = activeTab ? this.props.designCtx.renderChildBlock(this.props.designCtx, activeTab.content, this.handleAddContent.bind(null, this.state.activeIndex)) : null; // Render tabs return (react_1.default.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, - react_1.default.createElement("ul", { className: "nav nav-tabs", style: { marginBottom: 5 } }, this.props.tabbedBlockDef.tabs.map(function (tab, index) { return _this.renderTab(tab, index); })), + react_1.default.createElement("ul", { className: "nav nav-tabs", style: { marginBottom: 5 } }, this.props.tabbedBlockDef.tabs.map((tab, index) => this.renderTab(tab, index))), activeTabContent)); - }; - return TabbedDesigner; -}(react_1.default.Component)); + } +} exports.default = TabbedDesigner; diff --git a/lib/widgets/blocks/tabbed/TabbedInstance.js b/lib/widgets/blocks/tabbed/TabbedInstance.js index 4af4273c..f17a9952 100644 --- a/lib/widgets/blocks/tabbed/TabbedInstance.js +++ b/lib/widgets/blocks/tabbed/TabbedInstance.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -35,45 +22,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var _ = __importStar(require("lodash")); -var localization_1 = require("../../localization"); -var TabbedInstance = /** @class */ (function (_super) { - __extends(TabbedInstance, _super); - function TabbedInstance(props) { - var _this = _super.call(this, props) || this; - _this.handleSelectTab = function (index) { - _this.setState({ +const react_1 = __importDefault(require("react")); +const _ = __importStar(require("lodash")); +const localization_1 = require("../../localization"); +class TabbedInstance extends react_1.default.Component { + constructor(props) { + super(props); + this.handleSelectTab = (index) => { + this.setState({ activeIndex: index, - openTabIndexes: _.union(_this.state.openTabIndexes, [index]) + openTabIndexes: _.union(this.state.openTabIndexes, [index]) }); }; - _this.state = { + this.state = { activeIndex: 0, openTabIndexes: [0] }; - return _this; } - TabbedInstance.prototype.renderTab = function (tab, index) { - var labelText = localization_1.localize(tab.label, this.props.instanceCtx.locale); + renderTab(tab, index) { + const labelText = localization_1.localize(tab.label, this.props.instanceCtx.locale); return (react_1.default.createElement("li", { className: (this.state.activeIndex === index) ? "active" : "", key: index }, react_1.default.createElement("a", { onClick: this.handleSelectTab.bind(null, index), style: { cursor: "pointer" } }, labelText))); - }; - TabbedInstance.prototype.renderTabContent = function (tab, index) { + } + renderTabContent(tab, index) { // If not opened, do not render if (!this.state.openTabIndexes.includes(index)) { return null; } - var content = this.props.instanceCtx.renderChildBlock(this.props.instanceCtx, tab.content); + const content = this.props.instanceCtx.renderChildBlock(this.props.instanceCtx, tab.content); return (react_1.default.createElement("div", { key: index, style: { display: (this.state.activeIndex === index) ? "block" : "none" } }, content)); - }; - TabbedInstance.prototype.render = function () { - var _this = this; + } + render() { // Render tabs return (react_1.default.createElement("div", { style: { paddingTop: 5, paddingBottom: 5 } }, - react_1.default.createElement("ul", { className: "nav nav-tabs", style: { marginBottom: 5 } }, this.props.tabbedBlockDef.tabs.map(function (tab, index) { return _this.renderTab(tab, index); })), - this.props.tabbedBlockDef.tabs.map(function (tab, index) { return _this.renderTabContent(tab, index); }))); - }; - return TabbedInstance; -}(react_1.default.Component)); + react_1.default.createElement("ul", { className: "nav nav-tabs", style: { marginBottom: 5 } }, this.props.tabbedBlockDef.tabs.map((tab, index) => this.renderTab(tab, index))), + this.props.tabbedBlockDef.tabs.map((tab, index) => this.renderTabContent(tab, index)))); + } +} exports.default = TabbedInstance; diff --git a/lib/widgets/blocks/tabbed/tabbed.js b/lib/widgets/blocks/tabbed/tabbed.js index 561c1027..9536ffb4 100644 --- a/lib/widgets/blocks/tabbed/tabbed.js +++ b/lib/widgets/blocks/tabbed/tabbed.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,43 +23,38 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TabbedBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../../blocks"); -var propertyEditors_1 = require("../../propertyEditors"); -var TabbedDesigner_1 = __importDefault(require("./TabbedDesigner")); -var ListEditor_1 = __importDefault(require("../../ListEditor")); -var v4_1 = __importDefault(require("uuid/v4")); -var TabbedInstance_1 = __importDefault(require("./TabbedInstance")); +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../../blocks"); +const propertyEditors_1 = require("../../propertyEditors"); +const TabbedDesigner_1 = __importDefault(require("./TabbedDesigner")); +const ListEditor_1 = __importDefault(require("../../ListEditor")); +const v4_1 = __importDefault(require("uuid/v4")); +const TabbedInstance_1 = __importDefault(require("./TabbedInstance")); /** Tabbed control */ -var TabbedBlock = /** @class */ (function (_super) { - __extends(TabbedBlock, _super); - function TabbedBlock() { - return _super !== null && _super.apply(this, arguments) || this; +class TabbedBlock extends blocks_1.Block { + getChildren(contextVars) { + return this.blockDef.tabs.filter(tab => tab.content).map(tab => ({ blockDef: tab.content, contextVars: contextVars })); } - TabbedBlock.prototype.getChildren = function (contextVars) { - return this.blockDef.tabs.filter(function (tab) { return tab.content; }).map(function (tab) { return ({ blockDef: tab.content, contextVars: contextVars }); }); - }; - TabbedBlock.prototype.validate = function () { return null; }; - TabbedBlock.prototype.processChildren = function (action) { + validate() { return null; } + processChildren(action) { // Immer bug requires that producers not be nested - var tabContents = this.blockDef.tabs.map(function (t) { return action(t.content); }); - return immer_1.default(this.blockDef, function (draft) { + const tabContents = this.blockDef.tabs.map(t => action(t.content)); + return immer_1.default(this.blockDef, draft => { for (var i = 0; i < tabContents.length; i++) { draft.tabs[i].content = tabContents[i]; } }); - }; - TabbedBlock.prototype.renderDesign = function (props) { + } + renderDesign(props) { return React.createElement(TabbedDesigner_1.default, { designCtx: props, tabbedBlockDef: this.blockDef }); - }; - TabbedBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement(TabbedInstance_1.default, { instanceCtx: props, tabbedBlockDef: this.blockDef }); - }; - TabbedBlock.prototype.renderEditor = function (props) { - var _this = this; - var handleAddTab = function () { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (draft) { + } + renderEditor(props) { + const handleAddTab = () => { + props.store.replaceBlock(immer_1.default(this.blockDef, (draft) => { draft.tabs.push({ id: v4_1.default(), label: { _base: "en", en: "Unnamed" }, @@ -83,17 +65,10 @@ var TabbedBlock = /** @class */ (function (_super) { return (React.createElement("div", null, React.createElement("h3", null, "Tabbed"), React.createElement(propertyEditors_1.LabeledProperty, { label: "Tabs" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "tabs" }, function (tabs, onTabsChange) { - return React.createElement(ListEditor_1.default, { items: _this.blockDef.tabs, onItemsChange: onTabsChange }, function (tab, onTabChange) { - return React.createElement(propertyEditors_1.PropertyEditor, { obj: tab, onChange: onTabChange, property: "label" }, function (label, onLabelChange) { - return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: label, onChange: onLabelChange, locale: props.locale }); - }); - }); - }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "tabs" }, (tabs, onTabsChange) => React.createElement(ListEditor_1.default, { items: this.blockDef.tabs, onItemsChange: onTabsChange }, (tab, onTabChange) => React.createElement(propertyEditors_1.PropertyEditor, { obj: tab, onChange: onTabChange, property: "label" }, (label, onLabelChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: label, onChange: onLabelChange, locale: props.locale })))), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddTab }, React.createElement("i", { className: "fa fa-plus" }), " Add Tab")))); - }; - return TabbedBlock; -}(blocks_1.Block)); + } +} exports.TabbedBlock = TabbedBlock; diff --git a/lib/widgets/blocks/text.js b/lib/widgets/blocks/text.js index 91c2b11a..6e8dedfb 100644 --- a/lib/widgets/blocks/text.js +++ b/lib/widgets/blocks/text.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -33,45 +20,41 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TextBlock = void 0; -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var localization_1 = require("../localization"); -var mwater_expressions_1 = require("mwater-expressions"); -var _ = __importStar(require("lodash")); -var embeddedExprs_1 = require("../../embeddedExprs"); -var textual_1 = require("./textual"); -var TextBlock = /** @class */ (function (_super) { - __extends(TextBlock, _super); - function TextBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - TextBlock.prototype.getContextVarExprs = function (contextVar) { +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const localization_1 = require("../localization"); +const mwater_expressions_1 = require("mwater-expressions"); +const _ = __importStar(require("lodash")); +const embeddedExprs_1 = require("../../embeddedExprs"); +const textual_1 = require("./textual"); +class TextBlock extends textual_1.TextualBlock { + getContextVarExprs(contextVar) { if (this.blockDef.embeddedExprs) { - return _.compact(_.map(this.blockDef.embeddedExprs, function (ee) { return ee.contextVarId === contextVar.id ? ee.expr : null; })); + return _.compact(_.map(this.blockDef.embeddedExprs, ee => ee.contextVarId === contextVar.id ? ee.expr : null)); } return []; - }; - TextBlock.prototype.validate = function (options) { + } + validate(options) { // Validate expressions return embeddedExprs_1.validateEmbeddedExprs({ embeddedExprs: this.blockDef.embeddedExprs || [], schema: options.schema, contextVars: options.contextVars }); - }; - TextBlock.prototype.renderDesign = function (props) { - var text = localization_1.localize(this.blockDef.text, props.locale); + } + renderDesign(props) { + let text = localization_1.localize(this.blockDef.text, props.locale); // Replace expressions with name - var exprUtils = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)); + const exprUtils = new mwater_expressions_1.ExprUtils(props.schema, blocks_1.createExprVariables(props.contextVars)); if (this.blockDef.embeddedExprs) { - for (var i = 0; i < this.blockDef.embeddedExprs.length; i++) { + for (let i = 0; i < this.blockDef.embeddedExprs.length; i++) { if (this.blockDef.embeddedExprs[i].expr) { - text = text.replace("{" + i + "}", "{" + exprUtils.summarizeExpr(this.blockDef.embeddedExprs[i].expr, props.locale) + "}"); + text = text.replace(`{${i}}`, "{" + exprUtils.summarizeExpr(this.blockDef.embeddedExprs[i].expr, props.locale) + "}"); } } } - var node; + let node; if (this.blockDef.html) { node = this.processHTML(text); } @@ -82,11 +65,11 @@ var TextBlock = /** @class */ (function (_super) { node = text; } return this.renderText(text ? node : React.createElement("span", { className: "text-muted" }, "Text")); - }; - TextBlock.prototype.renderInstance = function (instanceCtx) { - var text = localization_1.localize(this.blockDef.text, instanceCtx.locale); + } + renderInstance(instanceCtx) { + let text = localization_1.localize(this.blockDef.text, instanceCtx.locale); // Get any embedded expression values - var exprValues = _.map(this.blockDef.embeddedExprs || [], function (ee) { return instanceCtx.getContextVarExprValue(ee.contextVarId, ee.expr); }); + const exprValues = _.map(this.blockDef.embeddedExprs || [], ee => instanceCtx.getContextVarExprValue(ee.contextVarId, ee.expr)); // Format and replace text = embeddedExprs_1.formatEmbeddedExprString({ text: text, @@ -97,7 +80,7 @@ var TextBlock = /** @class */ (function (_super) { locale: instanceCtx.locale, formatLocale: instanceCtx.formatLocale }); - var node; + let node; if (this.blockDef.html) { node = this.processHTML(text); } @@ -108,18 +91,14 @@ var TextBlock = /** @class */ (function (_super) { node = text; } return this.renderText(node); - }; - TextBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { return (React.createElement("div", null, React.createElement(propertyEditors_1.LabeledProperty, { label: "Text" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "text" }, function (value, onChange) { - return React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, multiline: _this.blockDef.multiline || _this.blockDef.markdown || _this.blockDef.html, allowCR: _this.blockDef.multiline || _this.blockDef.markdown || _this.blockDef.html }); - })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "text" }, (value, onChange) => React.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale, multiline: this.blockDef.multiline || this.blockDef.markdown || this.blockDef.html, allowCR: this.blockDef.multiline || this.blockDef.markdown || this.blockDef.html }))), React.createElement(propertyEditors_1.LabeledProperty, { label: "Embedded expressions", help: "Reference in text as {0}, {1}, etc." }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "embeddedExprs" }, function (value, onChange) { return (React.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })); })), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "embeddedExprs" }, (value, onChange) => (React.createElement(propertyEditors_1.EmbeddedExprsEditor, { value: value, onChange: onChange, schema: props.schema, dataSource: props.dataSource, contextVars: props.contextVars })))), this.renderTextualEditor(props))); - }; - return TextBlock; -}(textual_1.TextualBlock)); + } +} exports.TextBlock = TextBlock; diff --git a/lib/widgets/blocks/text.test.js b/lib/widgets/blocks/text.test.js index 6e244c73..dcca62cb 100644 --- a/lib/widgets/blocks/text.test.js +++ b/lib/widgets/blocks/text.test.js @@ -22,11 +22,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var text_1 = require("./text"); -var enzyme_1 = require("enzyme"); -var schema_1 = __importDefault(require("../../__fixtures__/schema")); -var d3Format = __importStar(require("d3-format")); -var tbd = { +const text_1 = require("./text"); +const enzyme_1 = require("enzyme"); +const schema_1 = __importDefault(require("../../__fixtures__/schema")); +const d3Format = __importStar(require("d3-format")); +const tbd = { type: "text", id: "t1", style: "p", @@ -35,22 +35,22 @@ var tbd = { { contextVarId: "cv1", expr: { type: "field", table: "t1", column: "number" }, format: "," } ] }; -var tb = new text_1.TextBlock(tbd); -var cv1 = { id: "cv1", table: "t1", type: "row", name: "Cv1" }; -test("gets expressions", function () { +const tb = new text_1.TextBlock(tbd); +const cv1 = { id: "cv1", table: "t1", type: "row", name: "Cv1" }; +test("gets expressions", () => { expect(tb.getContextVarExprs(cv1)).toEqual([ { type: "field", table: "t1", column: "number" } ]); }); -test("renders with format", function () { - var props = { +test("renders with format", () => { + const props = { getContextVarExprValue: jest.fn(), contextVars: [], schema: schema_1.default(), formatLocale: d3Format }; props.getContextVarExprValue.mockReturnValue(1234); - var inst = enzyme_1.shallow(tb.renderInstance(props)); + const inst = enzyme_1.shallow(tb.renderInstance(props)); expect(props.getContextVarExprValue.mock.calls[0]).toEqual(["cv1", { type: "field", table: "t1", column: "number" }]); expect(inst.text()).toBe("A 1,234 B"); }); diff --git a/lib/widgets/blocks/textual.js b/lib/widgets/blocks/textual.js index 5cc3302c..44ccf22e 100644 --- a/lib/widgets/blocks/textual.js +++ b/lib/widgets/blocks/textual.js @@ -1,54 +1,26 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TextualBlock = void 0; -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var react_1 = __importDefault(require("react")); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var bootstrap_2 = require("react-library/lib/bootstrap"); -var markdown_it_1 = __importDefault(require("markdown-it")); -var dompurify_1 = require("dompurify"); -var TextualBlock = /** @class */ (function (_super) { - __extends(TextualBlock, _super); - function TextualBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - TextualBlock.prototype.getClassName = function () { +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const react_1 = __importDefault(require("react")); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const bootstrap_2 = require("react-library/lib/bootstrap"); +const markdown_it_1 = __importDefault(require("markdown-it")); +const dompurify_1 = require("dompurify"); +class TextualBlock extends LeafBlock_1.default { + getClassName() { if (this.blockDef.color) { return "text-" + this.blockDef.color; } return ""; - }; + } /** Gets applied styles as CSS properties */ - TextualBlock.prototype.getStyle = function () { - var style = {}; + getStyle() { + const style = {}; if (this.blockDef.bold) { style.fontWeight = "bold"; } @@ -66,77 +38,71 @@ var TextualBlock = /** @class */ (function (_super) { style.whiteSpace = "pre-line"; } return style; - }; + } /** Renders content with the appropriate styling. If markdown, should already be processed */ - TextualBlock.prototype.renderText = function (content) { - var style = this.getStyle(); + renderText(content) { + const style = this.getStyle(); return react_1.default.createElement(this.blockDef.style || "div", { style: style, className: this.getClassName() }, content); - }; + } /** Processes markdown*/ - TextualBlock.prototype.processMarkdown = function (text) { + processMarkdown(text) { return react_1.default.createElement("div", { dangerouslySetInnerHTML: { __html: new markdown_it_1.default().render(text) } }); - }; + } /** Processes HTML */ - TextualBlock.prototype.processHTML = function (text) { + processHTML(text) { return react_1.default.createElement("div", { dangerouslySetInnerHTML: { __html: dompurify_1.sanitize(text) } }); - }; - TextualBlock.prototype.canonicalize = function () { + } + canonicalize() { if (this.blockDef.html && this.blockDef.markdown) { - return __assign(__assign({}, this.blockDef), { markdown: false }); + return Object.assign(Object.assign({}, this.blockDef), { markdown: false }); } return this.blockDef; - }; - TextualBlock.prototype.renderTextualEditor = function (props) { + } + renderTextualEditor(props) { return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Style" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "style" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Select, { value: value || "div", onChange: onChange, options: [ - { value: "div", label: "Plain Text" }, - { value: "p", label: "Paragraph" }, - { value: "h1", label: "Heading 1" }, - { value: "h2", label: "Heading 2" }, - { value: "h3", label: "Heading 3" }, - { value: "h4", label: "Heading 4" }, - { value: "h5", label: "Heading 5" } - ] }); - })), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "bold" }, function (value, onChange) { return react_1.default.createElement(bootstrap_2.Checkbox, { value: value, onChange: onChange }, "Bold"); }), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "italic" }, function (value, onChange) { return react_1.default.createElement(bootstrap_2.Checkbox, { value: value, onChange: onChange }, "Italic"); }), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "underline" }, function (value, onChange) { return react_1.default.createElement(bootstrap_2.Checkbox, { value: value, onChange: onChange }, "Underline"); }), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "style" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Select, { value: value || "div", onChange: onChange, options: [ + { value: "div", label: "Plain Text" }, + { value: "p", label: "Paragraph" }, + { value: "h1", label: "Heading 1" }, + { value: "h2", label: "Heading 2" }, + { value: "h3", label: "Heading 3" }, + { value: "h4", label: "Heading 4" }, + { value: "h5", label: "Heading 5" } + ] }))), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "bold" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Checkbox, { value: value, onChange: onChange }, "Bold")), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "italic" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Checkbox, { value: value, onChange: onChange }, "Italic")), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "underline" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Checkbox, { value: value, onChange: onChange }, "Underline")), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Alignment" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "align" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_2.Toggle, { value: value || "left", onChange: onChange, options: [ - { value: "left", label: react_1.default.createElement("i", { className: "fa fa-align-left" }) }, - { value: "center", label: react_1.default.createElement("i", { className: "fa fa-align-center" }) }, - { value: "right", label: react_1.default.createElement("i", { className: "fa fa-align-right" }) }, - { value: "justify", label: react_1.default.createElement("i", { className: "fa fa-align-justify" }) } - ] }); - })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "align" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Toggle, { value: value || "left", onChange: onChange, options: [ + { value: "left", label: react_1.default.createElement("i", { className: "fa fa-align-left" }) }, + { value: "center", label: react_1.default.createElement("i", { className: "fa fa-align-center" }) }, + { value: "right", label: react_1.default.createElement("i", { className: "fa fa-align-right" }) }, + { value: "justify", label: react_1.default.createElement("i", { className: "fa fa-align-justify" }) } + ] }))), react_1.default.createElement("div", null, !this.blockDef.html ? - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "markdown" }, function (value, onChange) { return react_1.default.createElement(bootstrap_2.Checkbox, { inline: true, value: value, onChange: onChange }, "Markdown"); }) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "markdown" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Checkbox, { inline: true, value: value, onChange: onChange }, "Markdown")) : null, !this.blockDef.markdown ? - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "html" }, function (value, onChange) { return react_1.default.createElement(bootstrap_2.Checkbox, { inline: true, value: value, onChange: onChange }, "HTML"); }) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "html" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Checkbox, { inline: true, value: value, onChange: onChange }, "HTML")) : null, !this.blockDef.markdown && !this.blockDef.html ? - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "multiline" }, function (value, onChange) { return react_1.default.createElement(bootstrap_2.Checkbox, { inline: true, value: value, onChange: onChange }, "Multi-line"); }) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "multiline" }, (value, onChange) => react_1.default.createElement(bootstrap_2.Checkbox, { inline: true, value: value, onChange: onChange }, "Multi-line")) : null), react_1.default.createElement("br", null), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Color" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "color" }, function (value, onChange) { - // Had to use "as any" due to Tyepscript bug - return react_1.default.createElement(bootstrap_1.Select, { value: value, onChange: onChange, options: [ - { value: null, label: "Default" }, - { value: "muted", label: "Muted" }, - { value: "primary", label: "Primary" }, - { value: "success", label: "Success" }, - { value: "info", label: "Info" }, - { value: "warning", label: "Warning" }, - { value: "danger", label: "Danger" } - ] }); - })))); - }; - return TextualBlock; -}(LeafBlock_1.default)); + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "color" }, (value, onChange) => + // Had to use "as any" due to Tyepscript bug + react_1.default.createElement(bootstrap_1.Select, { value: value, onChange: onChange, options: [ + { value: null, label: "Default" }, + { value: "muted", label: "Muted" }, + { value: "primary", label: "Primary" }, + { value: "success", label: "Success" }, + { value: "info", label: "Info" }, + { value: "warning", label: "Warning" }, + { value: "danger", label: "Danger" } + ] }))))); + } +} exports.TextualBlock = TextualBlock; diff --git a/lib/widgets/blocks/toc/ReorderableList.js b/lib/widgets/blocks/toc/ReorderableList.js index 78746826..5a4ebf4b 100644 --- a/lib/widgets/blocks/toc/ReorderableList.js +++ b/lib/widgets/blocks/toc/ReorderableList.js @@ -1,22 +1,11 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReorderableList = void 0; -var react_1 = __importDefault(require("react")); -var react_beautiful_dnd_1 = require("react-beautiful-dnd"); +const react_1 = __importDefault(require("react")); +const react_beautiful_dnd_1 = require("react-beautiful-dnd"); /** List which provides drag and drop reordering */ function ReorderableList(props) { function onDragEnd(result) { @@ -27,18 +16,18 @@ function ReorderableList(props) { props.onItemsChange(reorder(props.items, result.source.index, result.destination.index)); } function renderDraggable(item, index) { - var id = props.getItemId(item); - return react_1.default.createElement(react_beautiful_dnd_1.Draggable, { key: id, draggableId: id, index: index }, function (provided, snapshot) { return (props.renderItem(item, index, provided.innerRef, provided.draggableProps, provided.dragHandleProps)); }); + const id = props.getItemId(item); + return react_1.default.createElement(react_beautiful_dnd_1.Draggable, { key: id, draggableId: id, index: index }, (provided, snapshot) => (props.renderItem(item, index, provided.innerRef, provided.draggableProps, provided.dragHandleProps))); } return react_1.default.createElement(react_beautiful_dnd_1.DragDropContext, { onDragEnd: onDragEnd }, - react_1.default.createElement(react_beautiful_dnd_1.Droppable, { droppableId: "abc" }, function (provided, snapshot) { return (react_1.default.createElement("div", __assign({}, provided.droppableProps, { ref: provided.innerRef }), + react_1.default.createElement(react_beautiful_dnd_1.Droppable, { droppableId: "abc" }, (provided, snapshot) => (react_1.default.createElement("div", Object.assign({}, provided.droppableProps, { ref: provided.innerRef }), props.items.map(renderDraggable), - provided.placeholder)); })); + provided.placeholder)))); } exports.ReorderableList = ReorderableList; function reorder(list, startIndex, endIndex) { - var result = list.slice(); - var removed = result.splice(startIndex, 1)[0]; + const result = list.slice(); + const [removed] = result.splice(startIndex, 1); result.splice(endIndex, 0, removed); return result; } diff --git a/lib/widgets/blocks/toc/SplitPane.js b/lib/widgets/blocks/toc/SplitPane.js index 63943145..aedb28a7 100644 --- a/lib/widgets/blocks/toc/SplitPane.js +++ b/lib/widgets/blocks/toc/SplitPane.js @@ -3,12 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var FillDownwardComponent_1 = __importDefault(require("react-library/lib/FillDownwardComponent")); +const react_1 = __importDefault(require("react")); +const FillDownwardComponent_1 = __importDefault(require("react-library/lib/FillDownwardComponent")); /** Pane that is split left right */ -var SplitPane = function (_a) { - var left = _a.left, right = _a.right, removePadding = _a.removePadding, theme = _a.theme; - var className = removePadding ? "toc-split remove-padding " + theme : "toc-split " + theme; +const SplitPane = ({ left, right, removePadding, theme }) => { + const className = removePadding ? `toc-split remove-padding ${theme}` : `toc-split ${theme}`; return react_1.default.createElement(FillDownwardComponent_1.default, null, react_1.default.createElement("div", { className: className }, react_1.default.createElement("div", { className: "toc-split-left" }, left), diff --git a/lib/widgets/blocks/toc/TOCDesignComp.js b/lib/widgets/blocks/toc/TOCDesignComp.js index 87459d1f..dbfcbb95 100644 --- a/lib/widgets/blocks/toc/TOCDesignComp.js +++ b/lib/widgets/blocks/toc/TOCDesignComp.js @@ -1,90 +1,77 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var react_1 = __importDefault(require("react")); -var toc_1 = require("./toc"); -var react_2 = require("react"); -var immer_1 = __importDefault(require("immer")); -var uuid_1 = __importDefault(require("uuid")); -var SplitPane_1 = __importDefault(require("./SplitPane")); -var TOCDesignRightPane_1 = require("./TOCDesignRightPane"); -var ReorderableList_1 = require("./ReorderableList"); +const react_1 = __importDefault(require("react")); +const toc_1 = require("./toc"); +const react_2 = require("react"); +const immer_1 = __importDefault(require("immer")); +const uuid_1 = __importDefault(require("uuid")); +const SplitPane_1 = __importDefault(require("./SplitPane")); +const TOCDesignRightPane_1 = require("./TOCDesignRightPane"); +const ReorderableList_1 = require("./ReorderableList"); /** Designer component for TOC */ function TOCDesignComp(props) { - var blockDef = props.blockDef, renderProps = props.renderProps; + const { blockDef, renderProps } = props; // Select first item by default - var _a = react_2.useState(blockDef.items[0] ? blockDef.items[0].id : null), selectedId = _a[0], setSelectedId = _a[1]; + const [selectedId, setSelectedId] = react_2.useState(blockDef.items[0] ? blockDef.items[0].id : null); // Select item - var handleItemClick = function (item) { setSelectedId(item.id); }; + const handleItemClick = (item) => { setSelectedId(item.id); }; /** Alter items using an action */ - var alterBlockItems = function (action) { - renderProps.store.replaceBlock(immer_1.default(blockDef, function (draft) { + const alterBlockItems = (action) => { + renderProps.store.replaceBlock(immer_1.default(blockDef, draft => { draft.items = toc_1.alterItems(blockDef.items, action); })); }; function handleSetItems(items) { - renderProps.store.replaceBlock(immer_1.default(blockDef, function (draft) { + renderProps.store.replaceBlock(immer_1.default(blockDef, draft => { draft.items = items; })); } - var handleAddItem = function () { - renderProps.store.replaceBlock(immer_1.default(blockDef, function (draft) { - var _a; + const handleAddItem = () => { + renderProps.store.replaceBlock(immer_1.default(blockDef, draft => { draft.items.push({ id: uuid_1.default(), - labelBlock: { type: "text", id: uuid_1.default.v4(), text: (_a = { _base: renderProps.locale }, _a[renderProps.locale] = "New Item", _a) }, + labelBlock: { type: "text", id: uuid_1.default.v4(), text: { _base: renderProps.locale, [renderProps.locale]: "New Item" } }, children: [], contextVarMap: {} }); })); }; - var handleHeaderSet = function (header) { - renderProps.store.replaceBlock(immer_1.default(blockDef, function (draft) { + const handleHeaderSet = (header) => { + renderProps.store.replaceBlock(immer_1.default(blockDef, draft => { draft.header = header; })); }; - var handleFooterSet = function (footer) { - renderProps.store.replaceBlock(immer_1.default(blockDef, function (draft) { + const handleFooterSet = (footer) => { + renderProps.store.replaceBlock(immer_1.default(blockDef, draft => { draft.footer = footer; })); }; - var setItemLabelBlock = function (itemId, labelBlock) { - alterBlockItems(function (item) { + const setItemLabelBlock = (itemId, labelBlock) => { + alterBlockItems((item) => { if (item.id === itemId) { - return __assign(__assign({}, item), { labelBlock: labelBlock }); + return Object.assign(Object.assign({}, item), { labelBlock }); } return item; }); }; function handleSetChildren(itemId, children) { - alterBlockItems(function (item) { + alterBlockItems((item) => { if (item.id === itemId) { - return __assign(__assign({}, item), { children: children }); + return Object.assign(Object.assign({}, item), { children }); } return item; }); } - var addChildItem = function (itemId) { - alterBlockItems(function (item) { + const addChildItem = (itemId) => { + alterBlockItems((item) => { if (item.id === itemId) { - return immer_1.default(item, function (draft) { - var _a; + return immer_1.default(item, draft => { draft.children.push({ id: uuid_1.default(), - labelBlock: { type: "text", id: uuid_1.default.v4(), text: (_a = { _base: renderProps.locale }, _a[renderProps.locale] = "New Item", _a) }, + labelBlock: { type: "text", id: uuid_1.default.v4(), text: { _base: renderProps.locale, [renderProps.locale]: "New Item" } }, children: [] }); }); @@ -92,17 +79,17 @@ function TOCDesignComp(props) { return item; }); }; - var deleteItem = function (itemId) { - alterBlockItems(function (item) { return item.id === itemId ? null : item; }); + const deleteItem = (itemId) => { + alterBlockItems((item) => item.id === itemId ? null : item); }; // Render the dropdown gear menu to edit an entry - var renderCaretMenu = function (item) { + const renderCaretMenu = (item) => { return react_1.default.createElement(CaretMenu, { items: [ - { label: "Add Subitem", onClick: function () { return addChildItem(item.id); } }, - { label: "Delete", onClick: function () { return deleteItem(item.id); } } + { label: "Add Subitem", onClick: () => addChildItem(item.id) }, + { label: "Delete", onClick: () => deleteItem(item.id) } ] }); }; - var renderLeft = function () { + const renderLeft = () => { return react_1.default.createElement("div", { style: { padding: 10 } }, renderProps.renderChildBlock(renderProps, blockDef.header, handleHeaderSet), renderItems(blockDef.items, 0, handleSetItems), @@ -112,20 +99,20 @@ function TOCDesignComp(props) { renderProps.renderChildBlock(renderProps, blockDef.footer, handleFooterSet)); }; function renderItems(items, depth, onItemsChange) { - return react_1.default.createElement(ReorderableList_1.ReorderableList, { items: items, onItemsChange: onItemsChange, getItemId: function (item) { return item.id; }, renderItem: function (item, index, innerRef, draggableProps, dragHandleProps) { return (react_1.default.createElement("div", __assign({}, draggableProps, { ref: innerRef }), renderItem(item, index, depth, dragHandleProps))); } }); + return react_1.default.createElement(ReorderableList_1.ReorderableList, { items: items, onItemsChange: onItemsChange, getItemId: item => item.id, renderItem: (item, index, innerRef, draggableProps, dragHandleProps) => (react_1.default.createElement("div", Object.assign({}, draggableProps, { ref: innerRef }), renderItem(item, index, depth, dragHandleProps))) }); } /** Render an item at a specified depth which starts at 0 */ function renderItem(item, index, depth, dragHandleProps) { - var labelClasses = ["toc-item-label", "toc-item-label-level" + depth]; + const labelClasses = ["toc-item-label", `toc-item-label-level${depth}`]; if (item.id === selectedId) { - labelClasses.push("toc-item-label-selected bg-primary"); + labelClasses.push(`toc-item-label-selected bg-primary`); } if (item.widgetId) { labelClasses.push("toc-item-label-selectable"); } - return react_1.default.createElement("div", { className: "toc-item toc-item-level" + depth }, + return react_1.default.createElement("div", { className: `toc-item toc-item-level${depth}` }, react_1.default.createElement("div", { key: "main", className: labelClasses.join(" "), style: { display: "grid", gridTemplateColumns: "auto auto 1fr auto", alignItems: "center" }, onClick: handleItemClick.bind(null, item) }, - react_1.default.createElement("div", __assign({ style: { cursor: "pointer", paddingTop: 2, paddingLeft: 5 } }, dragHandleProps), + react_1.default.createElement("div", Object.assign({ style: { cursor: "pointer", paddingTop: 2, paddingLeft: 5 } }, dragHandleProps), react_1.default.createElement("i", { className: "fa fa-bars text-muted" })), react_1.default.createElement("div", null, renderProps.renderChildBlock(renderProps, item.labelBlock || null, setItemLabelBlock.bind(null, item.id))), renderCaretMenu(item)), @@ -134,13 +121,13 @@ function TOCDesignComp(props) { : null); } // Get selected item - var selectedItem = toc_1.iterateItems(blockDef.items).find(function (item) { return item.id === selectedId; }); - var renderRight = function () { + const selectedItem = toc_1.iterateItems(blockDef.items).find(item => item.id === selectedId); + const renderRight = () => { if (!selectedItem) { return null; } - return react_1.default.createElement(TOCDesignRightPane_1.TOCDesignRightPane, { item: selectedItem, renderProps: renderProps, onItemChange: function (item) { - alterBlockItems(function (draft) { + return react_1.default.createElement(TOCDesignRightPane_1.TOCDesignRightPane, { item: selectedItem, renderProps: renderProps, onItemChange: item => { + alterBlockItems(draft => { if (draft.id == selectedItem.id) { return item; } @@ -153,11 +140,11 @@ function TOCDesignComp(props) { } exports.default = TOCDesignComp; /** Drop down menu that shows as a downward caret */ -var CaretMenu = function (props) { +const CaretMenu = (props) => { return react_1.default.createElement("div", { className: "btn-group" }, react_1.default.createElement("button", { type: "button", className: "btn btn-link btn-xs dropdown-toggle", "data-toggle": "dropdown" }, react_1.default.createElement("i", { className: "fa fa-caret-down" })), - react_1.default.createElement("ul", { className: "dropdown-menu" }, props.items.map(function (item, index) { + react_1.default.createElement("ul", { className: "dropdown-menu" }, props.items.map((item, index) => { return react_1.default.createElement("li", { key: index }, react_1.default.createElement("a", { onClick: item.onClick }, item.label)); }))); diff --git a/lib/widgets/blocks/toc/TOCDesignRightPane.js b/lib/widgets/blocks/toc/TOCDesignRightPane.js index bdf345ee..9e640981 100644 --- a/lib/widgets/blocks/toc/TOCDesignRightPane.js +++ b/lib/widgets/blocks/toc/TOCDesignRightPane.js @@ -1,75 +1,63 @@ "use strict"; -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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TOCDesignRightPane = void 0; -var react_1 = __importDefault(require("react")); -var lodash_1 = __importDefault(require("lodash")); -var immer_1 = __importDefault(require("immer")); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); +const react_1 = __importDefault(require("react")); +const lodash_1 = __importDefault(require("lodash")); +const immer_1 = __importDefault(require("immer")); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); function TOCDesignRightPane(props) { - var item = props.item, onItemChange = props.onItemChange, renderProps = props.renderProps; - var selectedWidgetId = item.widgetId; - var handleLabelBlockChange = function (labelBlock) { - onItemChange(immer_1.default(item, function (draft) { + const { item, onItemChange, renderProps } = props; + const selectedWidgetId = item.widgetId; + const handleLabelBlockChange = (labelBlock) => { + onItemChange(immer_1.default(item, draft => { draft.labelBlock = labelBlock; })); }; - var handleWidgetIdChange = function (widgetId) { - onItemChange(immer_1.default(item, function (draft) { + const handleWidgetIdChange = (widgetId) => { + onItemChange(immer_1.default(item, draft => { draft.widgetId = widgetId; })); }; - var handleTitleChange = function (title) { - onItemChange(immer_1.default(item, function (draft) { + const handleTitleChange = (title) => { + onItemChange(immer_1.default(item, draft => { draft.title = title; })); }; - var handleContextVarMapChange = function (contextVarMap) { - onItemChange(immer_1.default(item, function (draft) { + const handleContextVarMapChange = (contextVarMap) => { + onItemChange(immer_1.default(item, draft => { draft.contextVarMap = contextVarMap; })); }; - var handleConditionChange = function (condition) { - onItemChange(immer_1.default(item, function (draft) { + const handleConditionChange = (condition) => { + onItemChange(immer_1.default(item, draft => { draft.condition = condition; })); }; // Create widget options - var widgetOptions = lodash_1.default.sortByAll(Object.values(renderProps.widgetLibrary.widgets), "group", "name").map(function (w) { return ({ label: (w.group ? w.group + ": " : "") + w.name, value: w.id }); }); - var renderContextVarValues = function () { + const widgetOptions = lodash_1.default.sortByAll(Object.values(renderProps.widgetLibrary.widgets), "group", "name").map(w => ({ label: (w.group ? `${w.group}: ` : "") + w.name, value: w.id })); + const renderContextVarValues = () => { if (!item.widgetId) { return null; } // Find the widget - var widgetDef = renderProps.widgetLibrary.widgets[item.widgetId]; + const widgetDef = renderProps.widgetLibrary.widgets[item.widgetId]; if (!widgetDef) { return null; } - var contextVarMap = item.contextVarMap || {}; + const contextVarMap = item.contextVarMap || {}; return (react_1.default.createElement("table", { className: "table table-bordered table-condensed" }, - react_1.default.createElement("tbody", null, widgetDef.contextVars.map(function (contextVar) { - var cv = contextVarMap[contextVar.id]; - var handleCVChange = function (contextVarId) { - var _a; + react_1.default.createElement("tbody", null, widgetDef.contextVars.map(contextVar => { + const cv = contextVarMap[contextVar.id]; + const handleCVChange = (contextVarId) => { if (contextVarId) { - handleContextVarMapChange(__assign(__assign({}, contextVarMap), (_a = {}, _a[contextVar.id] = contextVarId, _a))); + handleContextVarMapChange(Object.assign(Object.assign({}, contextVarMap), { [contextVar.id]: contextVarId })); } else { - handleContextVarMapChange(immer_1.default(contextVarMap, function (draft) { delete draft[contextVar.id]; })); + handleContextVarMapChange(immer_1.default(contextVarMap, draft => { delete draft[contextVar.id]; })); } }; return (react_1.default.createElement("tr", { key: contextVar.id }, @@ -87,7 +75,7 @@ function TOCDesignRightPane(props) { react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Variable Mappings" }, renderContextVarValues()), item.children.length > 0 ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Collapse/Expand" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: item, onChange: onItemChange, property: "collapse" }, function (value, onChange) { + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: item, onChange: onItemChange, property: "collapse" }, (value, onChange) => { return react_1.default.createElement(bootstrap_1.Toggle, { value: value || "expanded", onChange: onChange, options: [ { value: "expanded", label: "Always Expanded" }, { value: "startExpanded", label: "Start Expanded" }, @@ -96,6 +84,6 @@ function TOCDesignRightPane(props) { })) : null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Conditional display (optional)" }, - react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { schema: renderProps.schema, dataSource: renderProps.dataSource, contextVars: renderProps.contextVars, contextVarId: item.condition ? item.condition.contextVarId : null, expr: item.condition ? item.condition.expr : null, onChange: function (contextVarId, expr) { handleConditionChange({ contextVarId: contextVarId, expr: expr }); }, types: ["boolean"] })))); + react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { schema: renderProps.schema, dataSource: renderProps.dataSource, contextVars: renderProps.contextVars, contextVarId: item.condition ? item.condition.contextVarId : null, expr: item.condition ? item.condition.expr : null, onChange: (contextVarId, expr) => { handleConditionChange({ contextVarId, expr }); }, types: ["boolean"] })))); } exports.TOCDesignRightPane = TOCDesignRightPane; diff --git a/lib/widgets/blocks/toc/TOCInstanceComp.js b/lib/widgets/blocks/toc/TOCInstanceComp.js index 16684c35..4b0690b6 100644 --- a/lib/widgets/blocks/toc/TOCInstanceComp.js +++ b/lib/widgets/blocks/toc/TOCInstanceComp.js @@ -3,29 +3,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var lodash_1 = __importDefault(require("lodash")); -var toc_1 = require("./toc"); -var blocks_1 = require("../../blocks"); -var react_1 = require("react"); -var localization_1 = require("../../localization"); -var SplitPane_1 = __importDefault(require("./SplitPane")); -var react_2 = __importDefault(require("react")); -var PageStackDisplay_1 = require("../../../PageStackDisplay"); -var mwater_expressions_1 = require("mwater-expressions"); +const lodash_1 = __importDefault(require("lodash")); +const toc_1 = require("./toc"); +const blocks_1 = require("../../blocks"); +const react_1 = require("react"); +const localization_1 = require("../../localization"); +const SplitPane_1 = __importDefault(require("./SplitPane")); +const react_2 = __importDefault(require("react")); +const PageStackDisplay_1 = require("../../../PageStackDisplay"); +const mwater_expressions_1 = require("mwater-expressions"); /** Instance component for TOC */ function TOCInstanceComp(props) { - var blockDef = props.blockDef, instanceCtx = props.instanceCtx; + const { blockDef, instanceCtx } = props; // Ref to page stack to ensure closed properly - var pageStackRef = react_1.useRef(null); + const pageStackRef = react_1.useRef(null); // Select first item with widget by default - var firstItem = toc_1.iterateItems(blockDef.items).find(function (item) { return item.widgetId; }); - var _a = react_1.useState(firstItem ? firstItem.id : null), selectedId = _a[0], setSelectedId = _a[1]; + const firstItem = toc_1.iterateItems(blockDef.items).find(item => item.widgetId); + const [selectedId, setSelectedId] = react_1.useState(firstItem ? firstItem.id : null); // Store collapsed state for items. If not listed, is expanded - var _b = react_1.useState(function () { - return toc_1.iterateItems(blockDef.items).filter(function (item) { return item.collapse == "startCollapsed"; }).map(function (item) { return item.id; }); - }), collapsedItems = _b[0], setCollapsedItems = _b[1]; + const [collapsedItems, setCollapsedItems] = react_1.useState(() => { + return toc_1.iterateItems(blockDef.items).filter(item => item.collapse == "startCollapsed").map(item => item.id); + }); // Select item - var handleItemClick = function (item) { + const handleItemClick = (item) => { // Toggle collapse if (item.children.length > 0 && (item.collapse == "startCollapsed" || item.collapse == "startExpanded")) { if (collapsedItems.includes(item.id)) { @@ -52,26 +52,26 @@ function TOCInstanceComp(props) { setSelectedId(item.id); }; /** Render an item at a specified depth which starts at 0 */ - var renderItem = function (items, index, depth) { - var item = items[index]; + const renderItem = (items, index, depth) => { + const item = items[index]; // Determine if visible if (item.condition && item.condition.expr) { - var conditionValue = instanceCtx.getContextVarExprValue(item.condition.contextVarId, item.condition.expr); + const conditionValue = instanceCtx.getContextVarExprValue(item.condition.contextVarId, item.condition.expr); if (conditionValue !== true) { return null; } } - var collapsible = item.children.length > 0 && (item.collapse == "startCollapsed" || item.collapse == "startExpanded"); - var labelClasses = ["toc-item-label", "toc-item-label-level" + depth]; + const collapsible = item.children.length > 0 && (item.collapse == "startCollapsed" || item.collapse == "startExpanded"); + const labelClasses = ["toc-item-label", `toc-item-label-level${depth}`]; if (item.id === selectedId) { - labelClasses.push("toc-item-label-selected bg-primary"); + labelClasses.push(`toc-item-label-selected bg-primary`); } if (item.widgetId || collapsible) { labelClasses.push("toc-item-label-selectable"); } // Determine if collapsed - var collapsed = collapsedItems.includes(item.id); - return react_2.default.createElement("div", { key: item.id, className: "toc-item toc-item-level" + depth }, + const collapsed = collapsedItems.includes(item.id); + return react_2.default.createElement("div", { key: item.id, className: `toc-item toc-item-level${depth}` }, react_2.default.createElement("div", { key: "label", className: labelClasses.join(" "), onClick: handleItemClick.bind(null, item) }, react_2.default.createElement("div", { key: "expand", className: "chevron" }, collapsible ? (collapsed ? react_2.default.createElement("i", { className: "fas fa-fw fa-caret-right" }) : react_2.default.createElement("i", { className: "fas fa-fw fa-caret-down" })) @@ -81,43 +81,44 @@ function TOCInstanceComp(props) { : instanceCtx.renderChildBlock(instanceCtx, item.labelBlock || null)), item.children.length > 0 && !collapsed ? - react_2.default.createElement("div", { key: "children", className: "toc-item-children" }, item.children.map(function (child, index) { return renderItem(item.children, index, depth + 1); })) + react_2.default.createElement("div", { key: "children", className: "toc-item-children" }, item.children.map((child, index) => renderItem(item.children, index, depth + 1))) : null); }; - var renderLeft = function () { + const renderLeft = () => { return react_2.default.createElement("div", null, react_2.default.createElement("div", { key: "header", style: { padding: 5 } }, instanceCtx.renderChildBlock(instanceCtx, blockDef.header)), - blockDef.items.map(function (item, index) { return renderItem(blockDef.items, index, 0); }), + blockDef.items.map((item, index) => renderItem(blockDef.items, index, 0)), react_2.default.createElement("div", { key: "footer", style: { padding: 5 } }, instanceCtx.renderChildBlock(instanceCtx, blockDef.footer))); }; // Get selected item - var selectedItem = toc_1.iterateItems(blockDef.items).find(function (item) { return item.id === selectedId; }); - var selectedWidgetId = selectedItem ? selectedItem.widgetId : null; - var renderRight = function () { + const selectedItem = toc_1.iterateItems(blockDef.items).find(item => item.id === selectedId); + const selectedWidgetId = selectedItem ? selectedItem.widgetId : null; + const renderRight = () => { if (!selectedId || !selectedWidgetId || !selectedItem) { return null; } // Get widget - var widget = instanceCtx.widgetLibrary.widgets[selectedWidgetId]; + const widget = instanceCtx.widgetLibrary.widgets[selectedWidgetId]; // Map context var values - var mappedContextVarValues = {}; - var _loop_1 = function (innerContextVar) { - var outerContextVarId = (selectedItem.contextVarMap || {})[innerContextVar.id]; + const mappedContextVarValues = {}; + // For each context variable that the widget needs + for (const innerContextVar of widget.contextVars) { + const outerContextVarId = (selectedItem.contextVarMap || {})[innerContextVar.id]; if (outerContextVarId) { // Look up outer context variable - var outerCV = instanceCtx.contextVars.find(function (cv) { return cv.id == outerContextVarId; }); + const outerCV = instanceCtx.contextVars.find(cv => cv.id == outerContextVarId); if (!outerCV) { throw new Error("Outer context variable not found"); } // Get value - var outerCVValue = instanceCtx.contextVarValues[outerCV.id]; + let outerCVValue = instanceCtx.contextVarValues[outerCV.id]; // Add filters if rowset if (outerCV.type == "rowset") { outerCVValue = { type: "op", op: "and", table: outerCV.table, - exprs: lodash_1.default.compact([outerCVValue].concat(lodash_1.default.map(instanceCtx.getFilters(outerCV.id), function (f) { return f.expr; }))) + exprs: lodash_1.default.compact([outerCVValue].concat(lodash_1.default.map(instanceCtx.getFilters(outerCV.id), f => f.expr))) }; } // Inline variables used in rowsets as they may depend on context variables that aren't present in new page @@ -129,18 +130,12 @@ function TOCInstanceComp(props) { else { mappedContextVarValues[innerContextVar.id] = null; } - }; - // For each context variable that the widget needs - for (var _i = 0, _a = widget.contextVars; _i < _a.length; _i++) { - var innerContextVar = _a[_i]; - _loop_1(innerContextVar); } // Include global context variables - for (var _b = 0, _c = props.instanceCtx.globalContextVars || []; _b < _c.length; _b++) { - var globalContextVar = _c[_b]; + for (const globalContextVar of props.instanceCtx.globalContextVars || []) { mappedContextVarValues[globalContextVar.id] = props.instanceCtx.contextVarValues[globalContextVar.id]; } - var page = { + const page = { contextVarValues: mappedContextVarValues, database: instanceCtx.database, type: "normal", diff --git a/lib/widgets/blocks/toc/toc.js b/lib/widgets/blocks/toc/toc.js index e893ce7e..aceaebd3 100644 --- a/lib/widgets/blocks/toc/toc.js +++ b/lib/widgets/blocks/toc/toc.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,79 +23,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TOCBlock = exports.alterItems = exports.iterateItems = void 0; -var React = __importStar(require("react")); -var _ = __importStar(require("lodash")); -var blocks_1 = require("../../blocks"); -var immer_1 = require("immer"); -var TOCDesignComp_1 = __importDefault(require("./TOCDesignComp")); -var TOCInstanceComp_1 = __importDefault(require("./TOCInstanceComp")); +const React = __importStar(require("react")); +const _ = __importStar(require("lodash")); +const blocks_1 = require("../../blocks"); +const immer_1 = require("immer"); +const TOCDesignComp_1 = __importDefault(require("./TOCDesignComp")); +const TOCInstanceComp_1 = __importDefault(require("./TOCInstanceComp")); require("./toc.css"); -var propertyEditors_1 = require("../../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var uuid_1 = __importDefault(require("uuid")); +const propertyEditors_1 = require("../../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const uuid_1 = __importDefault(require("uuid")); /** Create a flat list of all items */ -exports.iterateItems = function (items) { +exports.iterateItems = (items) => { var flatItems = []; - for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { - var item = items_1[_i]; + for (const item of items) { flatItems.push(item); flatItems = flatItems.concat(exports.iterateItems(item.children)); } return flatItems; }; /** Alter each item, allowing item to be mutated, replaced (return item or array of items) or deleted (return null) */ -exports.alterItems = function (items, action) { - var newItems = _.flatten(_.compact(items.map(function (item) { return action(item); }))); - return immer_1.produce(newItems, function (draft) { - for (var _i = 0, draft_1 = draft; _i < draft_1.length; _i++) { - var ni = draft_1[_i]; +exports.alterItems = (items, action) => { + const newItems = _.flatten(_.compact(items.map(item => action(item)))); + return immer_1.produce(newItems, draft => { + for (const ni of draft) { ni.children = exports.alterItems(immer_1.original(ni.children), action); } }); }; -var TOCBlock = /** @class */ (function (_super) { - __extends(TOCBlock, _super); - function TOCBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } +class TOCBlock extends blocks_1.Block { /** Get child blocks */ - TOCBlock.prototype.getChildren = function (contextVars) { + getChildren(contextVars) { // Iterate all - return _.compact([this.blockDef.header, this.blockDef.footer].concat(exports.iterateItems(this.blockDef.items).map(function (item) { return item.labelBlock || null; }))) - .map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; + return _.compact([this.blockDef.header, this.blockDef.footer].concat(exports.iterateItems(this.blockDef.items).map(item => item.labelBlock || null))) + .map(bd => ({ blockDef: bd, contextVars: contextVars })); + } /** Get any context variables expressions that this block needs (not including child blocks) */ - TOCBlock.prototype.getContextVarExprs = function (contextVar, ctx) { - return _.compact(exports.iterateItems(this.blockDef.items).map(function (item) { return item.condition && item.condition.contextVarId == contextVar.id ? item.condition.expr : null; })); - }; + getContextVarExprs(contextVar, ctx) { + return _.compact(exports.iterateItems(this.blockDef.items).map(item => item.condition && item.condition.contextVarId == contextVar.id ? item.condition.expr : null)); + } /** Validate a single TOC item */ - TOCBlock.prototype.validateItem = function (designCtx, tocItem) { + validateItem(designCtx, tocItem) { if (tocItem.widgetId) { // Check that widget exists - var widget = designCtx.widgetLibrary.widgets[tocItem.widgetId]; + const widget = designCtx.widgetLibrary.widgets[tocItem.widgetId]; if (!widget) { return "Widget does not exist"; } - var _loop_1 = function (innerContextVar) { + // For each inner context variable + for (const innerContextVar of widget.contextVars) { // If mapped, check that outer context var exists if (tocItem.contextVarMap && tocItem.contextVarMap[innerContextVar.id]) { - var outerContextVarId_1 = tocItem.contextVarMap[innerContextVar.id]; - if (!designCtx.contextVars.find(function (cv) { return cv.id == outerContextVarId_1; })) { - return { value: "Context variable not found. Please check mapping" }; + const outerContextVarId = tocItem.contextVarMap[innerContextVar.id]; + if (!designCtx.contextVars.find(cv => cv.id == outerContextVarId)) { + return "Context variable not found. Please check mapping"; } } - }; - // For each inner context variable - for (var _i = 0, _a = widget.contextVars; _i < _a.length; _i++) { - var innerContextVar = _a[_i]; - var state_1 = _loop_1(innerContextVar); - if (typeof state_1 === "object") - return state_1.value; } } // Validate condition if (tocItem.condition) { - var error = blocks_1.validateContextVarExpr({ + const error = blocks_1.validateContextVarExpr({ contextVars: designCtx.contextVars, schema: designCtx.schema, contextVarId: tocItem.condition.contextVarId, @@ -117,65 +92,60 @@ var TOCBlock = /** @class */ (function (_super) { types: ["boolean"] }); if (error) { - return "Error in condition: " + error; + return `Error in condition: ${error}`; } } return null; - }; - TOCBlock.prototype.validate = function (designCtx) { + } + validate(designCtx) { // Validate all items - for (var _i = 0, _a = exports.iterateItems(this.blockDef.items); _i < _a.length; _i++) { - var tocItem = _a[_i]; - var error = this.validateItem(designCtx, tocItem); + for (const tocItem of exports.iterateItems(this.blockDef.items)) { + const error = this.validateItem(designCtx, tocItem); if (error) { return error; } } return null; - }; - TOCBlock.prototype.processChildren = function (action) { - var _this = this; - return immer_1.produce(this.blockDef, function (draft) { + } + processChildren(action) { + return immer_1.produce(this.blockDef, (draft) => { // For header and footer - draft.header = action(_this.blockDef.header); - draft.footer = action(_this.blockDef.footer); + draft.header = action(this.blockDef.header); + draft.footer = action(this.blockDef.footer); // For all other blocks - for (var _i = 0, _a = exports.iterateItems(draft.items); _i < _a.length; _i++) { - var item = _a[_i]; + for (const item of exports.iterateItems(draft.items)) { item.labelBlock = action(immer_1.original(item.labelBlock) || null); } }); - }; + } /** Canonicalize the block definition. Should be done after operations on the block are completed. Only alter self, not children. * Can also be used to upgrade blocks */ - TOCBlock.prototype.canonicalize = function () { + canonicalize() { // Upgrade any labels to labelBlocks - return immer_1.produce(this.blockDef, function (draft) { - for (var _i = 0, _a = exports.iterateItems(draft.items); _i < _a.length; _i++) { - var item = _a[_i]; + return immer_1.produce(this.blockDef, draft => { + for (const item of exports.iterateItems(draft.items)) { if (item.label && !item.labelBlock) { item.labelBlock = { type: "text", text: item.label, id: uuid_1.default.v4() }; delete item.label; } } }); - }; - TOCBlock.prototype.renderDesign = function (props) { + } + renderDesign(props) { return React.createElement(TOCDesignComp_1.default, { renderProps: props, blockDef: this.blockDef }); - }; - TOCBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return React.createElement(TOCInstanceComp_1.default, { instanceCtx: props, blockDef: this.blockDef, createBlock: props.createBlock }); - }; - TOCBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (React.createElement("div", null, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "removePadding" }, function (value, onChange) { return React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Remove Padding (for top-level TOCs)"); }), + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "removePadding" }, (value, onChange) => React.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Remove Padding (for top-level TOCs)")), React.createElement(propertyEditors_1.LabeledProperty, { label: "Theme" }, - React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "theme" }, function (value, onChange) { return (React.createElement(bootstrap_1.Toggle, { value: value || "light", onChange: onChange, options: [ + React.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "theme" }, (value, onChange) => (React.createElement(bootstrap_1.Toggle, { value: value || "light", onChange: onChange, options: [ { value: "light", label: "Light" }, { value: "dark", label: "Dark" } - ] })); })))); - }; - return TOCBlock; -}(blocks_1.Block)); + ] })))))); + } +} exports.TOCBlock = TOCBlock; diff --git a/lib/widgets/blocks/toggleFilter.js b/lib/widgets/blocks/toggleFilter.js index 301bf1d4..66e2dc53 100644 --- a/lib/widgets/blocks/toggleFilter.js +++ b/lib/widgets/blocks/toggleFilter.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -42,120 +18,98 @@ var __importStar = (this && this.__importStar) || function (mod) { __setModuleDefault(result, mod); return result; }; -var __spreadArrays = (this && this.__spreadArrays) || function () { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; -}; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ToggleFilterBlock = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importStar(require("react")); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var blocks_1 = require("../blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var propertyEditors_1 = require("../propertyEditors"); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var localization_1 = require("../localization"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var ListEditor_1 = __importDefault(require("../ListEditor")); +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importStar(require("react")); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const blocks_1 = require("../blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const propertyEditors_1 = require("../propertyEditors"); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const localization_1 = require("../localization"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const ListEditor_1 = __importDefault(require("../ListEditor")); /** Dropdown that filters one or more rowsets. The value of the filter is stored in the memo of the rowset filter * and depends on which type of filter it is. */ -var ToggleFilterBlock = /** @class */ (function (_super) { - __extends(ToggleFilterBlock, _super); - function ToggleFilterBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ToggleFilterBlock.prototype.validate = function (options) { +class ToggleFilterBlock extends LeafBlock_1.default { + validate(options) { // Check that at least one option if (this.blockDef.options.length == 0) { return "At least one option required"; } - for (var _i = 0, _a = this.blockDef.options; _i < _a.length; _i++) { - var option = _a[_i]; - var _loop_1 = function (filter) { + for (const option of this.blockDef.options) { + // Validate filters + for (const filter of option.filters) { // Validate rowset - var rowsetCV = options.contextVars.find(function (cv) { return cv.id === filter.rowsetContextVarId && cv.type === "rowset"; }); + const rowsetCV = options.contextVars.find(cv => cv.id === filter.rowsetContextVarId && cv.type === "rowset"); if (!rowsetCV) { - return { value: "Rowset required" }; + return "Rowset required"; } - var exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); - var error = exprValidator.validateExpr(filter.filterExpr, { table: rowsetCV.table, types: ["boolean"] }); + const exprValidator = new mwater_expressions_1.ExprValidator(options.schema, blocks_1.createExprVariables(options.contextVars)); + const error = exprValidator.validateExpr(filter.filterExpr, { table: rowsetCV.table, types: ["boolean"] }); if (error) { - return { value: error }; + return error; } - }; - // Validate filters - for (var _b = 0, _c = option.filters; _b < _c.length; _b++) { - var filter = _c[_b]; - var state_1 = _loop_1(filter); - if (typeof state_1 === "object") - return state_1.value; } // Ensure that a max of one filter per rowset - if (lodash_1.default.uniq(option.filters.map(function (f) { return f.rowsetContextVarId; })).length < option.filters.length) { + if (lodash_1.default.uniq(option.filters.map(f => f.rowsetContextVarId)).length < option.filters.length) { return "Maximum of one filter per rowset per option"; } } return null; - }; - ToggleFilterBlock.prototype.canonicalize = function () { + } + canonicalize() { if (this.blockDef.forceSelection && this.blockDef.options.length > 0 && this.blockDef.initialOption == null) { - return __assign(__assign({}, this.blockDef), { initialOption: 0 }); + return Object.assign(Object.assign({}, this.blockDef), { initialOption: 0 }); } return this.blockDef; - }; - ToggleFilterBlock.prototype.renderDesign = function (props) { - var _this = this; - var options = this.blockDef.options.map(function (o, index) { return ({ value: index, label: localization_1.localize(o.label, props.locale) }); }); - return react_1.default.createElement(bootstrap_1.Toggle, { options: options, value: this.blockDef.initialOption, onChange: function (index) { return props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { initialOption: index })); }, allowReset: !this.blockDef.forceSelection, size: mapToggleSize(this.blockDef.size) }); - }; - ToggleFilterBlock.prototype.renderInstance = function (ctx) { + } + renderDesign(props) { + const options = this.blockDef.options.map((o, index) => ({ value: index, label: localization_1.localize(o.label, props.locale) })); + return react_1.default.createElement(bootstrap_1.Toggle, { options: options, value: this.blockDef.initialOption, onChange: index => props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { initialOption: index })), allowReset: !this.blockDef.forceSelection, size: mapToggleSize(this.blockDef.size) }); + } + renderInstance(ctx) { return react_1.default.createElement(ToggleFilterInstance, { blockDef: this.blockDef, ctx: ctx }); - }; - ToggleFilterBlock.prototype.renderEditor = function (props) { + } + renderEditor(props) { return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Size" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "size" }, function (value, onChange) { - return react_1.default.createElement(bootstrap_1.Toggle, { value: value || "normal", onChange: onChange, options: [ - { value: "normal", label: "Default" }, - { value: "small", label: "Small" }, - { value: "extrasmall", label: "Extra-small" }, - { value: "large", label: "Large" } - ] }); - })), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "forceSelection", key: "forceSelection" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Force Selection"); }), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "size" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Toggle, { value: value || "normal", onChange: onChange, options: [ + { value: "normal", label: "Default" }, + { value: "small", label: "Small" }, + { value: "extrasmall", label: "Extra-small" }, + { value: "large", label: "Large" } + ] }))), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "forceSelection", key: "forceSelection" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Force Selection")), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Options", key: "options" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "options" }, function (value, onOptionsChange) { - var handleAddSearchExpr = function () { + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "options" }, (value, onOptionsChange) => { + const handleAddSearchExpr = () => { onOptionsChange((value || []).concat({ label: { _base: "en", en: "Option" }, filters: [] })); }; return (react_1.default.createElement("div", null, - react_1.default.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onOptionsChange }, function (option, onOptionChange) { return (react_1.default.createElement(EditOptionComponent, { option: option, contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, onChange: onOptionChange, locale: props.locale })); }), + react_1.default.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onOptionsChange }, (option, onOptionChange) => (react_1.default.createElement(EditOptionComponent, { option: option, contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, onChange: onOptionChange, locale: props.locale }))), react_1.default.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddSearchExpr }, "+ Add Option"))); })))); - }; - return ToggleFilterBlock; -}(LeafBlock_1.default)); + } +} exports.ToggleFilterBlock = ToggleFilterBlock; /** Edits a single toggle option */ function EditOptionComponent(props) { return react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Label", key: "label" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.option, onChange: props.onChange, property: "label" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.option, onChange: props.onChange, property: "label" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Filters", key: "filters" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.option, onChange: props.onChange, property: "filters" }, function (value, onChange) { + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.option, onChange: props.onChange, property: "filters" }, (value, onChange) => { function handleAddFilter() { - onChange(__spreadArrays(value, [{ rowsetContextVarId: null, filterExpr: null }])); + onChange([...value, { rowsetContextVarId: null, filterExpr: null }]); } return react_1.default.createElement("div", null, - react_1.default.createElement(ListEditor_1.default, { items: value, onItemsChange: onChange }, function (filter, onFilterChange) { + react_1.default.createElement(ListEditor_1.default, { items: value, onItemsChange: onChange }, (filter, onFilterChange) => { return react_1.default.createElement(EditFilterComponent, { filter: filter, onChange: onFilterChange, contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource }); }), react_1.default.createElement("button", { type: "button", className: "btn btn-link btn-xs", onClick: handleAddFilter }, "+ Add Filter")); @@ -163,26 +117,27 @@ function EditOptionComponent(props) { } /** Edits a single filter of an option */ function EditFilterComponent(props) { - var extraFilterCV = props.contextVars.find(function (cv) { return cv.id === props.filter.rowsetContextVarId; }); + const extraFilterCV = props.contextVars.find(cv => cv.id === props.filter.rowsetContextVarId); return react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Rowset" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.filter, onChange: props.onChange, property: "rowsetContextVarId" }, function (value, onChange) { return react_1.default.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }); })), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.filter, onChange: props.onChange, property: "rowsetContextVarId" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.ContextVarPropertyEditor, { value: value, onChange: onChange, contextVars: props.contextVars, types: ["rowset"] }))), extraFilterCV ? react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Filter expression" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.filter, onChange: props.onChange, property: "filterExpr" }, function (value, onChange) { return react_1.default.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, schema: props.schema, dataSource: props.dataSource, onChange: onChange, table: extraFilterCV.table, variables: blocks_1.createExprVariables(props.contextVars), types: ["boolean"] }); })) + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.filter, onChange: props.onChange, property: "filterExpr" }, (value, onChange) => react_1.default.createElement(mwater_expressions_ui_1.ExprComponent, { value: value, schema: props.schema, dataSource: props.dataSource, onChange: onChange, table: extraFilterCV.table, variables: blocks_1.createExprVariables(props.contextVars), types: ["boolean"] }))) : null); } function ToggleFilterInstance(props) { - var blockDef = props.blockDef, ctx = props.ctx; - var _a = react_1.useState(blockDef.initialOption), selectedIndex = _a[0], setSelectedIndex = _a[1]; + const { blockDef, ctx } = props; + const [selectedIndex, setSelectedIndex] = react_1.useState(blockDef.initialOption); // Set filter - react_1.useEffect(function () { + react_1.useEffect(() => { // Get all rowset variables possibly used - var rowsetCVIds = lodash_1.default.uniq(lodash_1.default.flattenDeep(blockDef.options.map(function (o) { return o.filters; }).map(function (fs) { return fs.map(function (f) { return f.rowsetContextVarId; }); }))); - var _loop_2 = function (rowsetCVId) { + const rowsetCVIds = lodash_1.default.uniq(lodash_1.default.flattenDeep(blockDef.options.map(o => o.filters).map(fs => fs.map(f => f.rowsetContextVarId)))); + // For each rowset + for (const rowsetCVId of rowsetCVIds) { // Determine filter - var option = selectedIndex != null ? blockDef.options[selectedIndex] : null; - var filter = option ? option.filters.find(function (f) { return f.rowsetContextVarId == rowsetCVId; }) : null; + const option = selectedIndex != null ? blockDef.options[selectedIndex] : null; + const filter = option ? option.filters.find(f => f.rowsetContextVarId == rowsetCVId) : null; if (filter) { ctx.setFilter(rowsetCVId, { id: blockDef.id, @@ -195,14 +150,9 @@ function ToggleFilterInstance(props) { expr: null }); } - }; - // For each rowset - for (var _i = 0, rowsetCVIds_1 = rowsetCVIds; _i < rowsetCVIds_1.length; _i++) { - var rowsetCVId = rowsetCVIds_1[_i]; - _loop_2(rowsetCVId); } }, [selectedIndex]); - var options = blockDef.options.map(function (o, index) { return ({ value: index, label: localization_1.localize(o.label, ctx.locale) }); }); + const options = blockDef.options.map((o, index) => ({ value: index, label: localization_1.localize(o.label, ctx.locale) })); return react_1.default.createElement(bootstrap_1.Toggle, { options: options, value: selectedIndex, onChange: setSelectedIndex, allowReset: !blockDef.forceSelection, size: mapToggleSize(blockDef.size) }); } /** Map to toggle sizes */ diff --git a/lib/widgets/blocks/validation.js b/lib/widgets/blocks/validation.js index ddb42512..62941f64 100644 --- a/lib/widgets/blocks/validation.js +++ b/lib/widgets/blocks/validation.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,24 +23,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ValidationBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var react_1 = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var propertyEditors_1 = require("../propertyEditors"); -var ListEditor_1 = __importDefault(require("../ListEditor")); -var localization_1 = require("../localization"); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var scrolling_1 = require("../scrolling"); -var ValidationBlock = /** @class */ (function (_super) { - __extends(ValidationBlock, _super); - function ValidationBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - ValidationBlock.prototype.validate = function (options) { - var error; - for (var _i = 0, _a = this.blockDef.validations; _i < _a.length; _i++) { - var validation = _a[_i]; +const immer_1 = __importDefault(require("immer")); +const react_1 = __importStar(require("react")); +const blocks_1 = require("../blocks"); +const propertyEditors_1 = require("../propertyEditors"); +const ListEditor_1 = __importDefault(require("../ListEditor")); +const localization_1 = require("../localization"); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const scrolling_1 = require("../scrolling"); +class ValidationBlock extends LeafBlock_1.default { + validate(options) { + let error; + for (const validation of this.blockDef.validations) { error = blocks_1.validateContextVarExpr({ schema: options.schema, contextVars: options.contextVars, @@ -81,81 +52,72 @@ var ValidationBlock = /** @class */ (function (_super) { } } return null; - }; + } /** Get context variable expressions needed */ - ValidationBlock.prototype.getContextVarExprs = function (contextVar) { - return this.blockDef.validations.filter(function (v) { return v.contextVarId == contextVar.id; }).map(function (v) { return v.condition; }); - }; - ValidationBlock.prototype.renderDesign = function (props) { + getContextVarExprs(contextVar) { + return this.blockDef.validations.filter(v => v.contextVarId == contextVar.id).map(v => v.condition); + } + renderDesign(props) { return react_1.default.createElement("div", { className: "text-muted" }, react_1.default.createElement("i", { className: "fa fa-check" }), " Validation"); - }; - ValidationBlock.prototype.renderInstance = function (props) { + } + renderInstance(props) { return react_1.default.createElement(ValidationBlockInstance, { renderProps: props, blockDef: this.blockDef }); - }; - ValidationBlock.prototype.renderEditor = function (props) { - var _this = this; - var handleAdd = function () { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (bd) { + } + renderEditor(props) { + const handleAdd = () => { + props.store.replaceBlock(immer_1.default(this.blockDef, (bd) => { bd.validations.push({ contextVarId: null, condition: null, message: null }); })); }; return (react_1.default.createElement("div", null, react_1.default.createElement("h3", null, "Validation"), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Validations" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "validations" }, function (validations, onValidationsChange) { - return react_1.default.createElement(ListEditor_1.default, { items: validations, onItemsChange: onValidationsChange }, function (validation, onValidationChange) { - return react_1.default.createElement(ValidationEditor, { validation: validation, onValidationChange: onValidationChange, contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, locale: props.locale }); - }); - }), + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "validations" }, (validations, onValidationsChange) => react_1.default.createElement(ListEditor_1.default, { items: validations, onItemsChange: onValidationsChange }, (validation, onValidationChange) => react_1.default.createElement(ValidationEditor, { validation: validation, onValidationChange: onValidationChange, contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, locale: props.locale }))), react_1.default.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAdd }, react_1.default.createElement("i", { className: "fa fa-plus" }), " Add Validation")), - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "immediate" }, function (value, onChange) { return react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Validate Immediately"); }))); - }; - return ValidationBlock; -}(LeafBlock_1.default)); + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: this.blockDef, onChange: props.store.replaceBlock, property: "immediate" }, (value, onChange) => react_1.default.createElement(bootstrap_1.Checkbox, { value: value, onChange: onChange }, "Validate Immediately")))); + } +} exports.ValidationBlock = ValidationBlock; /** Editor for a single validation */ -var ValidationEditor = function (props) { +const ValidationEditor = (props) => { return (react_1.default.createElement("div", null, react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Condition that must be not be false" }, - react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, aggrStatuses: ["individual", "aggregate", "literal"], types: ["boolean"], contextVarId: props.validation.contextVarId, expr: props.validation.condition, onChange: function (contextVarId, condition) { - props.onValidationChange(__assign(__assign({}, props.validation), { contextVarId: contextVarId, condition: condition })); + react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVars: props.contextVars, schema: props.schema, dataSource: props.dataSource, aggrStatuses: ["individual", "aggregate", "literal"], types: ["boolean"], contextVarId: props.validation.contextVarId, expr: props.validation.condition, onChange: (contextVarId, condition) => { + props.onValidationChange(Object.assign(Object.assign({}, props.validation), { contextVarId, condition })); } })), react_1.default.createElement(propertyEditors_1.LabeledProperty, { label: "Error Message" }, - react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.validation, onChange: props.onValidationChange, property: "message" }, function (value, onChange) { - return react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }); - })))); + react_1.default.createElement(propertyEditors_1.PropertyEditor, { obj: props.validation, onChange: props.onValidationChange, property: "message" }, (value, onChange) => react_1.default.createElement(propertyEditors_1.LocalizedTextPropertyEditor, { value: value, onChange: onChange, locale: props.locale }))))); }; -var getValidationErrors = function (blockDef, renderProps) { - var errors = []; +const getValidationErrors = (blockDef, renderProps) => { + const errors = []; // Check validations - for (var _i = 0, _a = blockDef.validations; _i < _a.length; _i++) { - var validation = _a[_i]; + for (const validation of blockDef.validations) { // Get value of condition - var value = renderProps.getContextVarExprValue(validation.contextVarId, validation.condition); + const value = renderProps.getContextVarExprValue(validation.contextVarId, validation.condition); if (value === false) { errors.push(localization_1.localize(validation.message, renderProps.locale)); } } return errors; }; -var ValidationBlockInstance = function (props) { +const ValidationBlockInstance = (props) => { // True if validating - var _a = react_1.useState(props.blockDef.immediate || false), validating = _a[0], setValidating = _a[1]; - var controlRef = react_1.useRef(null); - var validate = function (isFirstError) { + const [validating, setValidating] = react_1.useState(props.blockDef.immediate || false); + const controlRef = react_1.useRef(null); + const validate = (isFirstError) => { // Now validating setValidating(true); - var errors = getValidationErrors(props.blockDef, props.renderProps); + const errors = getValidationErrors(props.blockDef, props.renderProps); if (errors.length > 0) { // Scroll into view if first error (check scrollIntoView for test environments without that function) if (isFirstError && controlRef.current && controlRef.current.scrollIntoView) { controlRef.current.scrollIntoView(true); // Add some padding - var scrollParent = scrolling_1.getScrollParent(controlRef.current); + const scrollParent = scrolling_1.getScrollParent(controlRef.current); if (scrollParent) { scrollParent.scrollBy(0, -30); } @@ -165,7 +127,7 @@ var ValidationBlockInstance = function (props) { return null; }; // Register for validation - react_1.useEffect(function () { + react_1.useEffect(() => { return props.renderProps.registerForValidation(validate); }, []); // If not validating, null @@ -173,12 +135,12 @@ var ValidationBlockInstance = function (props) { return null; } // Get errors - var errors = getValidationErrors(props.blockDef, props.renderProps); + const errors = getValidationErrors(props.blockDef, props.renderProps); if (errors.length == 0) { return null; } - return react_1.default.createElement("div", { className: "alert alert-danger", ref: controlRef }, errors.map(function (e, index) { return react_1.default.createElement("div", { key: index }, + return react_1.default.createElement("div", { className: "alert alert-danger", ref: controlRef }, errors.map((e, index) => react_1.default.createElement("div", { key: index }, react_1.default.createElement("i", { className: "fa fa-exclamation-triangle" }), " ", - e); })); + e))); }; diff --git a/lib/widgets/blocks/vertical.js b/lib/widgets/blocks/vertical.js index dba22805..17065156 100644 --- a/lib/widgets/blocks/vertical.js +++ b/lib/widgets/blocks/vertical.js @@ -1,17 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -36,36 +23,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.VerticalBlock = void 0; -var immer_1 = __importDefault(require("immer")); -var React = __importStar(require("react")); -var blocks_1 = require("../blocks"); -var VerticalBlock = /** @class */ (function (_super) { - __extends(VerticalBlock, _super); - function VerticalBlock() { - return _super !== null && _super.apply(this, arguments) || this; +const immer_1 = __importDefault(require("immer")); +const React = __importStar(require("react")); +const blocks_1 = require("../blocks"); +class VerticalBlock extends blocks_1.Block { + get id() { return this.blockDef.id; } + getChildren(contextVars) { + return this.blockDef.items.map(bd => ({ blockDef: bd, contextVars: contextVars })); } - Object.defineProperty(VerticalBlock.prototype, "id", { - get: function () { return this.blockDef.id; }, - enumerable: false, - configurable: true - }); - VerticalBlock.prototype.getChildren = function (contextVars) { - return this.blockDef.items.map(function (bd) { return ({ blockDef: bd, contextVars: contextVars }); }); - }; - VerticalBlock.prototype.validate = function () { return null; }; - VerticalBlock.prototype.processChildren = function (action) { + validate() { return null; } + processChildren(action) { // Apply action to all children, discarding null ones - var newItems = []; - for (var _i = 0, _a = this.blockDef.items; _i < _a.length; _i++) { - var item = _a[_i]; - var newItem = action(item); + const newItems = []; + for (const item of this.blockDef.items) { + const newItem = action(item); if (newItem) { newItems.push(newItem); } } - return immer_1.default(this.blockDef, function (draft) { draft.items = newItems; }); - }; - VerticalBlock.prototype.canonicalize = function () { + return immer_1.default(this.blockDef, draft => { draft.items = newItems; }); + } + canonicalize() { // Remove if zero items if (this.blockDef.items.length === 0) { return null; @@ -75,35 +53,33 @@ var VerticalBlock = /** @class */ (function (_super) { return this.blockDef.items[0]; } // Flatten out nested vertical blocks - if (this.blockDef.items.some(function (bd) { return bd.type == "vertical"; })) { + if (this.blockDef.items.some(bd => bd.type == "vertical")) { // Create list of items - var newItems_1 = []; - for (var _i = 0, _a = this.blockDef.items; _i < _a.length; _i++) { - var item = _a[_i]; + let newItems = []; + for (const item of this.blockDef.items) { if (item.type == "vertical") { - newItems_1 = newItems_1.concat(item.items); + newItems = newItems.concat(item.items); } else { - newItems_1.push(item); + newItems.push(item); } } - return immer_1.default(this.blockDef, function (draft) { - draft.items = newItems_1; + return immer_1.default(this.blockDef, (draft) => { + draft.items = newItems; }); } return this.blockDef; - }; - VerticalBlock.prototype.renderDesign = function (props) { + } + renderDesign(props) { // Add keys - return (React.createElement("div", { style: { paddingLeft: 5, paddingRight: 5 } }, this.blockDef.items.map(function (childBlockDef, index) { return React.cloneElement(props.renderChildBlock(props, childBlockDef), { key: index }); }))); - }; - VerticalBlock.prototype.renderInstance = function (props) { - return (React.createElement("div", null, this.blockDef.items.map(function (childBlockDef, index) { - var childElem = props.renderChildBlock(props, childBlockDef); + return (React.createElement("div", { style: { paddingLeft: 5, paddingRight: 5 } }, this.blockDef.items.map((childBlockDef, index) => React.cloneElement(props.renderChildBlock(props, childBlockDef), { key: index })))); + } + renderInstance(props) { + return (React.createElement("div", null, this.blockDef.items.map((childBlockDef, index) => { + const childElem = props.renderChildBlock(props, childBlockDef); return childElem ? React.cloneElement(childElem, { key: index }) : null; }))); - }; - VerticalBlock.prototype.getLabel = function () { return ""; }; - return VerticalBlock; -}(blocks_1.Block)); + } + getLabel() { return ""; } +} exports.VerticalBlock = VerticalBlock; diff --git a/lib/widgets/blocks/widget.js b/lib/widgets/blocks/widget.js index 3e161dba..5fbc5a4c 100644 --- a/lib/widgets/blocks/widget.js +++ b/lib/widgets/blocks/widget.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,74 +23,61 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.mapObjectTree = exports.WidgetBlock = void 0; -var React = __importStar(require("react")); -var _ = __importStar(require("lodash")); -var LeafBlock_1 = __importDefault(require("../LeafBlock")); -var blocks_1 = require("../blocks"); -var BlockPlaceholder_1 = __importDefault(require("../BlockPlaceholder")); -var propertyEditors_1 = require("../propertyEditors"); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var immer_1 = __importDefault(require("immer")); -var ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); -var WidgetBlock = /** @class */ (function (_super) { - __extends(WidgetBlock, _super); - function WidgetBlock() { - return _super !== null && _super.apply(this, arguments) || this; - } - WidgetBlock.prototype.validate = function (options) { - var _this = this; +const React = __importStar(require("react")); +const _ = __importStar(require("lodash")); +const LeafBlock_1 = __importDefault(require("../LeafBlock")); +const blocks_1 = require("../blocks"); +const BlockPlaceholder_1 = __importDefault(require("../BlockPlaceholder")); +const propertyEditors_1 = require("../propertyEditors"); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const immer_1 = __importDefault(require("immer")); +const ContextVarsInjector_1 = __importDefault(require("../ContextVarsInjector")); +class WidgetBlock extends LeafBlock_1.default { + validate(options) { if (!this.blockDef.widgetId) { return "Widget required"; } // Ensure that widget exists - var widget = options.widgetLibrary.widgets[this.blockDef.widgetId]; + const widget = options.widgetLibrary.widgets[this.blockDef.widgetId]; if (!widget) { return "Invalid widget"; } - var _loop_1 = function (internalContextVarId) { - if (!options.contextVars.find(function (cv) { return cv.id === _this.blockDef.contextVarMap[internalContextVarId]; })) { - return { value: "Missing context variable in mapping" }; - } - }; // Ensure that all context variables exist - for (var _i = 0, _a = Object.keys(this.blockDef.contextVarMap); _i < _a.length; _i++) { - var internalContextVarId = _a[_i]; - var state_1 = _loop_1(internalContextVarId); - if (typeof state_1 === "object") - return state_1.value; + for (const internalContextVarId of Object.keys(this.blockDef.contextVarMap)) { + if (!options.contextVars.find(cv => cv.id === this.blockDef.contextVarMap[internalContextVarId])) { + return "Missing context variable in mapping"; + } } return null; - }; - WidgetBlock.prototype.getInitialFilters = function (contextVarId, instanceCtx) { - var widgetDef = instanceCtx.widgetLibrary.widgets[this.blockDef.widgetId]; + } + getInitialFilters(contextVarId, instanceCtx) { + const widgetDef = instanceCtx.widgetLibrary.widgets[this.blockDef.widgetId]; if (widgetDef && widgetDef.blockDef) { - var innerBlock = instanceCtx.createBlock(widgetDef.blockDef); + const innerBlock = instanceCtx.createBlock(widgetDef.blockDef); // Map contextVarId to internal id - for (var _i = 0, _a = Object.keys(this.blockDef.contextVarMap); _i < _a.length; _i++) { - var key = _a[_i]; - var value = this.blockDef.contextVarMap[key]; + for (const key of Object.keys(this.blockDef.contextVarMap)) { + const value = this.blockDef.contextVarMap[key]; if (value === contextVarId) { return innerBlock.getInitialFilters(key, instanceCtx); } } } return []; - }; - WidgetBlock.prototype.getContextVarExprs = function (contextVar, ctx) { - var _this = this; + } + getContextVarExprs(contextVar, ctx) { if (!this.blockDef.widgetId) { return []; } // Get inner widget - var widgetDef = ctx.widgetLibrary.widgets[this.blockDef.widgetId]; + const widgetDef = ctx.widgetLibrary.widgets[this.blockDef.widgetId]; if (!widgetDef.blockDef) { return []; } // Map context variable - var innerContextVar = widgetDef.contextVars.find(function (cv) { return contextVar.id === _this.blockDef.contextVarMap[cv.id]; }); + let innerContextVar = widgetDef.contextVars.find(cv => contextVar.id === this.blockDef.contextVarMap[cv.id]); if (!innerContextVar) { // Check if global variable - if ((ctx.globalContextVars || []).find(function (cv) { return cv.id == contextVar.id; })) { + if ((ctx.globalContextVars || []).find(cv => cv.id == contextVar.id)) { // Pass it straight through innerContextVar = contextVar; } @@ -123,19 +86,18 @@ var WidgetBlock = /** @class */ (function (_super) { } } // Get complete context variables exprs of inner widget blocks - var contextVarExprs = ctx.createBlock(widgetDef.blockDef).getSubtreeContextVarExprs(innerContextVar, __assign(__assign({}, ctx), { contextVars: widgetDef.contextVars })); + let contextVarExprs = ctx.createBlock(widgetDef.blockDef).getSubtreeContextVarExprs(innerContextVar, Object.assign(Object.assign({}, ctx), { contextVars: widgetDef.contextVars })); // Map any variables of expressions that cross widget boundary - contextVarExprs = contextVarExprs.map(function (cve) { return _this.mapInnerToOuterVariables(cve); }); + contextVarExprs = contextVarExprs.map((cve) => this.mapInnerToOuterVariables(cve)); return contextVarExprs; - }; + } /** Maps variables in an expression from inner variable names to outer ones */ - WidgetBlock.prototype.mapInnerToOuterVariables = function (expr) { - var _this = this; - return exports.mapObjectTree(expr, function (e) { + mapInnerToOuterVariables(expr) { + return exports.mapObjectTree(expr, (e) => { if (e.type === "variable") { // Change inner id to outer id - if (_this.blockDef.contextVarMap[e.variableId]) { - return __assign(__assign({}, e), { variableId: _this.blockDef.contextVarMap[e.variableId] }); + if (this.blockDef.contextVarMap[e.variableId]) { + return Object.assign(Object.assign({}, e), { variableId: this.blockDef.contextVarMap[e.variableId] }); } else { return e; @@ -145,16 +107,15 @@ var WidgetBlock = /** @class */ (function (_super) { return e; } }); - }; + } /** Maps variables in an expression from outer variable names to inner ones */ - WidgetBlock.prototype.mapOuterToInnerVariables = function (expr) { - var _this = this; - return exports.mapObjectTree(expr, function (e) { + mapOuterToInnerVariables(expr) { + return exports.mapObjectTree(expr, (e) => { if (e.type === "variable") { // Change outer id to inner id - for (var key in _this.blockDef.contextVarMap) { - if (_this.blockDef.contextVarMap[key] == e.variableId) { - return __assign(__assign({}, e), { variableId: key }); + for (const key in this.blockDef.contextVarMap) { + if (this.blockDef.contextVarMap[key] == e.variableId) { + return Object.assign(Object.assign({}, e), { variableId: key }); } } return e; @@ -163,22 +124,22 @@ var WidgetBlock = /** @class */ (function (_super) { return e; } }); - }; - WidgetBlock.prototype.renderDesign = function (props) { + } + renderDesign(props) { if (!this.blockDef.widgetId) { return React.createElement("div", { style: { fontStyle: "italic" } }, "Select widget..."); } // Find the widget - var widgetDef = props.widgetLibrary.widgets[this.blockDef.widgetId]; + const widgetDef = props.widgetLibrary.widgets[this.blockDef.widgetId]; if (widgetDef && widgetDef.blockDef) { - var innerBlock = props.createBlock(widgetDef.blockDef); - var innerContextVars = (props.globalContextVars || []) + const innerBlock = props.createBlock(widgetDef.blockDef); + const innerContextVars = (props.globalContextVars || []) .concat(widgetDef.contextVars) .concat(widgetDef.privateContextVars || []); // Create props for rendering inner block - var innerProps = __assign(__assign({}, props), { selectedId: null, contextVars: innerContextVars, store: new blocks_1.NullBlockStore(), blockPaletteEntries: [], renderChildBlock: function (childProps, childBlockDef) { + const innerProps = Object.assign(Object.assign({}, props), { selectedId: null, contextVars: innerContextVars, store: new blocks_1.NullBlockStore(), blockPaletteEntries: [], renderChildBlock: (childProps, childBlockDef) => { if (childBlockDef) { - var childBlock = props.createBlock(childBlockDef); + const childBlock = props.createBlock(childBlockDef); return childBlock.renderDesign(childProps); } else { @@ -192,14 +153,12 @@ var WidgetBlock = /** @class */ (function (_super) { else { // Handle case of widget with null block return React.createElement("div", null); } - }; - WidgetBlock.prototype.renderInstance = function (instanceCtx) { - var _this = this; + } + renderInstance(instanceCtx) { // Map context var values - var mappedContextVarValues = {}; - for (var _i = 0, _a = Object.keys(this.blockDef.contextVarMap); _i < _a.length; _i++) { - var innerContextVarId = _a[_i]; - var outerContextVarId = this.blockDef.contextVarMap[innerContextVarId]; + const mappedContextVarValues = {}; + for (const innerContextVarId of Object.keys(this.blockDef.contextVarMap)) { + const outerContextVarId = this.blockDef.contextVarMap[innerContextVarId]; if (outerContextVarId) { mappedContextVarValues[innerContextVarId] = instanceCtx.contextVarValues[outerContextVarId]; } @@ -208,89 +167,87 @@ var WidgetBlock = /** @class */ (function (_super) { } } // Include global context variables - for (var _b = 0, _c = instanceCtx.globalContextVars || []; _b < _c.length; _b++) { - var globalContextVar = _c[_b]; + for (const globalContextVar of instanceCtx.globalContextVars || []) { mappedContextVarValues[globalContextVar.id] = instanceCtx.contextVarValues[globalContextVar.id]; } // Find the widget - var widgetDef = instanceCtx.widgetLibrary.widgets[this.blockDef.widgetId]; + const widgetDef = instanceCtx.widgetLibrary.widgets[this.blockDef.widgetId]; if (widgetDef && widgetDef.blockDef) { - var innerBlock_1 = instanceCtx.createBlock(widgetDef.blockDef); + const innerBlock = instanceCtx.createBlock(widgetDef.blockDef); // Include outer context variables, even though widget does not technically need them // They are included as the widget might receive expressions such as rowsets that reference // variables that are only present in the outer scope. - var innerContextVars = (instanceCtx.globalContextVars || []) + const innerContextVars = (instanceCtx.globalContextVars || []) .concat(instanceCtx.contextVars) .concat(widgetDef.contextVars); - var innerContextVarValues = __assign(__assign(__assign({}, instanceCtx.contextVarValues), mappedContextVarValues), (_.pick(widgetDef.privateContextVarValues || {}, (widgetDef.privateContextVars || []).map(function (cv) { return cv.id; })))); - var innerInstanceCtx = __assign(__assign({}, instanceCtx), { contextVars: innerContextVars, contextVarValues: innerContextVarValues, getContextVarExprValue: function (contextVarId, expr) { + const innerContextVarValues = Object.assign(Object.assign(Object.assign({}, instanceCtx.contextVarValues), mappedContextVarValues), (_.pick(widgetDef.privateContextVarValues || {}, (widgetDef.privateContextVars || []).map(cv => cv.id)))); + const innerInstanceCtx = Object.assign(Object.assign({}, instanceCtx), { contextVars: innerContextVars, contextVarValues: innerContextVarValues, getContextVarExprValue: (contextVarId, expr) => { // Lookup outer id - var outerContextVarId = _this.blockDef.contextVarMap[contextVarId]; + const outerContextVarId = this.blockDef.contextVarMap[contextVarId]; if (outerContextVarId) { // Map variable from inner to outer - return instanceCtx.getContextVarExprValue(outerContextVarId, _this.mapInnerToOuterVariables(expr)); + return instanceCtx.getContextVarExprValue(outerContextVarId, this.mapInnerToOuterVariables(expr)); } else { // If global variable, pass through - if ((instanceCtx.globalContextVars || []).find(function (cv) { return cv.id == contextVarId; })) { + if ((instanceCtx.globalContextVars || []).find(cv => cv.id == contextVarId)) { return instanceCtx.getContextVarExprValue(contextVarId, expr); } return; } - }, onSelectContextVar: function (contextVarId, primaryKey) { + }, onSelectContextVar: (contextVarId, primaryKey) => { // Lookup outer id - var outerContextVarId = _this.blockDef.contextVarMap[contextVarId]; + const outerContextVarId = this.blockDef.contextVarMap[contextVarId]; if (outerContextVarId) { instanceCtx.onSelectContextVar(outerContextVarId, primaryKey); } - }, setFilter: function (contextVarId, filter) { + }, setFilter: (contextVarId, filter) => { // Lookup outer id - var outerContextVarId = _this.blockDef.contextVarMap[contextVarId]; + const outerContextVarId = this.blockDef.contextVarMap[contextVarId]; if (outerContextVarId) { - instanceCtx.setFilter(outerContextVarId, __assign(__assign({}, filter), { expr: _this.mapInnerToOuterVariables(filter.expr) })); + instanceCtx.setFilter(outerContextVarId, Object.assign(Object.assign({}, filter), { expr: this.mapInnerToOuterVariables(filter.expr) })); } - }, getFilters: function (contextVarId) { + }, getFilters: (contextVarId) => { // Lookup outer id, mapping any variables - var outerContextVarId = _this.blockDef.contextVarMap[contextVarId]; + const outerContextVarId = this.blockDef.contextVarMap[contextVarId]; if (outerContextVarId) { - return instanceCtx.getFilters(outerContextVarId).map(function (f) { return (__assign(__assign({}, f), { expr: _this.mapOuterToInnerVariables(f.expr) })); }); + return instanceCtx.getFilters(outerContextVarId).map(f => (Object.assign(Object.assign({}, f), { expr: this.mapOuterToInnerVariables(f.expr) }))); } return []; } }); // Inject private context vars - return React.createElement(ContextVarsInjector_1.default, { instanceCtx: innerInstanceCtx, innerBlock: widgetDef.blockDef, injectedContextVars: widgetDef.privateContextVars || [], injectedContextVarValues: _.pick(widgetDef.privateContextVarValues || {}, (widgetDef.privateContextVars || []).map(function (cv) { return cv.id; })) }, function (instanceCtx, loading, refreshing) { + return React.createElement(ContextVarsInjector_1.default, { instanceCtx: innerInstanceCtx, innerBlock: widgetDef.blockDef, injectedContextVars: widgetDef.privateContextVars || [], injectedContextVarValues: _.pick(widgetDef.privateContextVarValues || {}, (widgetDef.privateContextVars || []).map(cv => cv.id)) }, (instanceCtx, loading, refreshing) => { if (loading) { return React.createElement("div", { style: { color: "#AAA", textAlign: "center" } }, React.createElement("i", { className: "fa fa-circle-o-notch fa-spin" })); } - return (React.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, innerBlock_1.renderInstance(instanceCtx))); + return (React.createElement("div", { style: { opacity: refreshing ? 0.6 : undefined } }, innerBlock.renderInstance(instanceCtx))); }); } else { // Handle case of widget with null block return React.createElement("div", null); } - }; - WidgetBlock.prototype.renderEditor = function (props) { - var _this = this; + } + renderEditor(props) { // Create widget options - var widgetOptions = _.sortByAll(Object.values(props.widgetLibrary.widgets), "group", "name").map(function (w) { return ({ label: (w.group ? w.group + ": " : "") + w.name, value: w.id }); }); - var handleWidgetIdChange = function (widgetId) { - props.store.replaceBlock(__assign(__assign({}, _this.blockDef), { widgetId: widgetId, contextVarMap: {} })); + const widgetOptions = _.sortByAll(Object.values(props.widgetLibrary.widgets), "group", "name").map(w => ({ label: (w.group ? `${w.group}: ` : "") + w.name, value: w.id })); + const handleWidgetIdChange = (widgetId) => { + props.store.replaceBlock(Object.assign(Object.assign({}, this.blockDef), { widgetId: widgetId, contextVarMap: {} })); }; - var renderContextVarValues = function () { - if (!_this.blockDef.widgetId) { + const renderContextVarValues = () => { + if (!this.blockDef.widgetId) { return null; } // Find the widget - var widgetDef = props.widgetLibrary.widgets[_this.blockDef.widgetId]; + const widgetDef = props.widgetLibrary.widgets[this.blockDef.widgetId]; if (!widgetDef) { return null; } return (React.createElement("table", { className: "table table-bordered table-condensed" }, - React.createElement("tbody", null, widgetDef.contextVars.map(function (contextVar) { - var cv = _this.blockDef.contextVarMap[contextVar.id]; - var handleCVChange = function (contextVarId) { - props.store.replaceBlock(immer_1.default(_this.blockDef, function (draft) { + React.createElement("tbody", null, widgetDef.contextVars.map(contextVar => { + const cv = this.blockDef.contextVarMap[contextVar.id]; + const handleCVChange = (contextVarId) => { + props.store.replaceBlock(immer_1.default(this.blockDef, (draft) => { draft.contextVarMap[contextVar.id] = contextVarId; })); }; @@ -304,21 +261,20 @@ var WidgetBlock = /** @class */ (function (_super) { React.createElement(propertyEditors_1.LabeledProperty, { label: "Widget" }, React.createElement(bootstrap_1.Select, { value: this.blockDef.widgetId, onChange: handleWidgetIdChange, options: widgetOptions, nullLabel: "Select Widget" })), renderContextVarValues()); - }; - return WidgetBlock; -}(LeafBlock_1.default)); + } +} exports.WidgetBlock = WidgetBlock; // Run a possibly deep object through a mapping function. Automatically maps all values of objects and arrays recursively -exports.mapObjectTree = function (obj, mapping) { +exports.mapObjectTree = (obj, mapping) => { // If array, map items if (_.isArray(obj)) { - return obj.map(function (elem) { return exports.mapObjectTree(elem, mapping); }); + return obj.map((elem) => exports.mapObjectTree(elem, mapping)); } if (_.isObject(obj)) { // First map object itself - var res = mapping(obj); + const res = mapping(obj); // Then map values - return _.mapValues(res, function (value) { return exports.mapObjectTree(value, mapping); }); + return _.mapValues(res, (value) => exports.mapObjectTree(value, mapping)); } return obj; }; diff --git a/lib/widgets/blocks/widget.test.js b/lib/widgets/blocks/widget.test.js index 7df373d9..0ca37c76 100644 --- a/lib/widgets/blocks/widget.test.js +++ b/lib/widgets/blocks/widget.test.js @@ -3,18 +3,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var widget_1 = require("./widget"); -var BlockFactory_1 = __importDefault(require("../BlockFactory")); -var immer_1 = __importDefault(require("immer")); -var enzyme_1 = require("enzyme"); -var innerBlockDef = { +const widget_1 = require("./widget"); +const BlockFactory_1 = __importDefault(require("../BlockFactory")); +const immer_1 = __importDefault(require("immer")); +const enzyme_1 = require("enzyme"); +const innerBlockDef = { type: "expression", id: "exp1", contextVarId: "b1", expr: { type: "field", table: "t1", column: "text" }, format: null }; -var widgetDef = { +const widgetDef = { id: "w1", name: "W1", description: "", @@ -24,7 +24,7 @@ var widgetDef = { ], contextVarPreviewValues: {} }; -var blockDef = { +const blockDef = { id: "a", type: "widget", widgetId: "w1", @@ -32,64 +32,64 @@ var blockDef = { b1: "a1" } }; -var widgetLibrary = { +const widgetLibrary = { widgets: { "w1": widgetDef } }; -var contextVars = [ +const contextVars = [ { id: "a1", name: "A1", type: "text" }, { id: "a2", name: "A2", type: "text" } ]; -describe("getContextVarExprs", function () { - test("gathers from inner widget and maps", function () { - var createBlock = new BlockFactory_1.default().createBlock; - var widgetBlock = new widget_1.WidgetBlock(blockDef); +describe("getContextVarExprs", () => { + test("gathers from inner widget and maps", () => { + const createBlock = new BlockFactory_1.default().createBlock; + const widgetBlock = new widget_1.WidgetBlock(blockDef); // Get expressions - var exprs = widgetBlock.getContextVarExprs(contextVars[0], { widgetLibrary: widgetLibrary, createBlock: createBlock }); + const exprs = widgetBlock.getContextVarExprs(contextVars[0], { widgetLibrary: widgetLibrary, createBlock: createBlock }); expect(exprs).toEqual([ { type: "field", table: "t1", column: "text" } ]); }); - test("gathers from inner widget and maps variables too", function () { + test("gathers from inner widget and maps variables too", () => { // Alter widget block to have variable in expression - var widgetLibrary2 = immer_1.default(widgetLibrary, function (draft) { + const widgetLibrary2 = immer_1.default(widgetLibrary, (draft) => { (draft.widgets.w1.blockDef).expr = { type: "variable", variableId: "b1" }; }); - var createBlock = new BlockFactory_1.default().createBlock; - var widgetBlock = new widget_1.WidgetBlock(blockDef); + const createBlock = new BlockFactory_1.default().createBlock; + const widgetBlock = new widget_1.WidgetBlock(blockDef); // Get expressions - var exprs = widgetBlock.getContextVarExprs(contextVars[0], { widgetLibrary: widgetLibrary2, createBlock: createBlock }); + const exprs = widgetBlock.getContextVarExprs(contextVars[0], { widgetLibrary: widgetLibrary2, createBlock: createBlock }); expect(exprs).toEqual([ { type: "variable", variableId: "a1" } ]); }); }); -describe("getInitialFilters", function () { - test("translates", function () { - var createBlock = jest.fn(); - var widgetBlock = new widget_1.WidgetBlock(blockDef); - var innerBlock = { +describe("getInitialFilters", () => { + test("translates", () => { + const createBlock = jest.fn(); + const widgetBlock = new widget_1.WidgetBlock(blockDef); + const innerBlock = { getInitialFilters: jest.fn() }; // Return inner block createBlock.mockReset(); createBlock.mockReturnValueOnce(innerBlock); innerBlock.getInitialFilters.mockReturnValue([{ id: "f1", memo: "m", expr: {} }]); - var filters = widgetBlock.getInitialFilters("a1", { widgetLibrary: widgetLibrary, contextVars: [], createBlock: createBlock }); + const filters = widgetBlock.getInitialFilters("a1", { widgetLibrary: widgetLibrary, contextVars: [], createBlock: createBlock }); expect(filters).toEqual([{ id: "f1", memo: "m", expr: {} }]); expect(innerBlock.getInitialFilters.mock.calls[0][0]).toBe("b1"); }); }); -describe("renderInstance", function () { - var instanceCtx; - var innerInstanceCtx; +describe("renderInstance", () => { + let instanceCtx; + let innerInstanceCtx; // Render instance - beforeEach(function (done) { - var createBlock = jest.fn(); - var widgetBlock = new widget_1.WidgetBlock(blockDef); - var innerBlock = { - renderInstance: function (instanceCtx) { + beforeEach((done) => { + const createBlock = jest.fn(); + const widgetBlock = new widget_1.WidgetBlock(blockDef); + const innerBlock = { + renderInstance: (instanceCtx) => { innerInstanceCtx = instanceCtx; done(); } @@ -112,42 +112,42 @@ describe("renderInstance", function () { setFilter: jest.fn(), getFilters: jest.fn(), renderChildBlock: jest.fn(), - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => { return () => { }; }, + T: (str) => str }; - var x = enzyme_1.shallow(widgetBlock.renderInstance(instanceCtx)); + const x = enzyme_1.shallow(widgetBlock.renderInstance(instanceCtx)); }); - test("contextVars", function () { + test("contextVars", () => { expect(innerInstanceCtx.contextVars).toEqual(contextVars.concat(widgetDef.contextVars)); }); - test("contextVarValues maps", function () { + test("contextVarValues maps", () => { expect(innerInstanceCtx.contextVarValues.b1).toBe("a1"); }); - test("getContextVarExprValue maps variables", function () { - var outerGetContextVarExprValue = jest.fn(); + test("getContextVarExprValue maps variables", () => { + const outerGetContextVarExprValue = jest.fn(); instanceCtx.getContextVarExprValue = outerGetContextVarExprValue; outerGetContextVarExprValue.mockReturnValue("abc"); - var innerExpr = { type: "variable", variableId: "b1" }; + const innerExpr = { type: "variable", variableId: "b1" }; expect(innerInstanceCtx.getContextVarExprValue("b1", innerExpr)).toBe("abc"); expect(outerGetContextVarExprValue.mock.calls[0][0]).toBe("a1"); expect(outerGetContextVarExprValue.mock.calls[0][1]).toEqual({ type: "variable", variableId: "a1" }); }); - test("onSelectContextVar maps", function () { + test("onSelectContextVar maps", () => { innerInstanceCtx.onSelectContextVar("b1", "pk"); expect(instanceCtx.onSelectContextVar.mock.calls[0]).toEqual(["a1", "pk"]); }); - test("setFilter maps", function () { + test("setFilter maps", () => { innerInstanceCtx.setFilter("b1", {}); expect(instanceCtx.setFilter.mock.calls[0]).toEqual(["a1", {}]); }); }); -describe("mapObjectTree", function () { - test("deep mapping", function () { - var obj = { +describe("mapObjectTree", () => { + test("deep mapping", () => { + const obj = { x: 1, y: [{ foo: 1 }] }; - expect(widget_1.mapObjectTree(obj, function (input) { + expect(widget_1.mapObjectTree(obj, (input) => { return (input.foo) ? { foo: 2 } : input; })).toEqual({ x: 1, diff --git a/lib/widgets/columnValues.js b/lib/widgets/columnValues.js index a2684b52..23aa0577 100644 --- a/lib/widgets/columnValues.js +++ b/lib/widgets/columnValues.js @@ -1,74 +1,48 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnValuesEditor = void 0; -var lodash_1 = __importDefault(require("lodash")); -var react_1 = __importDefault(require("react")); -var immer_1 = __importDefault(require("immer")); -var localization_1 = require("./localization"); -var propertyEditors_1 = require("./propertyEditors"); -var react_select_1 = __importDefault(require("react-select")); +const lodash_1 = __importDefault(require("lodash")); +const react_1 = __importDefault(require("react")); +const immer_1 = __importDefault(require("immer")); +const localization_1 = require("./localization"); +const propertyEditors_1 = require("./propertyEditors"); +const react_select_1 = __importDefault(require("react-select")); /** Allows editing list of column values for add */ -var ColumnValuesEditor = /** @class */ (function (_super) { - __extends(ColumnValuesEditor, _super); - function ColumnValuesEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleContextVarExprChange = function (columnId, contextVarId, expr) { - _this.props.onChange(immer_1.default(_this.props.value, function (draft) { +class ColumnValuesEditor extends react_1.default.Component { + constructor() { + super(...arguments); + this.handleContextVarExprChange = (columnId, contextVarId, expr) => { + this.props.onChange(immer_1.default(this.props.value, (draft) => { draft[columnId].contextVarId = contextVarId; draft[columnId].expr = expr; })); }; - _this.handleRemove = function (columnId) { - _this.props.onChange(immer_1.default(_this.props.value, function (draft) { + this.handleRemove = (columnId) => { + this.props.onChange(immer_1.default(this.props.value, (draft) => { delete draft[columnId]; })); }; - _this.handleAdd = function (option) { + this.handleAdd = (option) => { if (option) { - _this.props.onChange(immer_1.default(_this.props.value, function (draft) { + this.props.onChange(immer_1.default(this.props.value, (draft) => { draft[option.value] = { contextVarId: null, expr: null }; })); } }; - return _this; } - ColumnValuesEditor.prototype.renderColumn = function (columnId) { - var column = this.props.schema.getColumn(this.props.table, columnId); + renderColumn(columnId) { + const column = this.props.schema.getColumn(this.props.table, columnId); if (!column) { return null; } - var contextVarExpr = this.props.value[columnId]; + const contextVarExpr = this.props.value[columnId]; // Override for special case of allowing to set joins - var idTable = column.type == "join" ? column.join.toTable : column.idTable; - var type = column.type == "join" ? "id" : column.type; - var contextVar = contextVarExpr.contextVarId ? this.props.contextVars.find(function (cv) { return cv.id == contextVarExpr.contextVarId; }) : null; + const idTable = column.type == "join" ? column.join.toTable : column.idTable; + const type = column.type == "join" ? "id" : column.type; + const contextVar = contextVarExpr.contextVarId ? this.props.contextVars.find(cv => cv.id == contextVarExpr.contextVarId) : null; return react_1.default.createElement("tr", { key: columnId }, react_1.default.createElement("td", { key: "name" }, localization_1.localize(column.name, this.props.locale)), react_1.default.createElement("td", { key: "value" }, @@ -76,18 +50,16 @@ var ColumnValuesEditor = /** @class */ (function (_super) { react_1.default.createElement(propertyEditors_1.ContextVarExprPropertyEditor, { contextVarId: contextVarExpr.contextVarId, expr: contextVarExpr.expr, onChange: this.handleContextVarExprChange.bind(null, columnId), contextVars: this.props.contextVars, schema: this.props.schema, dataSource: this.props.dataSource, idTable: idTable, enumValues: column.enumValues, aggrStatuses: contextVar && contextVar.type == "rowset" ? ["aggregate", "literal"] : ["individual", "literal"], types: [type] }))), react_1.default.createElement("td", { key: "remove" }, react_1.default.createElement("i", { className: "fa fa-remove", onClick: this.handleRemove.bind(null, columnId) }))); - }; - ColumnValuesEditor.prototype.render = function () { - var _this = this; + } + render() { // Only allow updateable column types - var columns = this.props.schema.getColumns(this.props.table).filter(function (column) { return (!column.expr && (column.type != "join" || column.join.type == "1-1" || column.join.type == "n-1")); }); - var options = lodash_1.default.sortBy(columns.map(function (column) { return ({ value: column.id, label: localization_1.localize(column.name, _this.props.locale) }); }), "label"); + const columns = this.props.schema.getColumns(this.props.table).filter(column => (!column.expr && (column.type != "join" || column.join.type == "1-1" || column.join.type == "n-1"))); + const options = lodash_1.default.sortBy(columns.map(column => ({ value: column.id, label: localization_1.localize(column.name, this.props.locale) })), "label"); // Render list of existing ones in order return react_1.default.createElement("div", null, react_1.default.createElement("table", { className: "table table-bordered table-condensed" }, - react_1.default.createElement("tbody", null, Object.keys(this.props.value).sort().map(function (columnId) { return _this.renderColumn(columnId); }))), - react_1.default.createElement(react_select_1.default, { value: null, options: options, onChange: this.handleAdd, menuPortalTarget: document.body, styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } })); - }; - return ColumnValuesEditor; -}(react_1.default.Component)); + react_1.default.createElement("tbody", null, Object.keys(this.props.value).sort().map(columnId => this.renderColumn(columnId)))), + react_1.default.createElement(react_select_1.default, { value: null, options: options, onChange: this.handleAdd, menuPortalTarget: document.body, styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } })); + } +} exports.ColumnValuesEditor = ColumnValuesEditor; diff --git a/lib/widgets/evalContextVarExpr.js b/lib/widgets/evalContextVarExpr.js index cc00ae3e..7ce54bef 100644 --- a/lib/widgets/evalContextVarExpr.js +++ b/lib/widgets/evalContextVarExpr.js @@ -8,134 +8,108 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.evalContextVarExpr = void 0; -var lodash_1 = __importDefault(require("lodash")); -var mwater_expressions_1 = require("mwater-expressions"); -var contexts_1 = require("../contexts"); -var blocks_1 = require("./blocks"); +const lodash_1 = __importDefault(require("lodash")); +const mwater_expressions_1 = require("mwater-expressions"); +const contexts_1 = require("../contexts"); +const blocks_1 = require("./blocks"); /** * Evaluate a context variable expression. * contextVar does not need to be part of the context, but if it is, it will still be handled correctly */ function evalContextVarExpr(options) { - return __awaiter(this, void 0, void 0, function () { - var contextVar, contextVarValue, expr, ctx, table, queryOptions, contextVars, filteredContextVarValues, rows, table, aggrStatus, queryOptions, isExisting, contextVars, filteredContextVarValues, rows; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = options.contextVar, contextVarValue = options.contextVarValue, expr = options.expr, ctx = options.ctx; - // Null expression has null value - if (!expr) { - return [2 /*return*/, null]; - } - // If no context variable, evaluate expression - if (contextVar == null) { - return [2 /*return*/, new mwater_expressions_1.PromiseExprEvaluator({ - schema: ctx.schema, - locale: ctx.locale, - variables: blocks_1.createExprVariables(ctx.contextVars), - variableValues: blocks_1.createExprVariableValues(ctx.contextVars, ctx.contextVarValues) - }).evaluateSync(expr)]; - } - if (!(contextVar.type == "row")) return [3 /*break*/, 2]; - // Simple case for no value - if (contextVarValue == null) { - return [2 /*return*/, null]; - } - table = contextVar.table; - queryOptions = { - select: { - value: expr - }, - from: table, - where: { - type: "op", - op: "=", - table: table, - exprs: [{ type: "id", table: table }, { type: "literal", valueType: "id", idTable: table, value: contextVarValue }] - } - }; - contextVars = ctx.contextVars.slice(); - filteredContextVarValues = contexts_1.getFilteredContextVarValues(ctx); - if (!ctx.contextVars.includes(contextVar)) { - contextVars.push(contextVar); - filteredContextVarValues[contextVar.id] = contextVarValue; - } - return [4 /*yield*/, ctx.database.query(queryOptions, contextVars, filteredContextVarValues)]; - case 1: - rows = _a.sent(); - return [2 /*return*/, rows.length > 0 ? rows[0].value : null]; - case 2: - if (!(contextVar.type == "rowset")) return [3 /*break*/, 4]; - table = contextVar.table; - aggrStatus = new mwater_expressions_1.ExprUtils(ctx.schema, blocks_1.createExprVariables(ctx.contextVars)).getExprAggrStatus(expr); - queryOptions = { - select: { - value: expr - }, - distinct: aggrStatus == "aggregate" ? false : true, - from: table, - where: contextVarValue, - // If multiple returned, has no value, so use limit of 2 - limit: 2 - }; - isExisting = ctx.contextVars.includes(contextVar); - // If exists, add the filters - if (isExisting) { - queryOptions.where = { - type: "op", - table: table, - op: "and", - exprs: lodash_1.default.compact([queryOptions.where || null].concat(lodash_1.default.compact(ctx.getFilters(contextVar.id).map(function (f) { return f.expr; })))) - }; - if (queryOptions.where.exprs.length === 0) { - queryOptions.where = null; - } - } - contextVars = ctx.contextVars.slice(); - filteredContextVarValues = contexts_1.getFilteredContextVarValues(ctx); - if (!isExisting) { - contextVars.push(contextVar); - filteredContextVarValues[contextVar.id] = contextVarValue; - } - return [4 /*yield*/, ctx.database.query(queryOptions, contextVars, filteredContextVarValues)]; - case 3: - rows = _a.sent(); - return [2 /*return*/, rows.length == 1 ? rows[0].value : null]; - case 4: throw new Error("Context variable type not supported"); + return __awaiter(this, void 0, void 0, function* () { + const { contextVar, contextVarValue, expr, ctx } = options; + // Null expression has null value + if (!expr) { + return null; + } + // If no context variable, evaluate expression + if (contextVar == null) { + return new mwater_expressions_1.PromiseExprEvaluator({ + schema: ctx.schema, + locale: ctx.locale, + variables: blocks_1.createExprVariables(ctx.contextVars), + variableValues: blocks_1.createExprVariableValues(ctx.contextVars, ctx.contextVarValues) + }).evaluateSync(expr); + } + // Evaluate row expression + if (contextVar.type == "row") { + // Simple case for no value + if (contextVarValue == null) { + return null; + } + const table = contextVar.table; + // Create query to get value + const queryOptions = { + select: { + value: expr + }, + from: table, + where: { + type: "op", + op: "=", + table: table, + exprs: [{ type: "id", table: table }, { type: "literal", valueType: "id", idTable: table, value: contextVarValue }] + } + }; + // Create contextVars list that includes injected variable, adding it if not already present + const contextVars = ctx.contextVars.slice(); + const filteredContextVarValues = contexts_1.getFilteredContextVarValues(ctx); + if (!ctx.contextVars.includes(contextVar)) { + contextVars.push(contextVar); + filteredContextVarValues[contextVar.id] = contextVarValue; + } + // Perform query + const rows = yield ctx.database.query(queryOptions, contextVars, filteredContextVarValues); + return rows.length > 0 ? rows[0].value : null; + } + // Evaluate rowset expression + if (contextVar.type == "rowset") { + const table = contextVar.table; + // Determine if aggregate + const aggrStatus = new mwater_expressions_1.ExprUtils(ctx.schema, blocks_1.createExprVariables(ctx.contextVars)).getExprAggrStatus(expr); + // Create query to get value + const queryOptions = { + select: { + value: expr + }, + distinct: aggrStatus == "aggregate" ? false : true, + from: table, + where: contextVarValue, + // If multiple returned, has no value, so use limit of 2 + limit: 2 + }; + // Determine if context variable is already in context + const isExisting = ctx.contextVars.includes(contextVar); + // If exists, add the filters + if (isExisting) { + queryOptions.where = { + type: "op", + table: table, + op: "and", + exprs: lodash_1.default.compact([queryOptions.where || null].concat(lodash_1.default.compact(ctx.getFilters(contextVar.id).map(f => f.expr)))) + }; + if (queryOptions.where.exprs.length === 0) { + queryOptions.where = null; + } + } + // Create contextVars list that includes injected variable, adding it if not already present + const contextVars = ctx.contextVars.slice(); + const filteredContextVarValues = contexts_1.getFilteredContextVarValues(ctx); + if (!isExisting) { + contextVars.push(contextVar); + filteredContextVarValues[contextVar.id] = contextVarValue; } - }); + // Perform query + const rows = yield ctx.database.query(queryOptions, contextVars, filteredContextVarValues); + return rows.length == 1 ? rows[0].value : null; + } + throw new Error("Context variable type not supported"); }); } exports.evalContextVarExpr = evalContextVarExpr; diff --git a/lib/widgets/evalContextVarExpr.test.js b/lib/widgets/evalContextVarExpr.test.js index 4fbc1e73..33c39240 100644 --- a/lib/widgets/evalContextVarExpr.test.js +++ b/lib/widgets/evalContextVarExpr.test.js @@ -8,46 +8,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge 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 __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -var mockDatabase_1 = __importDefault(require("../__fixtures__/mockDatabase")); -var schema_1 = __importDefault(require("../__fixtures__/schema")); -var evalContextVarExpr_1 = require("./evalContextVarExpr"); -var database; -var outerRenderProps; -var schema = schema_1.default(); -beforeEach(function () { - var db = mockDatabase_1.default(); - db.query = jest.fn(function () { return Promise.resolve([{ value: "abc" }]); }); +const mockDatabase_1 = __importDefault(require("../__fixtures__/mockDatabase")); +const schema_1 = __importDefault(require("../__fixtures__/schema")); +const evalContextVarExpr_1 = require("./evalContextVarExpr"); +let database; +let outerRenderProps; +const schema = schema_1.default(); +beforeEach(() => { + const db = mockDatabase_1.default(); + db.query = jest.fn(() => Promise.resolve([{ value: "abc" }])); database = db; outerRenderProps = { locale: "en", @@ -65,121 +38,76 @@ beforeEach(function () { getFilters: jest.fn(), renderChildBlock: jest.fn(), createBlock: jest.fn(), - registerForValidation: function () { return function () { }; }, - T: function (str) { return str; } + registerForValidation: () => () => { }, + T: (str) => str }; }); -test("exprs are computed for new row variables", function () { return __awaiter(void 0, void 0, void 0, function () { - var contextVar, value, contextVarExpr, result, queryOptions, expectedQueryOptions; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; - value = "1234"; - contextVarExpr = { type: "field", table: "t1", column: "c1" }; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: value, expr: contextVarExpr, ctx: outerRenderProps - }) - // Query should have been made - ]; - case 1: - result = _a.sent(); - queryOptions = database.query.mock.calls[0][0]; - expectedQueryOptions = { - select: { - value: contextVarExpr - }, - from: "t1", - where: { - type: "op", - op: "=", - table: "t1", - exprs: [{ type: "id", table: "t1" }, { type: "literal", valueType: "id", idTable: "t1", value: "1234" }] - } - }; - // Should perform the query - expect(queryOptions).toEqual(expectedQueryOptions); - // Should get the value - expect(result).toBe("abc"); - return [2 /*return*/]; - } +test("exprs are computed for new row variables", () => __awaiter(void 0, void 0, void 0, function* () { + const contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; + const value = "1234"; + const contextVarExpr = { type: "field", table: "t1", column: "c1" }; + const result = yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar, contextVarValue: value, expr: contextVarExpr, ctx: outerRenderProps }); -}); }); -test("exprs are null for null row variables", function () { return __awaiter(void 0, void 0, void 0, function () { - var contextVar, value, contextVarExpr, result; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; - value = null; - contextVarExpr = { type: "field", table: "t1", column: "c1" }; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: value, expr: contextVarExpr, ctx: outerRenderProps - }) - // Query should not have been made - ]; - case 1: - result = _a.sent(); - // Query should not have been made - expect(database.query.mock.calls.length).toBe(0); - // Should get the value as null - expect(result).toBeNull(); - return [2 /*return*/]; + // Query should have been made + const queryOptions = database.query.mock.calls[0][0]; + const expectedQueryOptions = { + select: { + value: contextVarExpr + }, + from: "t1", + where: { + type: "op", + op: "=", + table: "t1", + exprs: [{ type: "id", table: "t1" }, { type: "literal", valueType: "id", idTable: "t1", value: "1234" }] } + }; + // Should perform the query + expect(queryOptions).toEqual(expectedQueryOptions); + // Should get the value + expect(result).toBe("abc"); +})); +test("exprs are null for null row variables", () => __awaiter(void 0, void 0, void 0, function* () { + const contextVar = { id: "cv1", name: "cv1", type: "row", table: "t1" }; + const value = null; + const contextVarExpr = { type: "field", table: "t1", column: "c1" }; + const result = yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar, contextVarValue: value, expr: contextVarExpr, ctx: outerRenderProps }); -}); }); -test("exprs are computed for rowset variable", function () { return __awaiter(void 0, void 0, void 0, function () { - var contextVar, value, contextVarExpr, result, queryOptions, expectedQueryOptions; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; - value = { type: "literal", valueType: "boolean", value: false }; - contextVarExpr = { type: "op", table: "t1", op: "count", exprs: [] }; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: contextVar, - contextVarValue: value, expr: contextVarExpr, ctx: outerRenderProps - }) - // Query should have been made - ]; - case 1: - result = _a.sent(); - queryOptions = database.query.mock.calls[0][0]; - expectedQueryOptions = { - select: { - value: contextVarExpr - }, - distinct: false, - from: "t1", - where: value, - limit: 2 - }; - // Should perform the query - expect(queryOptions).toEqual(expectedQueryOptions); - // Should get the value - expect(result).toBe("abc"); - return [2 /*return*/]; - } + // Query should not have been made + expect(database.query.mock.calls.length).toBe(0); + // Should get the value as null + expect(result).toBeNull(); +})); +test("exprs are computed for rowset variable", () => __awaiter(void 0, void 0, void 0, function* () { + const contextVar = { id: "cv1", name: "cv1", type: "rowset", table: "t1" }; + const value = { type: "literal", valueType: "boolean", value: false }; + const contextVarExpr = { type: "op", table: "t1", op: "count", exprs: [] }; + const result = yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar, contextVarValue: value, expr: contextVarExpr, ctx: outerRenderProps }); -}); }); -test("exprs are computed for literals", function () { return __awaiter(void 0, void 0, void 0, function () { - var expr, result; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - expr = { type: "literal", valueType: "text", value: "abc" }; - return [4 /*yield*/, evalContextVarExpr_1.evalContextVarExpr({ - contextVar: null, contextVarValue: null, expr: expr, ctx: outerRenderProps - }) - // Should get the value - ]; - case 1: - result = _a.sent(); - // Should get the value - expect(result).toBe("abc"); - return [2 /*return*/]; - } + // Query should have been made + const queryOptions = database.query.mock.calls[0][0]; + const expectedQueryOptions = { + select: { + value: contextVarExpr + }, + distinct: false, + from: "t1", + where: value, + limit: 2 + }; + // Should perform the query + expect(queryOptions).toEqual(expectedQueryOptions); + // Should get the value + expect(result).toBe("abc"); +})); +test("exprs are computed for literals", () => __awaiter(void 0, void 0, void 0, function* () { + const expr = { type: "literal", valueType: "text", value: "abc" }; + const result = yield evalContextVarExpr_1.evalContextVarExpr({ + contextVar: null, contextVarValue: null, expr: expr, ctx: outerRenderProps }); -}); }); + // Should get the value + expect(result).toBe("abc"); +})); diff --git a/lib/widgets/propertyEditors.js b/lib/widgets/propertyEditors.js index ff569376..9b035938 100644 --- a/lib/widgets/propertyEditors.js +++ b/lib/widgets/propertyEditors.js @@ -1,28 +1,4 @@ "use strict"; -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 (b.hasOwnProperty(p)) d[p] = b[p]; }; - return extendStatics(d, b); - }; - 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) || 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 __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); @@ -47,20 +23,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TableColumnWidthEditor = exports.EmbeddedExprEditor = exports.EmbeddedExprsEditor = exports.EnumArrayEditor = exports.TableSelect = exports.DatetimeFormatEditor = exports.DateFormatEditor = exports.NumberFormatEditor = exports.OrderByEditor = exports.OrderByArrayEditor = exports.ActionDefEditor = exports.ContextVarExprPropertyEditor = exports.ContextVarPropertyEditor = exports.DropdownPropertyEditor = exports.LocalizedTextPropertyEditor = exports.PropertyEditor = exports.LabeledProperty = void 0; -var lodash_1 = __importDefault(require("lodash")); -var React = __importStar(require("react")); -var bootstrap_1 = require("react-library/lib/bootstrap"); -var blocks_1 = require("./blocks"); -var mwater_expressions_1 = require("mwater-expressions"); -var ListEditor_1 = __importDefault(require("./ListEditor")); -var mwater_expressions_ui_1 = require("mwater-expressions-ui"); -var PropTypes = __importStar(require("prop-types")); -var react_select_1 = __importDefault(require("react-select")); -var localization_1 = require("./localization"); -var collapsible_1 = require("./blocks/collapsible"); +const lodash_1 = __importDefault(require("lodash")); +const React = __importStar(require("react")); +const bootstrap_1 = require("react-library/lib/bootstrap"); +const blocks_1 = require("./blocks"); +const mwater_expressions_1 = require("mwater-expressions"); +const ListEditor_1 = __importDefault(require("./ListEditor")); +const mwater_expressions_ui_1 = require("mwater-expressions-ui"); +const PropTypes = __importStar(require("prop-types")); +const react_select_1 = __importDefault(require("react-select")); +const localization_1 = require("./localization"); +const collapsible_1 = require("./blocks/collapsible"); /* Components to build property editors. These may use bootstrap 3 as needed. */ /** Labeled group */ -exports.LabeledProperty = function (props) { +exports.LabeledProperty = (props) => { return (React.createElement("div", { className: "form-group" }, React.createElement("label", null, props.label, @@ -72,48 +48,42 @@ exports.LabeledProperty = function (props) { React.createElement("p", { className: "help-block", style: { marginLeft: 5 } }, props.help))); }; /** Creates a property editor for a property */ -var PropertyEditor = /** @class */ (function (_super) { - __extends(PropertyEditor, _super); - function PropertyEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleChange = function (value) { - var _a; - _this.props.onChange(Object.assign({}, _this.props.obj, (_a = {}, _a[_this.props.property] = value, _a))); +class PropertyEditor extends React.Component { + constructor() { + super(...arguments); + this.handleChange = (value) => { + this.props.onChange(Object.assign({}, this.props.obj, { [this.props.property]: value })); }; - return _this; } - PropertyEditor.prototype.render = function () { - var value = this.props.obj[this.props.property]; + render() { + const value = this.props.obj[this.props.property]; return this.props.children(value, this.handleChange); - }; - return PropertyEditor; -}(React.Component)); + } +} exports.PropertyEditor = PropertyEditor; -var LocalizedTextPropertyEditor = /** @class */ (function (_super) { - __extends(LocalizedTextPropertyEditor, _super); - function LocalizedTextPropertyEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleChange = function (e) { - var locale = _this.props.locale || "en"; - var str = e.target.value; - if (!_this.props.allowCR) { +class LocalizedTextPropertyEditor extends React.Component { + constructor() { + super(...arguments); + this.handleChange = (e) => { + const locale = this.props.locale || "en"; + let str = e.target.value; + if (!this.props.allowCR) { str = str.replace(/[\r\n]+/g, " "); } if (!str) { - _this.props.onChange(null); + this.props.onChange(null); return; } - var value = Object.assign({}, _this.props.value || {}); - value._base = _this.props.locale; + const value = Object.assign({}, this.props.value || {}); + value._base = this.props.locale; value[locale] = str; - _this.props.onChange(value); + this.props.onChange(value); }; - return _this; } - LocalizedTextPropertyEditor.prototype.render = function () { - var value = this.props.value || { _base: "en" }; - var locale = this.props.locale || "en"; - var str = ""; + render() { + const value = this.props.value || { _base: "en" }; + const locale = this.props.locale || "en"; + let str = ""; if (value[locale]) { str = value[locale]; } @@ -122,130 +92,105 @@ var LocalizedTextPropertyEditor = /** @class */ (function (_super) { React.createElement("textarea", { className: "form-control", value: str, onChange: this.handleChange, placeholder: this.props.placeholder, rows: 5 }) : React.createElement("input", { className: "form-control", type: "text", value: str, onChange: this.handleChange, placeholder: this.props.placeholder })); - }; - return LocalizedTextPropertyEditor; -}(React.Component)); + } +} exports.LocalizedTextPropertyEditor = LocalizedTextPropertyEditor; -var DropdownPropertyEditor = /** @class */ (function (_super) { - __extends(DropdownPropertyEditor, _super); - function DropdownPropertyEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleChange = function (value) { - var _a; - _this.props.onChange(Object.assign({}, _this.props.obj, (_a = {}, _a[_this.props.property] = value, _a))); +class DropdownPropertyEditor extends React.Component { + constructor() { + super(...arguments); + this.handleChange = (value) => { + this.props.onChange(Object.assign({}, this.props.obj, { [this.props.property]: value })); }; - return _this; } - DropdownPropertyEditor.prototype.render = function () { - var value = this.props.obj[this.props.property]; + render() { + const value = this.props.obj[this.props.property]; return (React.createElement(bootstrap_1.Select, { value: value, onChange: this.handleChange, options: this.props.options, nullLabel: this.props.nullLabel })); - }; - return DropdownPropertyEditor; -}(React.Component)); + } +} exports.DropdownPropertyEditor = DropdownPropertyEditor; /** Allows selecting a context variable */ -var ContextVarPropertyEditor = /** @class */ (function (_super) { - __extends(ContextVarPropertyEditor, _super); - function ContextVarPropertyEditor() { - return _super !== null && _super.apply(this, arguments) || this; - } - ContextVarPropertyEditor.prototype.render = function () { - var _this = this; - var contextVars = this.props.contextVars.filter(function (cv) { return !_this.props.types || _this.props.types.includes(cv.type); }); - contextVars = contextVars.filter(function (cv) { return !_this.props.table || _this.props.table === cv.table; }); +class ContextVarPropertyEditor extends React.Component { + render() { + let contextVars = this.props.contextVars.filter(cv => !this.props.types || this.props.types.includes(cv.type)); + contextVars = contextVars.filter(cv => !this.props.table || this.props.table === cv.table); if (this.props.filter) { contextVars.filter(this.props.filter); } - return React.createElement(bootstrap_1.Select, { value: this.props.value, onChange: this.props.onChange, nullLabel: this.props.nullLabel ? this.props.nullLabel : "Select...", options: contextVars.map(function (cv) { return ({ label: cv.name, value: cv.id }); }) }); - }; - return ContextVarPropertyEditor; -}(React.Component)); + return React.createElement(bootstrap_1.Select, { value: this.props.value, onChange: this.props.onChange, nullLabel: this.props.nullLabel ? this.props.nullLabel : "Select...", options: contextVars.map(cv => ({ label: cv.name, value: cv.id })) }); + } +} exports.ContextVarPropertyEditor = ContextVarPropertyEditor; /** Edits both a context variable selection and a related expression */ -exports.ContextVarExprPropertyEditor = function (props) { - var contextVar = props.contextVars.find(function (cv) { return cv.id === props.contextVarId; }); +exports.ContextVarExprPropertyEditor = (props) => { + const contextVar = props.contextVars.find(cv => cv.id === props.contextVarId); // Get all context variables up to an including one above. All context variables if null // This is because an outer context var expr cannot reference an inner context variable - var cvIndex = props.contextVars.findIndex(function (cv) { return cv.id === props.contextVarId; }); - var availContextVars = cvIndex >= 0 ? lodash_1.default.take(props.contextVars, cvIndex + 1) : props.contextVars; + const cvIndex = props.contextVars.findIndex(cv => cv.id === props.contextVarId); + const availContextVars = cvIndex >= 0 ? lodash_1.default.take(props.contextVars, cvIndex + 1) : props.contextVars; return React.createElement("div", { style: { border: "solid 1px #DDD", borderRadius: 5, padding: 10 } }, - React.createElement(ContextVarPropertyEditor, { value: props.contextVarId, onChange: function (cv) { props.onChange(cv, null); }, nullLabel: "No Row/Rowset", contextVars: props.contextVars, types: ["row", "rowset"] }), + React.createElement(ContextVarPropertyEditor, { value: props.contextVarId, onChange: cv => { props.onChange(cv, null); }, nullLabel: "No Row/Rowset", contextVars: props.contextVars, types: ["row", "rowset"] }), React.createElement("div", { style: { paddingTop: 10 } }, - React.createElement(mwater_expressions_ui_1.ExprComponent, { value: props.expr, onChange: function (expr) { props.onChange(props.contextVarId, expr); }, schema: props.schema, dataSource: props.dataSource, aggrStatuses: props.aggrStatuses, types: props.types, variables: blocks_1.createExprVariables(availContextVars), table: contextVar ? contextVar.table || null : null, enumValues: props.enumValues, idTable: props.idTable }))); + React.createElement(mwater_expressions_ui_1.ExprComponent, { value: props.expr, onChange: expr => { props.onChange(props.contextVarId, expr); }, schema: props.schema, dataSource: props.dataSource, aggrStatuses: props.aggrStatuses, types: props.types, variables: blocks_1.createExprVariables(availContextVars), table: contextVar ? contextVar.table || null : null, enumValues: props.enumValues, idTable: props.idTable }))); }; /** Edits an action definition, allowing selection of action */ -var ActionDefEditor = /** @class */ (function (_super) { - __extends(ActionDefEditor, _super); - function ActionDefEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleChangeAction = function (type) { +class ActionDefEditor extends React.Component { + constructor() { + super(...arguments); + this.handleChangeAction = (type) => { if (type) { - _this.props.onChange(_this.props.designCtx.actionLibrary.createNewActionDef(type)); + this.props.onChange(this.props.designCtx.actionLibrary.createNewActionDef(type)); } else { - _this.props.onChange(null); + this.props.onChange(null); } }; - return _this; } - ActionDefEditor.prototype.render = function () { - var action = this.props.value ? this.props.designCtx.actionLibrary.createAction(this.props.value) : null; + render() { + const action = this.props.value ? this.props.designCtx.actionLibrary.createAction(this.props.value) : null; return (React.createElement("div", null, - React.createElement(bootstrap_1.Select, { nullLabel: "No Action", onChange: this.handleChangeAction, value: this.props.value ? this.props.value.type : null, options: this.props.designCtx.actionLibrary.getActionTypes().map(function (at) { return ({ label: at.name, value: at.type }); }) }), + React.createElement(bootstrap_1.Select, { nullLabel: "No Action", onChange: this.handleChangeAction, value: this.props.value ? this.props.value.type : null, options: this.props.designCtx.actionLibrary.getActionTypes().map(at => ({ label: at.name, value: at.type })) }), action ? React.createElement(collapsible_1.CollapsibleComponent, { label: "Details" }, - React.createElement("div", { style: { paddingLeft: 10 } }, action.renderEditor(__assign(__assign({}, this.props.designCtx), { onChange: this.props.onChange })))) + React.createElement("div", { style: { paddingLeft: 10 } }, action.renderEditor(Object.assign(Object.assign({}, this.props.designCtx), { onChange: this.props.onChange })))) : null)); - }; - return ActionDefEditor; -}(React.Component)); + } +} exports.ActionDefEditor = ActionDefEditor; /** Edits an array of order by expressions */ -var OrderByArrayEditor = /** @class */ (function (_super) { - __extends(OrderByArrayEditor, _super); - function OrderByArrayEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleAddOrderByExpr = function () { - _this.props.onChange((_this.props.value || []).concat([{ expr: null, dir: "asc" }])); +class OrderByArrayEditor extends React.Component { + constructor() { + super(...arguments); + this.handleAddOrderByExpr = () => { + this.props.onChange((this.props.value || []).concat([{ expr: null, dir: "asc" }])); }; - return _this; } - OrderByArrayEditor.prototype.render = function () { - var _this = this; + render() { return (React.createElement("div", null, - React.createElement(ListEditor_1.default, { items: this.props.value || [], onItemsChange: this.props.onChange }, function (orderBy, onOrderByChange) { return (React.createElement(OrderByEditor, { value: orderBy, schema: _this.props.schema, dataSource: _this.props.dataSource, onChange: onOrderByChange, table: _this.props.table, contextVars: _this.props.contextVars })); }), + React.createElement(ListEditor_1.default, { items: this.props.value || [], onItemsChange: this.props.onChange }, (orderBy, onOrderByChange) => (React.createElement(OrderByEditor, { value: orderBy, schema: this.props.schema, dataSource: this.props.dataSource, onChange: onOrderByChange, table: this.props.table, contextVars: this.props.contextVars }))), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: this.handleAddOrderByExpr }, "+ Add Order By"))); - }; - return OrderByArrayEditor; -}(React.Component)); + } +} exports.OrderByArrayEditor = OrderByArrayEditor; -var OrderByEditor = /** @class */ (function (_super) { - __extends(OrderByEditor, _super); - function OrderByEditor() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleExprChange = function (expr) { - _this.props.onChange(__assign(__assign({}, _this.props.value), { expr: expr })); +class OrderByEditor extends React.Component { + constructor() { + super(...arguments); + this.handleExprChange = (expr) => { + this.props.onChange(Object.assign(Object.assign({}, this.props.value), { expr: expr })); }; - _this.handleDirToggle = function () { - _this.props.onChange(__assign(__assign({}, _this.props.value), { dir: (_this.props.value.dir === "asc") ? "desc" : "asc" })); + this.handleDirToggle = () => { + this.props.onChange(Object.assign(Object.assign({}, this.props.value), { dir: (this.props.value.dir === "asc") ? "desc" : "asc" })); }; - return _this; } - OrderByEditor.prototype.render = function () { + render() { return (React.createElement("div", { style: { display: "grid", gridTemplateColumns: "auto 1fr" } }, React.createElement("a", { onClick: this.handleDirToggle }, this.props.value.dir === "asc" ? React.createElement("i", { className: "fa fa-arrow-up" }) : React.createElement("i", { className: "fa fa-arrow-down" })), React.createElement(mwater_expressions_ui_1.ExprComponent, { schema: this.props.schema, dataSource: this.props.dataSource, types: ["text", "number", "enum", "boolean", "date", "datetime"], table: this.props.table, value: this.props.value.expr, variables: blocks_1.createExprVariables(this.props.contextVars), onChange: this.handleExprChange }))); - }; - return OrderByEditor; -}(React.Component)); + } +} exports.OrderByEditor = OrderByEditor; /** Edits a d3 format */ -var NumberFormatEditor = /** @class */ (function (_super) { - __extends(NumberFormatEditor, _super); - function NumberFormatEditor() { - return _super !== null && _super.apply(this, arguments) || this; - } - NumberFormatEditor.prototype.render = function () { +class NumberFormatEditor extends React.Component { + render() { return (React.createElement(bootstrap_1.Select, { value: this.props.value || "", onChange: this.props.onChange, options: [ { value: ",", label: "Normal: 1,234.567" }, { value: "", label: "Plain: 1234.567" }, @@ -257,17 +202,12 @@ var NumberFormatEditor = /** @class */ (function (_super) { { value: ".1%", label: "Percent rounded: 12.3%" }, { value: ".2%", label: "Percent rounded: 12.34%" } ] })); - }; - return NumberFormatEditor; -}(React.Component)); + } +} exports.NumberFormatEditor = NumberFormatEditor; /** Edits a moment.js date format */ -var DateFormatEditor = /** @class */ (function (_super) { - __extends(DateFormatEditor, _super); - function DateFormatEditor() { - return _super !== null && _super.apply(this, arguments) || this; - } - DateFormatEditor.prototype.render = function () { +class DateFormatEditor extends React.Component { + render() { return (React.createElement(bootstrap_1.Select, { value: this.props.value || "", onChange: this.props.onChange, nullLabel: "Short (Sep 4, 1986)", options: [ { value: "LL", label: "Long (September 4, 1986)" }, { value: "ll", label: "Short (Sep 4, 1986)" }, @@ -276,17 +216,12 @@ var DateFormatEditor = /** @class */ (function (_super) { { value: "MMM YYYY", label: "Month Year (Apr 1986)" }, { value: "YYYY", label: "YYYY (1986)" }, ] })); - }; - return DateFormatEditor; -}(React.Component)); + } +} exports.DateFormatEditor = DateFormatEditor; /** Edits a moment.js datetime format */ -var DatetimeFormatEditor = /** @class */ (function (_super) { - __extends(DatetimeFormatEditor, _super); - function DatetimeFormatEditor() { - return _super !== null && _super.apply(this, arguments) || this; - } - DatetimeFormatEditor.prototype.render = function () { +class DatetimeFormatEditor extends React.Component { + render() { return (React.createElement(bootstrap_1.Select, { value: this.props.value || "", onChange: this.props.onChange, nullLabel: "Short (Sep 4, 1986 8:30 PM)", options: [ { value: "llll", label: "Medium (Thu, Sep 4, 1986 8:30 PM)" }, { value: "LLLL", label: "Long (Thursday, September 4, 1986 8:30 PM)" }, @@ -297,95 +232,88 @@ var DatetimeFormatEditor = /** @class */ (function (_super) { { value: "MMM YYYY", label: "Month Year (Apr 1986)" }, { value: "YYYY", label: "YYYY (1986)" }, ] })); - }; - return DatetimeFormatEditor; -}(React.Component)); + } +} exports.DatetimeFormatEditor = DatetimeFormatEditor; /** Allow selecting a table */ -var TableSelect = /** @class */ (function (_super) { - __extends(TableSelect, _super); - function TableSelect() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.handleTableChange = function (table) { - _this.props.onChange(table.id); +class TableSelect extends React.Component { + constructor() { + super(...arguments); + this.handleTableChange = (table) => { + this.props.onChange(table.id); }; - _this.getOptionLabel = function (table) { return localization_1.localize(table.name, _this.props.locale); }; - _this.getOptionValue = function (table) { return table.id; }; - return _this; + this.getOptionLabel = (table) => localization_1.localize(table.name, this.props.locale); + this.getOptionValue = (table) => table.id; } - TableSelect.prototype.render = function () { - var _this = this; + render() { if (this.context.tableSelectElementFactory) { return this.context.tableSelectElementFactory({ schema: this.props.schema, value: this.props.value || null, onChange: this.props.onChange }); } - var tables = lodash_1.default.sortBy(this.props.schema.getTables(), function (table) { return localization_1.localize(table.name, _this.props.locale); }); - return React.createElement(react_select_1.default, { value: tables.find(function (t) { return t.id === _this.props.value; }) || null, options: tables, onChange: this.handleTableChange, getOptionLabel: this.getOptionLabel, getOptionValue: this.getOptionValue, isClearable: this.props.allowNull, menuPortalTarget: document.body, styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); - }; - TableSelect.contextTypes = { - tableSelectElementFactory: PropTypes.func // Can be overridden by setting tableSelectElementFactory in context that takes ({ schema, value, onChange, filter, onFilterChange }) - }; - return TableSelect; -}(React.Component)); + const tables = lodash_1.default.sortBy(this.props.schema.getTables(), (table) => localization_1.localize(table.name, this.props.locale)); + return React.createElement(react_select_1.default, { value: tables.find(t => t.id === this.props.value) || null, options: tables, onChange: this.handleTableChange, getOptionLabel: this.getOptionLabel, getOptionValue: this.getOptionValue, isClearable: this.props.allowNull, menuPortalTarget: document.body, styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); + } +} exports.TableSelect = TableSelect; +TableSelect.contextTypes = { + tableSelectElementFactory: PropTypes.func // Can be overridden by setting tableSelectElementFactory in context that takes ({ schema, value, onChange, filter, onFilterChange }) +}; /** Edits an array of enum values */ -exports.EnumArrayEditor = function (props) { +exports.EnumArrayEditor = (props) => { // Map value to array - var value = null; + let value = null; if (props.value) { - value = lodash_1.default.compact((props.value || []).map(function (v) { return props.enumValues.find(function (ev) { return ev.id === v; }); })); + value = lodash_1.default.compact((props.value || []).map((v) => props.enumValues.find(ev => ev.id === v))); } - var getOptionLabel = function (ev) { return localization_1.localize(ev.name, props.locale); }; - var getOptionValue = function (ev) { return ev.id; }; - var handleChange = function (evs) { - props.onChange(evs && evs.length > 0 ? evs.map(function (ev) { return ev.id; }) : null); + const getOptionLabel = (ev) => localization_1.localize(ev.name, props.locale); + const getOptionValue = (ev) => ev.id; + const handleChange = (evs) => { + props.onChange(evs && evs.length > 0 ? evs.map(ev => ev.id) : null); }; - return React.createElement(react_select_1.default, { value: value, onChange: handleChange, options: props.enumValues, placeholder: props.placeholder, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isClearable: true, isMulti: true, menuPortalTarget: document.body, styles: { menuPortal: function (style) { return (__assign(__assign({}, style), { zIndex: 2000 })); } } }); + return React.createElement(react_select_1.default, { value: value, onChange: handleChange, options: props.enumValues, placeholder: props.placeholder, getOptionLabel: getOptionLabel, getOptionValue: getOptionValue, isClearable: true, isMulti: true, menuPortalTarget: document.body, styles: { menuPortal: style => (Object.assign(Object.assign({}, style), { zIndex: 2000 })) } }); }; /** Edits embedded expressions. */ -exports.EmbeddedExprsEditor = function (props) { - var value = props.value, onChange = props.onChange, schema = props.schema, dataSource = props.dataSource, contextVars = props.contextVars; - var handleAddEmbeddedExpr = function () { - var defaultContextVar = props.contextVars.find(function (cv) { return cv.type === "rowset" || cv.type === "row"; }); +exports.EmbeddedExprsEditor = (props) => { + const { value, onChange, schema, dataSource, contextVars } = props; + const handleAddEmbeddedExpr = () => { + const defaultContextVar = props.contextVars.find(cv => cv.type === "rowset" || cv.type === "row"); onChange((value || []).concat([{ contextVarId: defaultContextVar ? defaultContextVar.id : null, expr: null, format: null }])); }; return (React.createElement("div", null, - React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onChange }, function (item, onItemChange, index) { - return React.createElement(exports.EmbeddedExprEditor, { value: item, onChange: onItemChange, schema: schema, dataSource: dataSource, contextVars: contextVars, index: index }); - }), + React.createElement(ListEditor_1.default, { items: value || [], onItemsChange: onChange }, (item, onItemChange, index) => React.createElement(exports.EmbeddedExprEditor, { value: item, onChange: onItemChange, schema: schema, dataSource: dataSource, contextVars: contextVars, index: index })), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddEmbeddedExpr }, "+ Add Embedded Expression"))); }; /** Allows editing of an embedded expression */ -exports.EmbeddedExprEditor = function (props) { - var schema = props.schema, dataSource = props.dataSource, contextVars = props.contextVars; - var handleChange = function (contextVarId, expr) { - var exprType = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)).getExprType(props.value.expr); - var newExprType = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)).getExprType(expr); +exports.EmbeddedExprEditor = (props) => { + const { schema, dataSource, contextVars } = props; + const handleChange = (contextVarId, expr) => { + const exprType = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)).getExprType(props.value.expr); + const newExprType = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)).getExprType(expr); if (newExprType !== exprType) { - props.onChange(__assign(__assign({}, props.value), { contextVarId: contextVarId, expr: expr, format: null })); + props.onChange(Object.assign(Object.assign({}, props.value), { contextVarId: contextVarId, expr: expr, format: null })); } else { - props.onChange(__assign(__assign({}, props.value), { contextVarId: contextVarId, expr: expr })); + props.onChange(Object.assign(Object.assign({}, props.value), { contextVarId: contextVarId, expr: expr })); } }; - var exprType = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)).getExprType(props.value.expr); + const exprType = new mwater_expressions_1.ExprUtils(schema, blocks_1.createExprVariables(contextVars)).getExprType(props.value.expr); return (React.createElement("div", null, - React.createElement(exports.LabeledProperty, { label: "Expression \"{" + props.index + "}\"" }, + React.createElement(exports.LabeledProperty, { label: `Expression "{${props.index}}"` }, React.createElement(exports.ContextVarExprPropertyEditor, { contextVarId: props.value.contextVarId, expr: props.value.expr, onChange: handleChange, schema: schema, dataSource: dataSource, contextVars: contextVars, aggrStatuses: ["individual", "aggregate", "literal"] })), exprType === "number" ? React.createElement(exports.LabeledProperty, { label: "Number Format" }, - React.createElement(PropertyEditor, { obj: props.value, onChange: props.onChange, property: "format" }, function (value, onChange) { return (React.createElement(NumberFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(PropertyEditor, { obj: props.value, onChange: props.onChange, property: "format" }, (value, onChange) => (React.createElement(NumberFormatEditor, { value: value, onChange: onChange })))) : null, exprType === "date" ? React.createElement(exports.LabeledProperty, { label: "Date Format" }, - React.createElement(PropertyEditor, { obj: props.value, onChange: props.onChange, property: "format" }, function (value, onChange) { return (React.createElement(DateFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(PropertyEditor, { obj: props.value, onChange: props.onChange, property: "format" }, (value, onChange) => (React.createElement(DateFormatEditor, { value: value, onChange: onChange })))) : null, exprType === "datetime" ? React.createElement(exports.LabeledProperty, { label: "Date/time Format" }, - React.createElement(PropertyEditor, { obj: props.value, onChange: props.onChange, property: "format" }, function (value, onChange) { return (React.createElement(DatetimeFormatEditor, { value: value, onChange: onChange })); })) + React.createElement(PropertyEditor, { obj: props.value, onChange: props.onChange, property: "format" }, (value, onChange) => (React.createElement(DatetimeFormatEditor, { value: value, onChange: onChange })))) : null)); }; /** Edits the width of a table column */ -exports.TableColumnWidthEditor = function (props) { +exports.TableColumnWidthEditor = (props) => { return React.createElement(bootstrap_1.Select, { value: props.columnWidth, onChange: props.onChange, options: [ { value: "auto", label: "Auto" }, { value: "1px", label: "Small as possible" }, diff --git a/lib/widgets/scrolling.js b/lib/widgets/scrolling.js index 29fb89e7..a093e75e 100644 --- a/lib/widgets/scrolling.js +++ b/lib/widgets/scrolling.js @@ -3,9 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.getScrollParent = void 0; // From: https://gist.github.com/twxia/bb20843c495a49644be6ea3804c0d775 function getScrollParent(node) { - var isElement = node instanceof HTMLElement; - var overflowY = isElement && window.getComputedStyle(node).overflowY; - var isScrollable = overflowY !== 'visible' && overflowY !== 'hidden'; + const isElement = node instanceof HTMLElement; + const overflowY = isElement && window.getComputedStyle(node).overflowY; + const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden'; if (!node) { return null; } diff --git a/lib/widgets/widgets.js b/lib/widgets/widgets.js index 1c5d2637..043c113a 100644 --- a/lib/widgets/widgets.js +++ b/lib/widgets/widgets.js @@ -1,50 +1,36 @@ "use strict"; -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); -}; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateWidget = void 0; -var contextVarValues_1 = require("../contextVarValues"); -var blocks_1 = require("./blocks"); +const contextVarValues_1 = require("../contextVarValues"); +const blocks_1 = require("./blocks"); /** Validate a widget, optionally also validating all children */ function validateWidget(widgetDef, ctx, includeChildren) { if (!widgetDef.blockDef) { return null; } - var globalContextVars = ctx.globalContextVars || []; + const globalContextVars = ctx.globalContextVars || []; // Validate context var values - for (var _i = 0, _a = widgetDef.contextVars; _i < _a.length; _i++) { - var cv = _a[_i]; - var error = contextVarValues_1.validateContextVarValue(ctx.schema, cv, globalContextVars.concat(widgetDef.contextVars), widgetDef.contextVarPreviewValues[cv.id]); + for (const cv of widgetDef.contextVars) { + const error = contextVarValues_1.validateContextVarValue(ctx.schema, cv, globalContextVars.concat(widgetDef.contextVars), widgetDef.contextVarPreviewValues[cv.id]); if (error) { return error; } } // Validate private context var values - var privateContextVars = widgetDef.privateContextVars || []; - for (var _b = 0, privateContextVars_1 = privateContextVars; _b < privateContextVars_1.length; _b++) { - var cv = privateContextVars_1[_b]; - var error = contextVarValues_1.validateContextVarValue(ctx.schema, cv, globalContextVars.concat(widgetDef.contextVars.concat(privateContextVars)), (widgetDef.privateContextVarValues || {})[cv.id]); + const privateContextVars = widgetDef.privateContextVars || []; + for (const cv of privateContextVars) { + const error = contextVarValues_1.validateContextVarValue(ctx.schema, cv, globalContextVars.concat(widgetDef.contextVars.concat(privateContextVars)), (widgetDef.privateContextVarValues || {})[cv.id]); if (error) { return error; } } if (includeChildren) { - var contextVars = globalContextVars.concat(widgetDef.contextVars).concat(privateContextVars); - for (var _c = 0, _d = blocks_1.getBlockTree(widgetDef.blockDef, ctx.createBlock, contextVars); _c < _d.length; _c++) { - var childBlock = _d[_c]; - var block = ctx.createBlock(childBlock.blockDef); + const contextVars = globalContextVars.concat(widgetDef.contextVars).concat(privateContextVars); + for (const childBlock of blocks_1.getBlockTree(widgetDef.blockDef, ctx.createBlock, contextVars)) { + const block = ctx.createBlock(childBlock.blockDef); // Create design context for validating block - var blockDesignCtx = __assign(__assign({}, ctx), { dataSource: ctx.dataSource, contextVars: childBlock.contextVars, store: new blocks_1.NullBlockStore(), blockPaletteEntries: [], selectedId: null, renderChildBlock: function () { throw new Error("Not implemented"); } }); - var error = block.validate(blockDesignCtx); + const blockDesignCtx = Object.assign(Object.assign({}, ctx), { dataSource: ctx.dataSource, contextVars: childBlock.contextVars, store: new blocks_1.NullBlockStore(), blockPaletteEntries: [], selectedId: null, renderChildBlock: () => { throw new Error("Not implemented"); } }); + const error = block.validate(blockDesignCtx); if (error) { return error; } diff --git a/tsconfig.json b/tsconfig.json index 9cb52e92..ea08290f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "baseUrl": ".", "module": "commonjs", - "target": "es5", + "target": "ES2016", "lib": ["es2017", "dom"], "sourceMap": true, "jsx": "react",