flipper-plugin
Version:
Flipper Desktop plugin SDK and components
148 lines • 7.18 kB
JavaScript
/**
* 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
;