Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
CopyPropertyTextContextMenuItem,
IModelAppUserPreferencesStorage,
RemoveFavoritePropertyContextMenuItem,
ShowHideNullValuesSettingsMenuItem,
ShowHideEmptyValuesSettingsMenuItem,
} from "@itwin/property-grid-react";
import type { IModelConnection } from "@itwin/core-frontend";
// __PUBLISH_EXTRACT_END__
Expand Down Expand Up @@ -78,10 +78,10 @@ describe("Property grid", () => {
// the list populates the settings menu
settingsMenuItems: [
// allows hiding properties without values
(props) => <ShowHideNullValuesSettingsMenuItem {...props} persist={true} />,
(props) => <ShowHideEmptyValuesSettingsMenuItem {...props} persist={true} />,
],

// supply an optional custom storage for user preferences, e.g. the show/hide null values used above
// supply an optional custom storage for user preferences, e.g. the show/hide empty values used above
preferencesStorage: new IModelAppUserPreferencesStorage("my-favorites-namespace"),

// supply the global selection storage that the widget will use to listen to selection
Expand Down
4 changes: 2 additions & 2 deletions apps/test-viewer/src/UiProvidersConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
createPropertyGrid,
PropertyGridManager,
RemoveFavoritePropertyContextMenuItem,
ShowHideNullValuesSettingsMenuItem,
ShowHideEmptyValuesSettingsMenuItem,
} from "@itwin/property-grid-react";
import { REPORTS_CONFIG_BASE_URL, ReportsConfigProvider, ReportsConfigWidget } from "@itwin/reports-config-widget-react";
import {
Expand Down Expand Up @@ -225,7 +225,7 @@ const configuredUiItems = new Map<string, UiItem>([
(props) => <CopyPropertyTextContextMenuItem {...props} />,
(props) => <CustomizeFormatPropertyContextMenuItem {...props} />,
],
settingsMenuItems: [(props) => <ShowHideNullValuesSettingsMenuItem {...props} persist={true} />],
settingsMenuItems: [(props) => <ShowHideEmptyValuesSettingsMenuItem {...props} persist={true} />],
onPerformanceMeasured: (feature, elapsedTime) => {
console.log(`PropertyGrid [${feature}] took ${elapsedTime} ms`);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Added `ShowHideEmptyValuesSettingsMenuItem` and `EmptyValuesSettingContext` whose names match the rendered `Show/Hide Empty Values` setting and deprecated `ShowHideNullValuesSettingsMenuItem` and `NullValueSettingContext` in favor of them. Also fixed the setting incorrectly hiding boolean and merged properties.",
"packageName": "@itwin/property-grid-react",
"email": "AzureDevOps@users.noreply.github.com",
"dependentChangeType": "patch"
}
1 change: 0 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
"requeries",
"rpcinterface",
"selectables",
"SHOWNULL",
"sublabel",
"txns",
"typemoq",
Expand Down
8 changes: 4 additions & 4 deletions packages/itwin/property-grid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import {
CopyPropertyTextContextMenuItem,
IModelAppUserPreferencesStorage,
RemoveFavoritePropertyContextMenuItem,
ShowHideNullValuesSettingsMenuItem,
ShowHideEmptyValuesSettingsMenuItem,
} from "@itwin/property-grid-react";
import type { IModelConnection } from "@itwin/core-frontend";

Expand Down Expand Up @@ -81,10 +81,10 @@ UiItemsManager.register({
// the list populates the settings menu
settingsMenuItems: [
// allows hiding properties without values
(props) => <ShowHideNullValuesSettingsMenuItem {...props} persist={true} />,
(props) => <ShowHideEmptyValuesSettingsMenuItem {...props} persist={true} />,
],

// supply an optional custom storage for user preferences, e.g. the show/hide null values used above
// supply an optional custom storage for user preferences, e.g. the show/hide empty values used above
preferencesStorage: new IModelAppUserPreferencesStorage("my-favorites-namespace"),

// supply the global selection storage that the widget will use to listen to selection
Expand Down Expand Up @@ -225,7 +225,7 @@ The entry point is only rendered if there's at least one settings menu item prov

### Hiding empty values

The package delivers `ShowHideNullValuesSettingsMenuItem` that allows users to hide / show properties that don't have values:
The package delivers `ShowHideEmptyValuesSettingsMenuItem` that allows users to hide / show properties that don't have values:

| Empty values displayed | Empty values hidden |
| ----------------------------------------------------------------- | ------------------------------------------------------------- |
Expand Down
17 changes: 13 additions & 4 deletions packages/itwin/property-grid/api/property-grid-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export interface DefaultContextMenuItemProps extends ContextMenuItemProps {
onSelect?: (defaultAction: () => Promise<void>) => Promise<void>;
}

// @public
export function EmptyValuesSettingContext(input: PropsWithChildren<object>): JSX_2.Element;

// @public
export interface FavoritePropertiesContextMenuItemProps extends DefaultContextMenuItemProps {
scope?: FavoritePropertiesScope;
Expand Down Expand Up @@ -105,8 +108,8 @@ export type MultiElementPropertyGridProps = OmitOverUnion<PropertyGridProps, "he
getParentInstanceKey?: (key: InstanceKey) => Promise<InstanceKey | undefined>;
};

// @public
export function NullValueSettingContext(input: PropsWithChildren<object>): JSX_2.Element;
// @public @deprecated
export const NullValueSettingContext: typeof EmptyValuesSettingContext;

// @public
export type PerformanceTrackedFeatures = "properties-load" | "elements-list-load";
Expand Down Expand Up @@ -244,13 +247,19 @@ export interface SettingsMenuProps {
}

// @public
export function ShowHideNullValuesSettingsMenuItem(input: ShowHideNullValuesSettingsMenuItemProps): JSX_2.Element;
export function ShowHideEmptyValuesSettingsMenuItem(input: ShowHideEmptyValuesSettingsMenuItemProps): JSX_2.Element;

// @public
export interface ShowHideNullValuesSettingsMenuItemProps extends SettingsMenuItemProps {
export interface ShowHideEmptyValuesSettingsMenuItemProps extends SettingsMenuItemProps {
persist?: boolean;
}

// @public @deprecated
export const ShowHideNullValuesSettingsMenuItem: typeof ShowHideEmptyValuesSettingsMenuItem;

// @public @deprecated
export type ShowHideNullValuesSettingsMenuItemProps = ShowHideEmptyValuesSettingsMenuItemProps;

// @public
export interface SingleElementDataProviderProps extends DataProviderProps {
instanceKey: InstanceKey;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ public;function;CopyPropertyTextContextMenuItem
public;function;createPropertyGrid
public;interface;DataProviderProps
public;interface;DefaultContextMenuItemProps
public;function;EmptyValuesSettingContext
public;interface;FavoritePropertiesContextMenuItemProps
public;type;FilteringPropertyGridProps
public;class;IModelAppUserPreferencesStorage
public;function;MultiElementPropertyGrid
public;type;MultiElementPropertyGridProps
public;function;NullValueSettingContext
public;const;NullValueSettingContext
deprecated;const;NullValueSettingContext
public;type;PerformanceTrackedFeatures
public;interface;PreferencesStorage
public;function;PropertyGrid
Expand All @@ -38,8 +40,12 @@ public;type;PropertyGridWidgetProps
public;function;RemoveFavoritePropertyContextMenuItem
public;interface;SettingsMenuItemProps
public;interface;SettingsMenuProps
public;function;ShowHideNullValuesSettingsMenuItem
public;interface;ShowHideNullValuesSettingsMenuItemProps
public;function;ShowHideEmptyValuesSettingsMenuItem
public;interface;ShowHideEmptyValuesSettingsMenuItemProps
public;const;ShowHideNullValuesSettingsMenuItem
deprecated;const;ShowHideNullValuesSettingsMenuItem
public;type;ShowHideNullValuesSettingsMenuItemProps
deprecated;type;ShowHideNullValuesSettingsMenuItemProps
public;interface;SingleElementDataProviderProps
public;function;SingleElementPropertyGrid
public;type;SingleElementPropertyGridProps
Expand Down
10 changes: 9 additions & 1 deletion packages/itwin/property-grid/src/property-grid-react.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,20 @@ export {
SettingsMenuProps,
PropertyGridSettingsMenuItemProps,
PropertyGridSettingsMenuItem,
ShowHideEmptyValuesSettingsMenuItemProps,
ShowHideEmptyValuesSettingsMenuItem,
// eslint-disable-next-line @typescript-eslint/no-deprecated
ShowHideNullValuesSettingsMenuItemProps,
// eslint-disable-next-line @typescript-eslint/no-deprecated
ShowHideNullValuesSettingsMenuItem,
} from "./property-grid-react/components/SettingsDropdownMenu.js";

export { DataProviderProps } from "./property-grid-react/hooks/UseDataProvider.js";
export { NullValueSettingContext } from "./property-grid-react/hooks/UseNullValuesSetting.js";
export {
EmptyValuesSettingContext,
// eslint-disable-next-line @typescript-eslint/no-deprecated
NullValueSettingContext,
} from "./property-grid-react/hooks/UseEmptyValuesSetting.js";
export { TelemetryContextProvider, PerformanceTrackedFeatures } from "./property-grid-react/hooks/UseTelemetryContext.js";
export * from "./property-grid-react/hooks/UsePropertyGridTransientState.js";
export {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,13 @@ export class NonEmptyValuesPropertyDataFilterer extends PropertyRecordDataFilter
};
}

// merged primitive values are not empty (the value differs between instances), so they should always match the filter.
// empty string primitive values are considered empty, but `false`/`0` are valid non-empty values.
const hasValue = node.isMerged || (node.value.value !== undefined && node.value.value !== "");
return {
filteredTypes: [FilteredType.Value],
matchesFilter: !!node.value.displayValue,
matchesCount: node.value.displayValue ? 1 : 0,
matchesFilter: hasValue,
matchesCount: hasValue ? 1 : 0,
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import classnames from "classnames";
import { useEffect, useState } from "react";
import { SvgArrowDown, SvgArrowUp, SvgPropertiesList } from "@itwin/itwinui-icons-react";
import { IconButton } from "@itwin/itwinui-react";
import { EmptyValuesSettingContext } from "../hooks/UseEmptyValuesSetting.js";
import { useInstanceSelection } from "../hooks/UseInstanceSelection.js";
import { NullValueSettingContext } from "../hooks/UseNullValuesSetting.js";
import { useTelemetryContext } from "../hooks/UseTelemetryContext.js";
import { useSelectionHandler } from "../hooks/UseUnifiedSelectionHandler.js";
import { PropertyGridManager } from "../PropertyGridManager.js";
Expand Down Expand Up @@ -127,7 +127,7 @@ export function MultiElementPropertyGrid({ ancestorsNavigationControls, getParen
return (
<div className="property-grid-react-transition-container">
<div className="property-grid-react-transition-container-inner">
<NullValueSettingContext>
<EmptyValuesSettingContext>
{items.map((component, idx) => (
<div
key={component.key}
Expand All @@ -140,7 +140,7 @@ export function MultiElementPropertyGrid({ ancestorsNavigationControls, getParen
{component}
</div>
))}
</NullValueSettingContext>
</EmptyValuesSettingContext>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import {
import { Text } from "@itwin/itwinui-react";
import { useActionButtons } from "../hooks/UseActionButtons.js";
import { useContextMenu } from "../hooks/UseContextMenu.js";
import { useEmptyValuesSettingContext } from "../hooks/UseEmptyValuesSetting.js";
import { useLoadedInstanceInfo } from "../hooks/UseInstanceInfo.js";
import { useNullValueSettingContext } from "../hooks/UseNullValuesSetting.js";
import { useResizeObserver } from "../hooks/UseResizeObserver.js";
import { useTelemetryContext } from "../hooks/UseTelemetryContext.js";
import { FilteringPropertyGrid, NonEmptyValuesPropertyDataFilterer } from "./FilteringPropertyGrid.js";
Expand Down Expand Up @@ -105,9 +105,9 @@ export function PropertyGridContent({
});

const [filterText, setFilterText] = useState<string>("");
const { showNullValues } = useNullValueSettingContext();
const { showEmptyValues } = useEmptyValuesSettingContext();
const { onFeatureUsed } = useTelemetryContext();
const filterer = useFilterer({ showNullValues, filterText });
const filterer = useFilterer({ showEmptyValues, filterText });
const { ref, height, width } = useResizeObserver();

const reportFiltering = useDebounced(() => onFeatureUsed("filter-properties"), 1000);
Expand Down Expand Up @@ -186,11 +186,11 @@ function PropertyGridHeader({ item, controls, settingsProps, onBackButtonClick,
}

interface UseFiltererProps {
showNullValues: boolean;
showEmptyValues: boolean;
filterText: string;
}

function useFilterer({ showNullValues, filterText }: UseFiltererProps) {
function useFilterer({ showEmptyValues, filterText }: UseFiltererProps) {
const [defaultFilterers] = useState(() => ({
nonEmpty: new NonEmptyValuesPropertyDataFilterer(),
}));
Expand All @@ -202,12 +202,12 @@ function useFilterer({ showNullValues, filterText }: UseFiltererProps) {
const valueAndRecordFilterer = new CompositePropertyDataFilterer(valueFilterer, CompositeFilterType.Or, labelFilterer);
const textFilterer = new CompositePropertyDataFilterer(valueAndRecordFilterer, CompositeFilterType.Or, categoryFilterer);

if (!showNullValues) {
if (!showEmptyValues) {
return new CompositePropertyDataFilterer(textFilterer, CompositeFilterType.And, defaultFilterers.nonEmpty);
}

return textFilterer;
}, [defaultFilterers.nonEmpty, filterText, showNullValues]);
}, [defaultFilterers.nonEmpty, filterText, showEmptyValues]);

return compositeFilterer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { Fragment } from "react";
import { SvgMoreVertical } from "@itwin/itwinui-icons-react";
import { DropdownMenu, IconButton, MenuItem } from "@itwin/itwinui-react";
import { useNullValueSettingContext } from "../hooks/UseNullValuesSetting.js";
import { useEmptyValuesSettingContext } from "../hooks/UseEmptyValuesSetting.js";
import { PropertyGridManager } from "../PropertyGridManager.js";

import type { PropsWithChildren, ReactNode } from "react";
Expand Down Expand Up @@ -58,10 +58,10 @@ export function PropertyGridSettingsMenuItem({ id, onClick, title, children }: P
}

/**
* Props for `ShowHideNullValuesSettingsMenuItem`.
* Props for `ShowHideEmptyValuesSettingsMenuItem`.
* @public
*/
export interface ShowHideNullValuesSettingsMenuItemProps extends SettingsMenuItemProps {
export interface ShowHideEmptyValuesSettingsMenuItemProps extends SettingsMenuItemProps {
/** Specifies whether setting value should be persisted on change. */
persist?: boolean;
}
Expand All @@ -70,11 +70,11 @@ export interface ShowHideNullValuesSettingsMenuItemProps extends SettingsMenuIte
* Renders `Show/Hide Empty Values` setting.
* @public
*/
export function ShowHideNullValuesSettingsMenuItem({ close, persist }: ShowHideNullValuesSettingsMenuItemProps) {
const { showNullValues, setShowNullValues } = useNullValueSettingContext();
export function ShowHideEmptyValuesSettingsMenuItem({ close, persist }: ShowHideEmptyValuesSettingsMenuItemProps) {
const { showEmptyValues, setShowEmptyValues } = useEmptyValuesSettingContext();

const label = showNullValues ? PropertyGridManager.translate("settings.hide-null.label") : PropertyGridManager.translate("settings.show-null.label");
const description = showNullValues
const label = showEmptyValues ? PropertyGridManager.translate("settings.hide-null.label") : PropertyGridManager.translate("settings.show-null.label");
const description = showEmptyValues
? PropertyGridManager.translate("settings.hide-null.description")
: PropertyGridManager.translate("settings.show-null.description");

Expand All @@ -83,7 +83,7 @@ export function ShowHideNullValuesSettingsMenuItem({ close, persist }: ShowHideN
id="show-hide-null-values"
title={description}
onClick={() => {
void setShowNullValues(!showNullValues, { persist });
void setShowEmptyValues(!showEmptyValues, { persist });
close();
}}
>
Expand All @@ -92,6 +92,20 @@ export function ShowHideNullValuesSettingsMenuItem({ close, persist }: ShowHideN
);
}

/**
* Props for `ShowHideNullValuesSettingsMenuItem`.
* @deprecated in 1.20. Use `ShowHideEmptyValuesSettingsMenuItemProps` instead.
* @public
*/
export type ShowHideNullValuesSettingsMenuItemProps = ShowHideEmptyValuesSettingsMenuItemProps;

/**
* Renders `Show/Hide Empty Values` setting.
* @deprecated in 1.20. Use `ShowHideEmptyValuesSettingsMenuItem` instead.
* @public
*/
export const ShowHideNullValuesSettingsMenuItem = ShowHideEmptyValuesSettingsMenuItem;

/**
* Props for `SettingsDropdownMenu`.
* @internal
Expand Down
Loading
Loading