"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useBulkEditSelect = useBulkEditSelect; var _react = require("react"); var _esQuery = require("@kbn/es-query"); var _map_filters_to_kuery_node = require("../lib/rule_api/map_filters_to_kuery_node"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ var ActionTypes; (function (ActionTypes) { ActionTypes["TOGGLE_SELECT_ALL"] = "TOGGLE_SELECT_ALL"; ActionTypes["TOGGLE_ROW"] = "TOGGLE_ROW"; ActionTypes["SET_SELECTION"] = "SET_SELECTION"; ActionTypes["CLEAR_SELECTION"] = "CLEAR_SELECTION"; })(ActionTypes || (ActionTypes = {})); const initialState = { selectedIds: new Set(), isAllSelected: false }; const reducer = (state, action) => { const { type, payload } = action; switch (type) { case ActionTypes.TOGGLE_SELECT_ALL: return { ...state, isAllSelected: !state.isAllSelected, selectedIds: new Set() }; case ActionTypes.TOGGLE_ROW: { const id = payload; if (state.selectedIds.has(id)) { state.selectedIds.delete(id); } else { state.selectedIds.add(id); } return { ...state, selectedIds: new Set(state.selectedIds) }; } case ActionTypes.SET_SELECTION: { const selectedIds = payload; return { ...state, selectedIds: new Set(selectedIds) }; } case ActionTypes.CLEAR_SELECTION: { return { ...initialState, selectedIds: new Set() }; } default: return state; } }; function useBulkEditSelect(props) { const { totalItemCount = 0, items = [], typesFilter, actionTypesFilter, tagsFilter, ruleExecutionStatusesFilter, ruleLastRunOutcomesFilter, ruleStatusesFilter, searchText } = props; const [state, dispatch] = (0, _react.useReducer)(reducer, { ...initialState, selectedIds: new Set() }); const itemIds = (0, _react.useMemo)(() => { return items.map(item => item.id); }, [items]); const numberOfSelectedItems = (0, _react.useMemo)(() => { const { selectedIds, isAllSelected } = state; if (!totalItemCount) { return 0; } if (isAllSelected) { return totalItemCount - selectedIds.size; } return itemIds.filter(id => selectedIds.has(id)).length; }, [state, itemIds, totalItemCount]); const isPageSelected = (0, _react.useMemo)(() => { const { selectedIds, isAllSelected } = state; if (!items.length) { return false; } return items.every(item => { if (!item.isEditable) { return true; } if (isAllSelected) { return !selectedIds.has(item.id); } return selectedIds.has(item.id); }); }, [state, items]); const isRowSelected = (0, _react.useCallback)(rule => { const { selectedIds, isAllSelected } = state; if (!rule.isEditable) { return false; } if (isAllSelected) { return !selectedIds.has(rule.id); } return selectedIds.has(rule.id); }, [state]); const onSelectRow = (0, _react.useCallback)(rule => { dispatch({ type: ActionTypes.TOGGLE_ROW, payload: rule.id }); }, []); const onSelectAll = (0, _react.useCallback)(() => { dispatch({ type: ActionTypes.TOGGLE_SELECT_ALL, payload: !state.isAllSelected }); }, [state]); const onSelectPage = (0, _react.useCallback)(() => { const { selectedIds, isAllSelected } = state; // Select current page in non-select all mode. Ignore rules that cannot be edited if (!isPageSelected && !isAllSelected) { const idsToSelect = items.filter(item => item.isEditable).map(item => item.id); dispatch({ type: ActionTypes.SET_SELECTION, payload: [...selectedIds, ...idsToSelect] }); } // Unselect current page in non-select all mode. if (isPageSelected && !isAllSelected) { items.forEach(item => selectedIds.delete(item.id)); dispatch({ type: ActionTypes.SET_SELECTION, payload: [...selectedIds] }); } // Select current page in select all mode. Ignore rules that cannot be edited if (!isPageSelected && isAllSelected) { items.forEach(item => { if (item.isEditable) { selectedIds.delete(item.id); } }); dispatch({ type: ActionTypes.SET_SELECTION, payload: [...selectedIds] }); } // Unselect current page in select all mode. if (isPageSelected && isAllSelected) { dispatch({ type: ActionTypes.SET_SELECTION, payload: [...selectedIds, ...itemIds] }); } }, [state, isPageSelected, items, itemIds]); const onClearSelection = (0, _react.useCallback)(() => { dispatch({ type: ActionTypes.CLEAR_SELECTION }); }, []); const getFilterKueryNode = (0, _react.useCallback)(idsToExclude => { const ruleFilterKueryNode = (0, _map_filters_to_kuery_node.mapFiltersToKueryNode)({ typesFilter, actionTypesFilter, tagsFilter, ruleExecutionStatusesFilter, ruleLastRunOutcomesFilter, ruleStatusesFilter, searchText }); if (idsToExclude && idsToExclude.length) { const excludeFilter = (0, _esQuery.fromKueryExpression)(`NOT (${idsToExclude.map(id => `alert.id: "alert:${id}"`).join(' or ')})`); if (ruleFilterKueryNode) { return _esQuery.nodeBuilder.and([ruleFilterKueryNode, excludeFilter]); } return excludeFilter; } return ruleFilterKueryNode; }, [typesFilter, actionTypesFilter, tagsFilter, ruleExecutionStatusesFilter, ruleLastRunOutcomesFilter, ruleStatusesFilter, searchText]); const getFilter = (0, _react.useCallback)(() => { const { selectedIds, isAllSelected } = state; const idsArray = [...selectedIds]; if (isAllSelected) { // Select all but nothing is selected to exclude if (idsArray.length === 0) { return getFilterKueryNode(); } // Select all, exclude certain alerts return getFilterKueryNode(idsArray); } return getFilterKueryNode(); }, [state, getFilterKueryNode]); return (0, _react.useMemo)(() => { return { selectedIds: [...state.selectedIds], isAllSelected: state.isAllSelected, isPageSelected, numberOfSelectedItems, isRowSelected, getFilter, onSelectRow, onSelectAll, onSelectPage, onClearSelection }; }, [state, isPageSelected, numberOfSelectedItems, isRowSelected, getFilter, onSelectRow, onSelectAll, onSelectPage, onClearSelection]); }