UNPKG

flipper-plugin

Version:

Flipper Desktop plugin SDK and components

148 lines 7.18 kB
"use strict"; /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (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.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PowerSearch = void 0; const React = __importStar(require("react")); const PowerSearchContainer_1 = require("./PowerSearchContainer"); const PowerSearchTermFinder_1 = require("./PowerSearchTermFinder"); const PowerSearchTerm_1 = require("./PowerSearchTerm"); const useLatestRef_1 = require("../../utils/useLatestRef"); const react_use_1 = require("react-use"); const theme_1 = require("../theme"); const icons_1 = require("@ant-design/icons"); const FlipperLib_1 = require("../../plugin/FlipperLib"); const OPTION_KEY_DELIMITER = '::'; const PowerSearch = ({ config, searchExpression: searchExpressionExternal, initialSearchExpression, onSearchExpressionChange, onConfirmUnknownOption, }) => { const [searchExpression, setSearchExpression] = React.useState(() => { if (searchExpressionExternal) { return searchExpressionExternal; } if (initialSearchExpression) { return initialSearchExpression; } return []; }); const onSearchExpressionChangeLatestRef = (0, useLatestRef_1.useLatestRef)(onSearchExpressionChange); (0, react_use_1.useUpdateEffect)(() => { if (searchExpression.every((term) => term.searchValue !== undefined)) { onSearchExpressionChangeLatestRef.current(searchExpression); (0, FlipperLib_1.getFlipperLib)().logger.track('usage', 'power-search:search-expression-finalize'); } }, [searchExpression, onSearchExpressionChangeLatestRef]); React.useEffect(() => { if (searchExpressionExternal) { setSearchExpression(searchExpressionExternal); } }, [searchExpressionExternal]); const options = React.useMemo(() => { const groupedOptions = []; for (const field of Object.values(config.fields)) { const group = { label: field.label, options: [], value: field.key, }; for (const operator of Object.values(field.operators)) { const option = { label: `${field.label} ${operator.label}`, value: `${field.key}${OPTION_KEY_DELIMITER}${operator.key}`, }; group.options.push(option); } groupedOptions.push(group); } return groupedOptions; }, [config.fields]); const searchTermFinderRef = React.useRef(null); return (React.createElement(PowerSearchContainer_1.PowerSearchContainer, null, React.createElement(icons_1.SearchOutlined, { style: { margin: theme_1.theme.space.tiny, color: theme_1.theme.textColorSecondary, } }), searchExpression.map((searchTerm, i) => { return (React.createElement(PowerSearchTerm_1.PowerSearchTerm, { key: JSON.stringify(searchTerm), searchTerm: searchTerm, onCancel: () => { setSearchExpression((prevSearchExpression) => { if (prevSearchExpression[i]) { return [ ...prevSearchExpression.slice(0, i), ...prevSearchExpression.slice(i + 1), ]; } return prevSearchExpression; }); }, onFinalize: (finalSearchTerm) => { setSearchExpression((prevSearchExpression) => { return [ ...prevSearchExpression.slice(0, i), finalSearchTerm, ...prevSearchExpression.slice(i + 1), ]; }); // setTimeout allows antd to clear the search input (default behavior when a predefined option is selected) and prevents onChange from firing twice // Without it, when you enter a value in the enum_set term to filter available options, and then select on the filtered optiong, onChange fires twice. // First, with the selected option. Second, with the search value that you used for filtering. setTimeout(() => { searchTermFinderRef.current?.focus(); }); } })); }), React.createElement(PowerSearchTermFinder_1.PowerSearchTermFinder, { ref: searchTermFinderRef, options: options, onSelect: (selectedOption) => { const [fieldKey, operatorKey] = selectedOption.value.split(OPTION_KEY_DELIMITER); const fieldConfig = config.fields[fieldKey]; const operatorConfig = fieldConfig.operators[operatorKey]; setSearchExpression((prevSearchExpression) => [ ...prevSearchExpression, { field: fieldConfig, operator: operatorConfig, searchValue: operatorConfig.valueType === 'NO_VALUE' ? null : undefined, }, ]); }, onBackspacePressWhileEmpty: () => { setSearchExpression((prevSearchExpression) => { return prevSearchExpression.slice(0, prevSearchExpression.length - 1); }); }, onConfirmUnknownOption: onConfirmUnknownOption ? (searchString) => { const searchExpressionTerm = onConfirmUnknownOption(searchString); if (searchExpressionTerm) { setSearchExpression((prevSearchExpression) => [ ...prevSearchExpression, searchExpressionTerm, ]); } } : undefined }))); }; exports.PowerSearch = PowerSearch; //# sourceMappingURL=index.js.map