This is an automated email from the ASF dual-hosted git repository. andytaylor pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/activemq-artemis-console.git
commit 4153946e32f26a6c44c60e3d2d9e47984833c259 Author: GChuf <[email protected]> AuthorDate: Sat Aug 30 12:57:05 2025 +0200 ARTEMIS-5641: Separate filters and search from the ArtemisTable component --- .../src/table/ArtemisFilters.tsx | 111 ++++++++++++++++ .../src/table/ArtemisTable.tsx | 147 ++++----------------- 2 files changed, 136 insertions(+), 122 deletions(-) diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisFilters.tsx b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisFilters.tsx new file mode 100644 index 0000000..3b65452 --- /dev/null +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisFilters.tsx @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useState } from 'react'; +import { Button, Select, SelectList, SelectOption, MenuToggleElement, MenuToggle, SearchInput, ToolbarItem } from '@patternfly/react-core'; + +export type ArtemisFiltersProps = { + columns: { id: string; name: string; visible: boolean }[]; + operationOptions: { id: string; name: string }[]; + initialFilter: { column: string; operation: string; input: string }; + onApplyFilter: (filter: { column: string; operation: string; input: string }) => void; +}; + +export const ArtemisFilters: React.FC<ArtemisFiltersProps> = ({ columns, operationOptions, initialFilter, onApplyFilter }) => { + const [filterColumn, setFilterColumn] = useState( + columns.find(c => c.id === initialFilter.column)?.name + ); + const [filterOperation, setFilterOperation] = useState( + operationOptions.find(o => o.id === initialFilter.operation)?.name + ); + const [inputValue, setInputValue] = useState(initialFilter.input); + const [columnOpen, setColumnOpen] = useState(false); + const [operationOpen, setOperationOpen] = useState(false); + + const applyFilter = () => { + const operation = operationOptions.find(operation => operation.name === filterOperation); + const column = columns.find(column => column.name === filterColumn); + if (operation && column) { + onApplyFilter({ column: column.id, operation: operation.id, input: inputValue }); + } + } + + return ( + <> + <ToolbarItem variant="search-filter" key='column-id-select'> + <Select + toggle={(toggleRef: React.Ref<MenuToggleElement>) => ( + <MenuToggle isFullWidth role='menu' ref={toggleRef} onClick={() => setColumnOpen(prev => !prev)}> + {filterColumn} + </MenuToggle> + )} + aria-label="Select Input" + isOpen={columnOpen} + onOpenChange={setColumnOpen} + onSelect={(_e, selection) => { setFilterColumn(selection as string); setColumnOpen(false); }} + selected={filterColumn} + > + <SelectList> + {columns.filter(c => c.visible).map(column => ( + <SelectOption key={column.id} value={column.name}>{column.name}</SelectOption> + ))} + </SelectList> + </Select> + </ToolbarItem> + + <ToolbarItem variant="search-filter" key="filter-type"> + <Select + toggle={(toggleRef: React.Ref<MenuToggleElement>) => ( + <MenuToggle isFullWidth role='menu' ref={toggleRef} onClick={() => setOperationOpen(prev => !prev)}> + {filterOperation} + </MenuToggle> + )} + aria-label="Select Input" + isOpen={operationOpen} + onOpenChange={setOperationOpen} + onSelect={(_e, selection) => { setFilterOperation(selection as string); setOperationOpen(false); }} + selected={filterOperation} + > + <SelectList> + {operationOptions.map(operation => ( + <SelectOption key={operation.id} value={operation.name}>{operation.name}</SelectOption> + ))} + </SelectList> + </Select> + </ToolbarItem> + + <ToolbarItem variant="search-filter" key="search=text"> + <SearchInput + aria-label="Search Text" + value={inputValue} + onChange={(_event, value) => setInputValue(value)} + onClear={() => { + setInputValue(''); + applyFilter(); + }} + onKeyDown={(e) => { + if (e.key === 'Enter') { + applyFilter(); + } + }} + /> + </ToolbarItem> + + <Button onClick={applyFilter}>Search</Button> + </> + ); +}; \ No newline at end of file diff --git a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisTable.tsx b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisTable.tsx index 6bd0e7f..616a21e 100644 --- a/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisTable.tsx +++ b/artemis-console-extension/artemis-extension/packages/artemis-console-plugin/src/table/ArtemisTable.tsx @@ -31,13 +31,7 @@ import { Pagination, PaginationVariant, Text, - TextContent, - Select, - SelectOption, - SearchInput, - MenuToggleElement, - MenuToggle, - SelectList + TextContent } from '@patternfly/react-core'; import { SortAmountDownIcon } from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon'; import { Thead, Tr, Th, Tbody, Td, IAction, ActionsColumn, Table, InnerScrollContainer } from '@patternfly/react-table'; @@ -46,9 +40,12 @@ import { OptionsMenu, OptionsMenuItem, OptionsMenuItemGroup, - OptionsMenuSeparator, OptionsMenuToggle + OptionsMenuSeparator, + OptionsMenuToggle } from '@patternfly/react-core/deprecated' +import { ArtemisFilters } from './ArtemisFilters'; + export type Column = { id: string name: string @@ -126,7 +123,7 @@ const operationOptions = [ if (broker.storageColumnLocation && sessionStorage.getItem(broker.storageColumnLocation + '.filter')) { return JSON.parse(sessionStorage.getItem(broker.storageColumnLocation + '.filter') as string); } - return { + return { column: columns[1].id, operation: operationOptions[0].id, input: '' @@ -135,12 +132,6 @@ const operationOptions = [ const [filter, setFilter] = useState(() => broker.filter !== undefined ? broker.filter : initialFilter()); - const [filterColumnStatusSelected, setFilterColumnStatusSelected] = useState(columns.find(column => filter.column === column.id)?.name); - const [filterColumnOperationSelected, setFilterColumnOperationSelected] = useState(operationOptions.find(operation => operation.id === filter.operation)?.name); - const [inputValue, setInputValue] = useState(filter.input); - const [filterColumnStatusIsExpanded, setFilterColumnStatusIsExpanded] = useState(false); - const [filterColumnOperationIsExpanded, setFilterColumnOperationIsExpanded] = useState(false); - const listData = async () => { const data = await broker.getData(page, perPage, activeSort, filter); setRows(data.data); @@ -153,7 +144,7 @@ const operationOptions = [ setColumns(updatedColumns); setColumnsLoaded(true); } - }, [columns, columnsLoaded]); + }, [columnsLoaded]); useEffect(() => { listData(); @@ -189,10 +180,6 @@ const operationOptions = [ setColumns(updatedColumns); }; - const onSearchTextChange = (newValue: string) => { - setInputValue(newValue); - }; - const updateColumnStatus = (index: number, column: Column) => { const updatedColumns = [...columns]; updatedColumns[index].visible = !columns[index].visible; @@ -208,25 +195,6 @@ const operationOptions = [ sessionStorage.setItem(broker.storageColumnLocation + ".activesort",JSON.stringify(updatedActiveSort)); } - const onFilterColumnStatusSelect = ( - _event?: React.MouseEvent<Element, MouseEvent> | undefined, - selection?: string | number | undefined - ) => { - setFilterColumnStatusSelected(selection as string); - setFilterColumnStatusIsExpanded(false); - }; - - const onFilterColumnOperationSelect = ( - _event?: React.MouseEvent<Element, MouseEvent> | undefined, - selection?: string | number | undefined - ) => { - const operation = operationOptions.find(operation => operation.name === selection); - if (operation) { - setFilterColumnOperationSelected(selection as string); - } - setFilterColumnOperationIsExpanded(false); - }; - const getRowActions = (row: never, rowIndex: number): IAction[] => { if (broker.getRowActions) { return broker.getRowActions(row, rowIndex); @@ -250,19 +218,6 @@ const operationOptions = [ return producer[columnName]; } - const applyFilter = () => { - setPage(1); - const operation = operationOptions.find(operation => operation.name === filterColumnOperationSelected); - const column = columns.find(column => column.name === filterColumnStatusSelected); - if (operation && column) { - var filter = { column: column.id, operation: operation.id, input: inputValue }; - setFilter(filter); - if (broker.storageColumnLocation) { - sessionStorage.setItem(broker.storageColumnLocation + '.filter', JSON.stringify(filter)); - } - } - } - const renderPagination = (variant: PaginationVariant | undefined) => ( <Pagination itemCount={resultsSize} @@ -329,16 +284,16 @@ const operationOptions = [ ); }; - - const toolbarItems = ( + return ( <React.Fragment> + <Toolbar id="toolbar"> <ToolbarContent> <ToolbarItem key='address-sort'> <OptionsMenu id="options-menu-multiple-options-example" menuItems={[ - <OptionsMenuItemGroup key="first group" aria-label="Sort column"> + <OptionsMenuItemGroup key="sort-columns" aria-label="Sort column"> {Object.values(broker.allColumns).filter((element) => element.visible).map((column, columnIndex) => ( <OptionsMenuItem key={column.id} @@ -352,7 +307,7 @@ const operationOptions = [ ))} </OptionsMenuItemGroup>, <OptionsMenuSeparator key="separator" />, - <OptionsMenuItemGroup key="second group" aria-label="Sort direction"> + <OptionsMenuItemGroup key="sort-direction" aria-label="Sort direction"> <OptionsMenuItem onSelect={() => updateActiveSort(activeSort.id, SortDirection.ASCENDING)} isSelected={activeSort.order === SortDirection.ASCENDING} @@ -383,65 +338,20 @@ const operationOptions = [ isGrouped /> </ToolbarItem> - <ToolbarItem variant="search-filter" key='column-id-select'> - <Select - toggle={(toggleRef: React.Ref<MenuToggleElement>) => ( - <MenuToggle isFullWidth role='menu' ref={toggleRef} onClick={() => setFilterColumnStatusIsExpanded(prev => !prev)}> - {filterColumnStatusSelected} - </MenuToggle> - )} - aria-label="Select Input" - onSelect={onFilterColumnStatusSelect} - selected={filterColumnStatusSelected} - isOpen={filterColumnStatusIsExpanded} - onOpenChange={(isOpen: boolean) => setFilterColumnStatusIsExpanded(isOpen)} - > - <SelectList> - {columns.filter((element) => element.visible).map((column, index) => ( - <SelectOption key={column.id} value={column.name}>{column.name}</SelectOption> - ))} - </SelectList> - </Select> - </ToolbarItem> - <ToolbarItem variant="search-filter" key="filter-type"> - <Select - toggle={(toggleRef: React.Ref<MenuToggleElement>) => ( - <MenuToggle isFullWidth role='menu' ref={toggleRef} onClick={() => setFilterColumnOperationIsExpanded(prev => !prev)}> - {filterColumnOperationSelected} - </MenuToggle> - )} - aria-label="Select Input" - onSelect={onFilterColumnOperationSelect} - selected={filterColumnOperationSelected} - isOpen={filterColumnOperationIsExpanded} - onOpenChange={(isOpen: boolean) => setFilterColumnOperationIsExpanded(isOpen)} - > - <SelectList> - {operationOptions.map((column, _index) => ( - <SelectOption key={column.id} value={column.name}>{column.name}</SelectOption> - ))} - </SelectList> - </Select> - </ToolbarItem> - <ToolbarItem variant="search-filter" key="search=text"> - <SearchInput - aria-label="search-text" - onChange={(_event, value) => onSearchTextChange(value)} - value={inputValue} - onClear={() => { - onSearchTextChange(''); - applyFilter(); - }} - onKeyDown={(e) => { - if (e.key === 'Enter') { - applyFilter(); - } - }} - /> - </ToolbarItem> - <ToolbarItem key="search-button"> - <Button onClick={applyFilter} id="table-search-button">Search</Button> - </ToolbarItem> + + <ArtemisFilters + columns={columns} + operationOptions={operationOptions} + initialFilter={filter} + onApplyFilter={(f) => { + setPage(1); + setFilter(f); + if (broker.storageColumnLocation) { + sessionStorage.setItem(broker.storageColumnLocation + '.filter', JSON.stringify(f)); + } + }} + /> + <ToolbarItem key="column-select"> <Button variant='link' onClick={handleModalToggle}>Manage Columns</Button> </ToolbarItem> @@ -453,12 +363,7 @@ const operationOptions = [ } </ToolbarContent> </Toolbar> - </React.Fragment> - ); - return ( - <React.Fragment> - {toolbarItems} <InnerScrollContainer> <Table variant="compact" aria-label="Data Table" id='data-table'> <Thead> @@ -520,5 +425,3 @@ const operationOptions = [ </React.Fragment> ); }; - - --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected] For further information, visit: https://activemq.apache.org/contact
