diff --git a/packages/libs/coreui/src/components/inputs/SelectTree/SelectTree.tsx b/packages/libs/coreui/src/components/inputs/SelectTree/SelectTree.tsx index 567f82ee28..c39476a488 100644 --- a/packages/libs/coreui/src/components/inputs/SelectTree/SelectTree.tsx +++ b/packages/libs/coreui/src/components/inputs/SelectTree/SelectTree.tsx @@ -16,20 +16,22 @@ export interface SelectTreeProps extends CheckboxTreeProps { } function SelectTree(props: SelectTreeProps) { - const [buttonDisplayContent, setButtonDisplayContent] = useState( - props.currentList && props.currentList.length - ? props.currentList.join(', ') - : props.buttonDisplayContent - ); const { - selectedList, - onSelectionChange, shouldCloseOnSelection, + wrapPopover, + currentList, + selectedList = [], + onSelectionChange, hasPopoverButton = true, instantUpdate = true, - wrapPopover, } = props; + const [buttonDisplayContent, setButtonDisplayContent] = useState( + currentList && currentList.length + ? currentList.join(', ') + : props.buttonDisplayContent + ); + // This local state is updated whenever a checkbox is clicked in the species tree. // When `instantUpdate` is false, pass the final value to `onSelectionChange` when the popover closes. // When it is true we call `onSelectionChange` whenever `localSelectedList` changes @@ -47,8 +49,9 @@ function SelectTree(props: SelectTreeProps) { // live updates to caller when needed useEffect(() => { if (!instantUpdate) return; + if (!onSelectionChange) return; onSelectionChange(localSelectedList); - }, [onSelectionChange, localSelectedList]); + }, [onSelectionChange, localSelectedList, instantUpdate]); function truncatedButtonContent(selectedList: string[]) { return ( @@ -72,48 +75,15 @@ function SelectTree(props: SelectTreeProps) { ? truncatedButtonContent(localSelectedList) : props.buttonDisplayContent ); - if (!instantUpdate) onSelectionChange(localSelectedList); + if (!instantUpdate && onSelectionChange) + onSelectionChange(localSelectedList); }; const checkboxTree = ( ); diff --git a/packages/libs/coreui/src/components/inputs/checkboxes/CheckboxTree/CheckboxTree.tsx b/packages/libs/coreui/src/components/inputs/checkboxes/CheckboxTree/CheckboxTree.tsx index 01c1ca0c05..0f6ebbf09e 100644 --- a/packages/libs/coreui/src/components/inputs/checkboxes/CheckboxTree/CheckboxTree.tsx +++ b/packages/libs/coreui/src/components/inputs/checkboxes/CheckboxTree/CheckboxTree.tsx @@ -162,7 +162,7 @@ export type CheckboxTreeProps = { isSelectable?: boolean; /** List of selected nodes as represented by their ids, defaults to [ ] */ - selectedList: string[]; + selectedList?: string[]; /** * List of filtered nodes as represented by their ids used to determine isLeafVisible node status. @@ -182,7 +182,7 @@ export type CheckboxTreeProps = { /** Takes array of ids, thus encapsulates: selectAll, clearAll, selectDefault, selectCurrent (i.e. reset) */ - onSelectionChange: ChangeHandler; + onSelectionChange?: ChangeHandler; /** List of “current” ids, if omitted (undefined or null), then don’t display link */ currentList?: string[]; @@ -193,7 +193,7 @@ export type CheckboxTreeProps = { //%%%%%%%%%%% Properties associated with search %%%%%%%%%%% /** Indicates whether this is a searchable CBT. If so, then show boxes and respect the optional parameters below, also turn off expansion; default to false */ - isSearchable: boolean; + isSearchable?: boolean; /** Indicates if the search box should have autoFocus set to true */ autoFocusSearchBox?: boolean; @@ -202,7 +202,7 @@ export type CheckboxTreeProps = { showSearchBox?: boolean; /** PlaceHolder text; shown in grey if searchTerm is empty */ - searchBoxPlaceholder: string; + searchBoxPlaceholder?: string; /** Name of icon to show in search box */ searchIconName?: 'search' | 'filter'; @@ -214,13 +214,13 @@ export type CheckboxTreeProps = { searchBoxHelp?: string; /** Current search term; if non-empty, expandability is disabled */ - searchTerm: string; + searchTerm?: string; /** Takes single arg: the new search text. Called when user types into the search box */ - onSearchTermChange: (term: string) => void; + onSearchTermChange?: (term: string) => void; /** Takes (node, searchTerms) and returns boolean. searchTerms is a list of query terms, parsed from the original input string. This function returns a boolean indicating if a node matches search criteria and should be shown */ - searchPredicate: (node: T, terms: string[]) => boolean; + searchPredicate?: (node: T, terms: string[]) => boolean; renderNoResults?: (searchTerm: string, tree: T) => React.ReactNode; @@ -246,6 +246,31 @@ export type CheckboxTreeProps = { customTreeNodeCssSelectors?: object; }; +// Default values. Used across multiple functions in this file. +// Define defaultCheckboxTreeProps as a partial of CheckboxTreeProps + +const defaultCheckboxTreeProps = { + showRoot: false, + expandedList: null, + isSelectable: false, + selectedList: [], + customCheckboxes: {}, + isMultiPick: true, + onSelectionChange: () => { + /* */ + }, + isSearchable: false, + showSearchBox: true, + searchBoxPlaceholder: 'Search...', + searchBoxHelp: '', + searchTerm: '', + onSearchTermChange: () => { + /* */ + }, + searchPredicate: () => true, + linksPosition: LinksPosition.Both, +}; + type TreeLinkHandler = MouseEventHandler; type TreeLinksProps = { @@ -463,7 +488,7 @@ function applyPropsToStatefulTree( isSearchable: CheckboxTreeProps['isSearchable'], isMultiPick: CheckboxTreeProps['isMultiPick'], searchTerm: CheckboxTreeProps['searchTerm'], - selectedList: CheckboxTreeProps['selectedList'], + selectedList: CheckboxTreeProps['selectedList'] = defaultCheckboxTreeProps.selectedList, propsExpandedList: CheckboxTreeProps['expandedList'], isAdditionalFilterApplied: CheckboxTreeProps['isAdditionalFilterApplied'], isLeafVisible: (id: string) => boolean, @@ -589,8 +614,8 @@ function applyPropsToStatefulTree( */ function isActiveSearch( isAdditionalFilterApplied: CheckboxTreeProps['isAdditionalFilterApplied'], - isSearchable: CheckboxTreeProps['isSearchable'], - searchTerm: CheckboxTreeProps['searchTerm'] + isSearchable: CheckboxTreeProps['isSearchable'] = defaultCheckboxTreeProps.isSearchable, + searchTerm: CheckboxTreeProps['searchTerm'] = defaultCheckboxTreeProps.searchTerm ) { return isSearchable && isFiltered(searchTerm, isAdditionalFilterApplied); } @@ -625,12 +650,12 @@ function isFiltered(searchTerm: string, isAdditionalFilterApplied?: boolean) { */ function createIsLeafVisible( tree: CheckboxTreeProps['tree'], - searchTerm: CheckboxTreeProps['searchTerm'], - searchPredicate: CheckboxTreeProps['searchPredicate'], + searchTerm: CheckboxTreeProps['searchTerm'] = defaultCheckboxTreeProps.searchTerm, + searchPredicate: CheckboxTreeProps['searchPredicate'] = defaultCheckboxTreeProps.searchPredicate, getNodeId: CheckboxTreeProps['getNodeId'], getNodeChildren: CheckboxTreeProps['getNodeChildren'], isAdditionalFilterApplied: CheckboxTreeProps['isAdditionalFilterApplied'], - isSearchable: CheckboxTreeProps['isSearchable'], + isSearchable: CheckboxTreeProps['isSearchable'] = defaultCheckboxTreeProps.isSearchable, filteredList: CheckboxTreeProps['filteredList'] ) { // if not searching, if no additional filters are applied, and if filteredList is undefined, then all nodes are visible @@ -695,32 +720,32 @@ function CheckboxTree(props: CheckboxTreeProps) { tree, getNodeId, getNodeChildren, - searchTerm, - selectedList, + searchTerm = defaultCheckboxTreeProps.searchTerm, + selectedList = defaultCheckboxTreeProps.selectedList, currentList, defaultList, - isSearchable, + isSearchable = defaultCheckboxTreeProps.isSearchable, isAdditionalFilterApplied, name, shouldExpandDescendantsWithOneChild, onExpansionChange, - isSelectable, - isMultiPick, - onSelectionChange, - showRoot, + onSelectionChange = defaultCheckboxTreeProps.onSelectionChange, + isSelectable = defaultCheckboxTreeProps.isSelectable, + isMultiPick = defaultCheckboxTreeProps.isMultiPick, + showRoot = defaultCheckboxTreeProps.showRoot, additionalActions, - linksPosition = LinksPosition.Both, - showSearchBox, + linksPosition = defaultCheckboxTreeProps.linksPosition, + showSearchBox = defaultCheckboxTreeProps.showSearchBox, autoFocusSearchBox, - onSearchTermChange, - searchBoxPlaceholder, + onSearchTermChange = defaultCheckboxTreeProps.onSearchTermChange, + searchBoxPlaceholder = defaultCheckboxTreeProps.searchBoxPlaceholder, searchIconName, searchIconPosition, - searchBoxHelp, + searchBoxHelp = defaultCheckboxTreeProps.searchBoxHelp, additionalFilters, wrapTreeSection, shouldExpandOnClick = true, - customCheckboxes, + customCheckboxes = defaultCheckboxTreeProps.customCheckboxes, renderNoResults, styleOverrides = {}, customTreeNodeCssSelectors = {}, @@ -764,7 +789,7 @@ function CheckboxTree(props: CheckboxTreeProps) { * Creates a function that will handle selection-related tree link clicks */ function createSelector(listFetcher: ListFetcher) { - return createLinkHandler(listFetcher, props.onSelectionChange); + return createLinkHandler(listFetcher, onSelectionChange); } // define event handlers related to expansion @@ -1071,29 +1096,6 @@ function defaultRenderNoResults() { ); } -const defaultProps = { - showRoot: false, - expandedList: null, - isSelectable: false, - selectedList: [], - customCheckboxes: {}, - isMultiPick: true, - onSelectionChange: () => { - /* */ - }, - isSearchable: false, - showSearchBox: true, - searchBoxPlaceholder: 'Search...', - searchBoxHelp: '', - searchTerm: '', - onSearchTermChange: () => { - /* */ - }, - searchPredicate: () => true, - linksPosition: LinksPosition.Both, -}; - -CheckboxTree.defaultProps = defaultProps; CheckboxTree.LinkPlacement = LinksPosition; export default CheckboxTree; diff --git a/packages/libs/wdk-client/src/Components/AttributeFilter/FieldFilter.jsx b/packages/libs/wdk-client/src/Components/AttributeFilter/FieldFilter.jsx index 419eb09954..36a0b7e514 100644 --- a/packages/libs/wdk-client/src/Components/AttributeFilter/FieldFilter.jsx +++ b/packages/libs/wdk-client/src/Components/AttributeFilter/FieldFilter.jsx @@ -12,12 +12,14 @@ const cx = makeClassNameHelper('field-detail'); * Main interactive filtering interface for a particular field. */ function FieldFilter(props) { + const { displayName = 'Items' } = props; + let className = cx('', props.hideFieldPanel && 'fullWidth'); return (
{!props.activeField ? ( - + ) : (

@@ -48,9 +50,9 @@ function FieldFilter(props) { props.activeFieldState.summary == null && props.activeFieldState.leafSummaries == null) || props.dataCount == null ? null : isMulti(props.activeField) ? ( - + ) : ( - + )} )} @@ -95,8 +97,4 @@ FieldFilter.propTypes = { selectByDefault: PropTypes.bool.isRequired, }; -FieldFilter.defaultProps = { - displayName: 'Items', -}; - export default FieldFilter; diff --git a/packages/libs/wdk-client/src/Components/AttributeFilter/ServerSideAttributeFilter.jsx b/packages/libs/wdk-client/src/Components/AttributeFilter/ServerSideAttributeFilter.jsx index 044bf7d451..df70a6d538 100644 --- a/packages/libs/wdk-client/src/Components/AttributeFilter/ServerSideAttributeFilter.jsx +++ b/packages/libs/wdk-client/src/Components/AttributeFilter/ServerSideAttributeFilter.jsx @@ -10,7 +10,16 @@ import FieldFilter from '../../Components/AttributeFilter/FieldFilter'; * Filtering UI for server-side filtering. */ function ServerSideAttributeFilter(props) { - var { displayName, fieldTree, hideFilterPanel, hideFieldPanel } = props; + const { + fieldTree, + displayName = 'Items', + hideFilterPanel = false, + hideFieldPanel = false, + hideGlobalCounts = false, + selectByDefault = false, + histogramScaleYAxisDefault = true, + histogramTruncateYAxisDefault = false, + } = props; if (fieldTree == null) { return

Data is not available for {displayName}.

; @@ -18,7 +27,9 @@ function ServerSideAttributeFilter(props) { return (
- {hideFilterPanel || } + {hideFilterPanel || ( + + )} {/* Main selection UI */}
@@ -79,16 +90,6 @@ ServerSideAttributeFilter.propTypes = { onRangeScaleChange: PropTypes.func.isRequired, }; -ServerSideAttributeFilter.defaultProps = { - displayName: 'Items', - hideFilterPanel: false, - hideFieldPanel: false, - hideGlobalCounts: false, - selectByDefault: false, - histogramScaleYAxisDefault: true, - histogramTruncateYAxisDefault: false, -}; - export default wrappable(ServerSideAttributeFilter); export function withOptions(options) { diff --git a/packages/libs/wdk-client/src/Views/Records/RecordActionLink.jsx b/packages/libs/wdk-client/src/Views/Records/RecordActionLink.jsx index 5dc5103bee..67ab169dbc 100644 --- a/packages/libs/wdk-client/src/Views/Records/RecordActionLink.jsx +++ b/packages/libs/wdk-client/src/Views/Records/RecordActionLink.jsx @@ -4,17 +4,26 @@ import Link from '../../Components/Link/Link'; import { wrappable } from '../../Utils/ComponentUtils'; let RecordActionLink = (props) => { - let className = 'wdk-RecordActionLink ' + props.className; - let LinkComponent = props.external ? 'a' : Link; + const { + onClick, + href = '#', + external = false, + label = 'Record action', + iconClassName = 'fa fa-bolt', + showLabel = true, + } = props; + + let className = 'wdk-RecordActionLink ' + (props.className || ''); + let LinkComponent = external ? 'a' : Link; let linkProps = { - [props.external ? 'href' : 'to']: props.href, - title: props.label, + [external ? 'href' : 'to']: href, + title: label, className: className, - onClick: props.onClick, + onClick: onClick, }; return ( - {props.showLabel ? props.label : ''} + {showLabel ? label : ''} ); }; @@ -30,13 +39,4 @@ RecordActionLink.propTypes = { showLabel: PropTypes.bool, }; -RecordActionLink.defaultProps = { - href: '#', - external: false, - className: '', - label: 'Record action', - iconClassName: 'fa fa-bolt', - showLabel: true, -}; - export default wrappable(RecordActionLink); diff --git a/packages/libs/web-common/src/components/records/Sequence.tsx b/packages/libs/web-common/src/components/records/Sequence.tsx index 13a83a30d9..c4d0900e76 100644 --- a/packages/libs/web-common/src/components/records/Sequence.tsx +++ b/packages/libs/web-common/src/components/records/Sequence.tsx @@ -138,10 +138,6 @@ Sequence.propTypes = { ), }; -Sequence.defaultProps = { - highlightRegions: [], -}; - function handleCopy(event: React.ClipboardEvent) { const string = window.getSelection()?.toString() ?? ''; //const selection = makeSequenceLines(string).join('\n');