From f1a6f724bbe83a49b3123e88594c5806a14b4b44 Mon Sep 17 00:00:00 2001 From: Clayton Grassick Date: Fri, 11 Jun 2021 09:52:03 -0400 Subject: [PATCH] Added text[] search --- .../blocks/search/SearchBlockInstance.d.ts | 2 +- .../blocks/search/SearchBlockInstance.js | 53 +++++++++---------- lib/widgets/blocks/search/search.js | 4 +- package-lock.json | 6 +-- .../blocks/search/SearchBlockInstance.tsx | 16 +++++- src/widgets/blocks/search/search.tsx | 4 +- 6 files changed, 46 insertions(+), 39 deletions(-) diff --git a/lib/widgets/blocks/search/SearchBlockInstance.d.ts b/lib/widgets/blocks/search/SearchBlockInstance.d.ts index a6280305..36caf156 100644 --- a/lib/widgets/blocks/search/SearchBlockInstance.d.ts +++ b/lib/widgets/blocks/search/SearchBlockInstance.d.ts @@ -1,4 +1,4 @@ -import * as React from "react"; +import React from "react"; import { SearchBlockDef } from "./search"; import { InstanceCtx } from "../../../contexts"; /** Search block that filters the rowset */ diff --git a/lib/widgets/blocks/search/SearchBlockInstance.js b/lib/widgets/blocks/search/SearchBlockInstance.js index 405881c5..7bf008da 100644 --- a/lib/widgets/blocks/search/SearchBlockInstance.js +++ b/lib/widgets/blocks/search/SearchBlockInstance.js @@ -1,37 +1,21 @@ "use strict"; -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]; } }); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); -}) : function(o, v) { - o["default"] = v; -}); -var __importStar = (this && this.__importStar) || function (mod) { - if (mod && mod.__esModule) return mod; - var result = {}; - if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); - __setModuleDefault(result, mod); - return result; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SearchControl = void 0; -const React = __importStar(require("react")); +const react_1 = __importDefault(require("react")); const blocks_1 = require("../../blocks"); const mwater_expressions_1 = require("mwater-expressions"); const localization_1 = require("../../localization"); -const react_1 = require("react"); +const react_2 = require("react"); /** Search block that filters the rowset */ const SearchBlockInstance = (props) => { const { blockDef, instanceCtx } = props; - const [searchText, setSearchText] = react_1.useState(""); - const searchControlRef = react_1.useRef(null); + const [searchText, setSearchText] = react_2.useState(""); + const searchControlRef = react_2.useRef(null); // Focus if enabled - react_1.useEffect(() => { + react_2.useEffect(() => { if (blockDef.autoFocus && searchControlRef.current) { searchControlRef.current.focus(); } @@ -52,6 +36,17 @@ const SearchBlockInstance = (props) => { ] }; } + if (exprType === "text[]") { + return { + type: "op", + op: "~*", + table: table, + exprs: [ + { type: "op", op: "to_text", table: table, exprs: [expr] }, + { type: "literal", valueType: "text", value: escapeRegex(searchText) } + ] + }; + } if (exprType === "enum") { // Find matching enums const enumValues = exprUtils.getExprEnumValues(expr).filter(ev => localization_1.localize(ev.name, instanceCtx.locale).toLowerCase().includes(searchText.toLowerCase())); @@ -108,14 +103,14 @@ const SearchBlockInstance = (props) => { // Set filter instanceCtx.setFilter(blockDef.rowsetContextVarId, createFilter(value)); }; - return React.createElement(SearchControl, { value: searchText, onChange: handleChange, ref: searchControlRef, placeholder: localization_1.localize(blockDef.placeholder, instanceCtx.locale) }); + return react_1.default.createElement(SearchControl, { value: searchText, onChange: handleChange, ref: searchControlRef, placeholder: localization_1.localize(blockDef.placeholder, instanceCtx.locale) }); }; exports.default = SearchBlockInstance; /** Simple input box with magnifying glass */ -class SearchControl extends React.Component { +class SearchControl extends react_1.default.Component { constructor() { super(...arguments); - this.inputRef = React.createRef(); + this.inputRef = react_1.default.createRef(); this.handleChange = (ev) => { if (this.props.onChange) { this.props.onChange(ev.target.value); @@ -128,9 +123,9 @@ class SearchControl extends React.Component { } } 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 (react_1.default.createElement("div", { style: { position: "relative", display: "inline-block", margin: 5, width: "15em" } }, + react_1.default.createElement("i", { className: "fa fa-search", style: { position: "absolute", right: 8, top: 10, color: "#AAA", pointerEvents: "none" } }), + react_1.default.createElement("input", { type: "text", ref: this.inputRef, className: "form-control", style: { width: "100%" }, value: this.props.value, onChange: this.handleChange, placeholder: this.props.placeholder }))); } } exports.SearchControl = SearchControl; diff --git a/lib/widgets/blocks/search/search.js b/lib/widgets/blocks/search/search.js index 4466cb4b..0d63fd8b 100644 --- a/lib/widgets/blocks/search/search.js +++ b/lib/widgets/blocks/search/search.js @@ -50,7 +50,7 @@ class SearchBlock extends LeafBlock_1.default { } let error; // Validate expr - error = exprValidator.validateExpr(searchExpr, { table: rowsetCV.table, types: ["text", "enum", "enumset"] }); + error = exprValidator.validateExpr(searchExpr, { table: rowsetCV.table, types: ["text", "enum", "enumset", "text[]"] }); if (error) { return error; } @@ -76,7 +76,7 @@ class SearchBlock extends LeafBlock_1.default { onItemsChange(value.concat(null)); }; return (React.createElement("div", null, - 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(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", "text[]"], variables: blocks_1.createExprVariables(props.contextVars) }))), React.createElement("button", { type: "button", className: "btn btn-link btn-sm", onClick: handleAddSearchExpr }, "+ Add Expression"))); })) : null, diff --git a/package-lock.json b/package-lock.json index a2c243dc..924a74b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10962,9 +10962,9 @@ }, "dependencies": { "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.5.tgz", + "integrity": "sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA==", "requires": { "regenerator-runtime": "^0.13.4" } diff --git a/src/widgets/blocks/search/SearchBlockInstance.tsx b/src/widgets/blocks/search/SearchBlockInstance.tsx index 860f2b23..376cf243 100644 --- a/src/widgets/blocks/search/SearchBlockInstance.tsx +++ b/src/widgets/blocks/search/SearchBlockInstance.tsx @@ -1,8 +1,8 @@ -import * as React from "react"; +import _ from "lodash"; +import React from "react"; import { SearchBlockDef } from "./search"; import { createExprVariables, Filter } from "../../blocks"; import { Expr, ExprUtils } from "mwater-expressions"; -import * as _ from "lodash"; import { localize } from "../../localization"; import { InstanceCtx } from "../../../contexts"; import { useState, useRef, useEffect } from "react"; @@ -43,6 +43,18 @@ const SearchBlockInstance = (props: { } as Expr } + if (exprType === "text[]") { + return { + type: "op", + op: "~*", + table: table, + exprs: [ + { type: "op", op: "to_text", table: table, exprs: [expr] }, + { type: "literal", valueType: "text", value: escapeRegex(searchText) } + ] + } as Expr + } + if (exprType === "enum") { // Find matching enums const enumValues = exprUtils.getExprEnumValues(expr)!.filter(ev => localize(ev.name, instanceCtx.locale).toLowerCase().includes(searchText.toLowerCase())) diff --git a/src/widgets/blocks/search/search.tsx b/src/widgets/blocks/search/search.tsx index 2fef5ee9..11a0591e 100644 --- a/src/widgets/blocks/search/search.tsx +++ b/src/widgets/blocks/search/search.tsx @@ -48,7 +48,7 @@ export class SearchBlock extends LeafBlock { let error: string | null // Validate expr - error = exprValidator.validateExpr(searchExpr, { table: rowsetCV.table, types: ["text", "enum", "enumset"] }) + error = exprValidator.validateExpr(searchExpr, { table: rowsetCV.table, types: ["text", "enum", "enumset", "text[]"] }) if (error) { return error } @@ -95,7 +95,7 @@ export class SearchBlock extends LeafBlock { dataSource={props.dataSource} onChange={onExprChange} table={rowsetCV.table!} - types={["text", "enum", "enumset"]} + types={["text", "enum", "enumset", "text[]"]} variables={createExprVariables(props.contextVars)} /> )}