Skip to content

Commit

Permalink
Fix selection scope field (#261) (#5391)
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardasB authored Apr 13, 2023
1 parent eb00bf4 commit bbaccc3
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 71 deletions.
2 changes: 1 addition & 1 deletion common/api/appui-react.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -5021,7 +5021,7 @@ export enum SelectionScope {
}

// @public
export const SelectionScopeField: ConnectedComponent<typeof SelectionScopeFieldComponent, Omit_3<React_2.ClassAttributes<SelectionScopeFieldComponent> & SelectionScopeFieldProps, "availableSelectionScopes" | "activeSelectionScope">>;
export const SelectionScopeField: ConnectedComponent<typeof SelectionScopeFieldComponent, Omit_3<SelectionScopeFieldProps, "availableSelectionScopes" | "activeSelectionScope">>;

// @public @deprecated
export class SeparatorBackstageItem extends React_2.PureComponent<BackstageItemProps> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/appui-react",
"comment": "Fix stale options of SelectionScopeField.",
"type": "none"
}
],
"packageName": "@itwin/appui-react"
}
5 changes: 0 additions & 5 deletions ui/appui-react/public/locales/en/UiFramework.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,6 @@
"label": "Scope",
"toolTip": "Selection Scope"
},
"selectionScopeLabels": {
"element": "Element",
"assembly": "Assembly",
"top-assembly": "Top Assembly"
},
"tests": {
"singleContent": "Single Content",
"label": "Test Label",
Expand Down
73 changes: 31 additions & 42 deletions ui/appui-react/src/appui-react/statusfields/SelectionScope.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import classnames from "classnames";
import * as React from "react";
import { connect } from "react-redux";
import { FooterIndicator } from "@itwin/appui-layout-react";
import { Select, SelectOption } from "@itwin/itwinui-react";
import { Select } from "@itwin/itwinui-react";
import { PresentationSelectionScope } from "../redux/SessionState";
import { UiFramework } from "../UiFramework";
import { StatusFieldProps } from "./StatusFieldProps";
Expand All @@ -20,7 +20,6 @@ import { StatusFieldProps } from "./StatusFieldProps";
* @public
*/
interface SelectionScopeFieldProps extends StatusFieldProps {

activeSelectionScope: string;
availableSelectionScopes: PresentationSelectionScope[];
}
Expand All @@ -33,54 +32,44 @@ interface SelectionScopeFieldProps extends StatusFieldProps {
* in the Redux state.
* @public
*/
class SelectionScopeFieldComponent extends React.Component<SelectionScopeFieldProps> {
private _label = UiFramework.translate("selectionScopeField.label");
private _toolTip = UiFramework.translate("selectionScopeField.toolTip");
private _scopeOptions: SelectOption<string>[] = [];
function SelectionScopeFieldComponent(props: SelectionScopeFieldProps) {
const label = UiFramework.translate("selectionScopeField.label");
const toolTip = UiFramework.translate("selectionScopeField.toolTip");

constructor(props: SelectionScopeFieldProps) {
super(props);
this._scopeOptions = this.props.availableSelectionScopes.map((scope: PresentationSelectionScope) => {
const label = !!scope.label ? scope.label : UiFramework.translate(`selectionScopeLabels.${scope.id}`);
return { value: scope.id, label };
});
}
const options = React.useMemo(() => props.availableSelectionScopes.map((scope) => {
return { value: scope.id, label: scope.label };
}), [props.availableSelectionScopes]);

private _updateSelectValue = (newValue: string) => {
const updateSelectValue = (newValue: string) => {
// istanbul ignore else
if (newValue) {
UiFramework.setActiveSelectionScope(newValue);
}
};

public override render(): React.ReactNode {

return (
<FooterIndicator // eslint-disable-line deprecation/deprecation
className={classnames("uifw-statusFields-selectionScope", this.props.className)}
style={this.props.style}
// eslint-disable-next-line deprecation/deprecation
isInFooterMode={this.props.isInFooterMode ?? true}
>
{// eslint-disable-next-line deprecation/deprecation
(this.props.isInFooterMode ?? true) &&
<label className="uifw-statusFields-selectionScope-label">
{this._label}:
</label>
}
<Select
className="uifw-statusFields-selectionScope-selector"
value={this.props.activeSelectionScope}
options={this._scopeOptions}
onChange={this._updateSelectValue}
data-testid="components-selectionScope-selector"
title={this._toolTip}
size="small" />
</FooterIndicator >
);
}
return (
<FooterIndicator // eslint-disable-line deprecation/deprecation
className={classnames("uifw-statusFields-selectionScope", props.className)}
style={props.style}
// eslint-disable-next-line deprecation/deprecation
isInFooterMode={props.isInFooterMode ?? true}
>
{// eslint-disable-next-line deprecation/deprecation
(props.isInFooterMode ?? true) &&
<label className="uifw-statusFields-selectionScope-label">
{label}:
</label>
}
<Select
className="uifw-statusFields-selectionScope-selector"
value={props.activeSelectionScope}
options={options}
onChange={updateSelectValue}
data-testid="components-selectionScope-selector"
title={toolTip}
size="small" />
</FooterIndicator >
);
}

/** Function used by Redux to map state data in Redux store to props that are used to render this component. */
function mapStateToProps(state: any) {
const frameworkState = state[UiFramework.frameworkStateKey]; // since app sets up key, don't hard-code name
Expand Down
23 changes: 0 additions & 23 deletions ui/appui-react/src/test/statusfields/SelectionScope.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,29 +138,6 @@ import TestUtils, { handleError, selectChangeValueByIndex, stubScrollIntoView }
// expect(selectElement.selectedIndex).to.be.equal(1);
});

it("SelectionScopeField should properly handle empty override scope labels", async () => {
UiFramework.dispatchActionToStore(SessionStateActionId.SetAvailableSelectionScopes, [
{ id: "element", label: "" } as PresentationSelectionScope,
{ id: "assembly", label: "" } as PresentationSelectionScope,
{ id: "top-assembly", label: "" } as PresentationSelectionScope,
]);

UiFramework.dispatchActionToStore(SessionStateActionId.SetSelectionScope, "top-assembly");

const component = render(<Provider store={TestUtils.store}>
<StatusBar widgetControl={widgetControl} />
</Provider>);
expect(component).not.to.be.undefined;
const selectElement = component.getByTestId("components-selectionScope-selector") as HTMLSelectElement;
expect(selectElement).not.to.be.null;
expect(UiFramework.getActiveSelectionScope()).to.be.equal("top-assembly");
component.getByText("selectionScopeLabels.top-assembly");
UiFramework.dispatchActionToStore(SessionStateActionId.SetSelectionScope, "assembly");
component.getByText("selectionScopeLabels.assembly");
UiFramework.dispatchActionToStore(SessionStateActionId.SetSelectionScope, "element");
component.getByText("selectionScopeLabels.element");
});

it("SelectionScopeField should properly handle override scope labels", async () => {
UiFramework.dispatchActionToStore(SessionStateActionId.SetAvailableSelectionScopes, [
{ id: "element", label: "Functional Element" } as PresentationSelectionScope,
Expand Down

0 comments on commit bbaccc3

Please sign in to comment.