Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- force children to get displayed as inline content
- `<StringPreviewContentBlobToggler />`
- `useOnly` property: specify if only parts of the content should be used for the shortened preview, this property replaces `firstNonEmptyLineOnly`
- `<ActivityControlWidget />`
- extend `activityActions` parameter by `notification` property in order to display a notification in an overlay pointing at the activity button.

### Fixed

Expand Down Expand Up @@ -45,6 +47,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

This is a major release, and it might be not compatible with your current usage of our library. Please read about the necessary changes in the section about how to migrate.

### Added

- `<ActivityControlWidget />`
- Add parameter `active` to activity control action to set the `active` state of its button.

### Changed

- `<MultiSelect />`:
- Change default filter predicate to match multi-word queries.

### Migration from v24 to v25

- remove deprecated components, properties and imports from your project, if the info cannot be found here then it was already mentioned in **Deprecated** sections of the past changelogs
Expand Down
82 changes: 54 additions & 28 deletions src/cmem/ActivityControl/ActivityControlWidget.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import React from "react";

import { ValidIconName } from "../../components/Icon/canonicalIconNames";
import { IconProps } from "../../components/Icon/Icon";
import { TestIconProps } from "../../components/Icon/TestIcon";
import { TestableComponent } from "../../components/interfaces";
import { ProgressBarProps } from "../../components/ProgressBar/ProgressBar";
import { SpinnerProps } from "../../components/Spinner/Spinner";
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
import {ValidIconName} from "../../components/Icon/canonicalIconNames";
import {IconProps} from "../../components/Icon/Icon";
import {TestIconProps} from "../../components/Icon/TestIcon";
import {TestableComponent} from "../../components/interfaces";
import {ProgressBarProps} from "../../components/ProgressBar/ProgressBar";
import {SpinnerProps} from "../../components/Spinner/Spinner";
import {CLASSPREFIX as eccgui} from "../../configuration/constants";
import {
Card,
ContextMenu,
ContextOverlay,
IconButton,
MenuItem,
Notification,
NotificationProps,
OverflowText,
OverviewItem,
OverviewItemActions,
Expand Down Expand Up @@ -97,14 +100,24 @@ interface IActivityContextMenu extends TestableComponent {
export interface ActivityControlWidgetAction extends TestableComponent {
// The action that should be triggered
action: () => void;
// The tooltip that should be shown over the action icon
// The tooltip that should be shown over the action icon on hover
tooltip?: string;
// The icon of the action button
icon: ValidIconName | React.ReactElement<TestIconProps>;
// Action is currently disabled (but shown)
disabled?: boolean;
// Warning state
hasStateWarning?: boolean;
// Active state
active?: boolean
/** A notification that is shown in an overlay pointing at the activity action button. */
notification?: {
message: string
onClose: () => void
intent?: NotificationProps["intent"]
// Timeout in ms before notification is closed. Default: none
timeout?: number
}
}

interface IActivityMenuAction extends ActivityControlWidgetAction {
Expand Down Expand Up @@ -210,26 +223,39 @@ export function ActivityControlWidget(props: ActivityControlWidgetProps) {
>
{activityActions &&
activityActions.map((action, idx) => {
return (
<IconButton
key={
typeof action.icon === "string"
? action.icon
: action["data-test-id"] ?? action["data-testid"] ?? idx
}
data-test-id={action["data-test-id"]}
data-testid={action["data-testid"]}
name={action.icon}
text={action.tooltip}
onClick={action.action}
disabled={action.disabled}
intent={action.hasStateWarning ? "warning" : undefined}
tooltipProps={{
hoverOpenDelay: 200,
placement: "bottom",
}}
/>
);
const ActionButton = () => <IconButton
key={
typeof action.icon === "string"
? action.icon
: action["data-test-id"] ?? action["data-testid"] ?? idx
}
data-test-id={action["data-test-id"]}
data-testid={action["data-testid"]}
name={action.icon}
text={action.tooltip}
onClick={action.action}
disabled={action.disabled}
intent={action.hasStateWarning ? "warning" : undefined}
tooltipProps={{
hoverOpenDelay: 200,
placement: "bottom"
}}
active={action.active}
/>
return action.notification ?
<ContextOverlay
content={<Notification
message={action.notification.message}
intent={action.notification.intent ?? "neutral"}
onDismiss={action.notification.onClose}
timeout={action.notification.timeout}
/>}
defaultIsOpen={true}
onClose={action.notification.onClose}
>
<ActionButton/>
</ContextOverlay> :
<ActionButton/>
})}
{additionalActions}
{activityContextMenu && activityContextMenu.menuItems.length > 0 && (
Expand Down
15 changes: 12 additions & 3 deletions src/components/MultiSelect/MultiSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ import { removeExtraSpaces } from "../../common/utils/stringUtils";
import { CLASSPREFIX as eccgui } from "../../configuration/constants";
import { TestableComponent } from "../interfaces";

import { ContextOverlayProps, Highlighter, IconButton, MenuItem, OverflowText, Spinner } from "./../../index";
import {
ContextOverlayProps,
Highlighter,
highlighterUtils,
IconButton,
MenuItem,
OverflowText,
Spinner
} from "./../../index";

export interface MultiSuggestFieldSelectionProps<T> {
newlySelected?: T;
Expand Down Expand Up @@ -53,7 +61,7 @@ interface MultiSuggestFieldCommonProps<T>
/**
* prop to listen for query changes, when text is entered in the multi-select input
*/
runOnQueryChange?: (query: string) => Promise<T[] | undefined>;
runOnQueryChange?: (query: string) => Promise<T[] | undefined> | (T[] | undefined);
/**
* Whether the component should take up the full width of its container.
* This overrides `tagInputProps.fill`.
Expand Down Expand Up @@ -265,7 +273,8 @@ export function MultiSuggestField<T>({
};

const defaultFilterPredicate = (item: T, query: string) => {
return itemLabel(item).toLowerCase().includes(query);
const searchWords = highlighterUtils.extractSearchWords(query, true)
return highlighterUtils.matchesAllWords(itemLabel(item).toLowerCase(), searchWords)
};

/**
Expand Down