Skip to content

Commit

Permalink
DYN-6956 - symbol nodes should not show in home workspace search/brow…
Browse files Browse the repository at this point in the history
…se UI. (DynamoDS#228)

tests pass, merging.
  • Loading branch information
mjkkirschner authored May 10, 2024
1 parent 5bd2f15 commit ea43d0b
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 57 deletions.
5 changes: 3 additions & 2 deletions __tests__/Snapshottest/UIOutputComparisonTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ describe("LibraryContainer", function () {
let data = createLibraryItem(ItemData);

// Create "LibraryContainer" to pass as an argument for creation of "LibraryItem"
const libContainer = LibraryEntryPoint.CreateLibraryController();
let libcontroller = LibraryEntryPoint.CreateLibraryController()
let libContainer = mount(libcontroller.createLibraryContainer())

// Creation of LibraryItem component
const libraryItemComponent = <LibraryItem libraryContainer={libContainer} data={data} showItemSummary={false} />;
const libraryItemComponent = <LibraryItem libraryContainer={libContainer as any} data={data} showItemSummary={false} />;

it("Test UI rendering of single component of Library Item", function () {
// "LibraryItem" with Shallow rendering to testing component as a unit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ exports[`LibraryContainer Test UI rendering of Library Item and child components
"contextData": "",
"description": "",
"expanded": false,
"hiddenInWorkspaceContext": false,
"iconUrl": "",
"itemType": "category",
"keywords": [
Expand All @@ -29,6 +30,7 @@ exports[`LibraryContainer Test UI rendering of Library Item and child components
"contextData": "",
"description": "",
"expanded": false,
"hiddenInWorkspaceContext": false,
"iconUrl": "",
"itemType": "category",
"keywords": [
Expand All @@ -45,6 +47,7 @@ exports[`LibraryContainer Test UI rendering of Library Item and child components
"contextData": "",
"description": "",
"expanded": false,
"hiddenInWorkspaceContext": false,
"iconUrl": "",
"itemType": "none",
"keywords": [
Expand All @@ -59,35 +62,47 @@ exports[`LibraryContainer Test UI rendering of Library Item and child components
}
}
libraryContainer={
LibraryController {
"DefaultSectionName": "default",
"FilterCategoryEventName": "filterCategoryChange",
"ItemClickedEventName": "itemClicked",
"ItemMouseEnterEventName": "itemMouseEnter",
"ItemMouseLeaveEventName": "itemMouseLeave",
"ItemSummaryExpandedEventName": "itemSummaryExpanded",
"MiscSectionName": "Miscellaneous",
"RefreshLibraryViewRequestName": "refreshLibraryView",
"SearchTextUpdatedEventName": "searchTextUpdated",
"SectionIconClickedEventName": "sectionIconClicked",
"createLibraryByElementId": [Function],
"createLibraryContainer": [Function],
"on": [Function],
"raiseEvent": [Function],
"reactor": Reactor {
"events": [],
},
"refreshLibraryView": [Function],
"refreshLibraryViewHandler": null,
"registerRequestHandler": [Function],
"request": [Function],
"requestHandler": {},
"searchLibraryItemsHandler": null,
"setLayoutSpecsJson": [Function],
"setLayoutSpecsJsonHandler": null,
"setLoadedTypesJson": [Function],
"setLoadedTypesJsonHandler": null,
}
<LibraryContainer
defaultSectionString="default"
libraryController={
LibraryController {
"DefaultSectionName": "default",
"FilterCategoryEventName": "filterCategoryChange",
"ItemClickedEventName": "itemClicked",
"ItemMouseEnterEventName": "itemMouseEnter",
"ItemMouseLeaveEventName": "itemMouseLeave",
"ItemSummaryExpandedEventName": "itemSummaryExpanded",
"MiscSectionName": "Miscellaneous",
"RefreshLibraryViewRequestName": "refreshLibraryView",
"SearchTextUpdatedEventName": "searchTextUpdated",
"SectionIconClickedEventName": "sectionIconClicked",
"createLibraryByElementId": [Function],
"createLibraryContainer": [Function],
"on": [Function],
"raiseEvent": [Function],
"reactor": Reactor {
"events": [],
},
"refreshLibraryView": [Function],
"refreshLibraryViewHandler": [Function],
"registerRequestHandler": [Function],
"request": [Function],
"requestHandler": {},
"searchLibraryItemsHandler": null,
"setHostContext": [Function],
"setHostContextHandler": [Function],
"setLayoutSpecsJson": [Function],
"setLayoutSpecsJsonHandler": [Function],
"setLoadedTypesJson": [Function],
"setLoadedTypesJsonHandler": [Function],
}
}
miscSectionString="Miscellaneous"
>
<div>
This is LibraryContainer
</div>
</LibraryContainer>
}
showItemSummary={false}
>
Expand Down
5 changes: 3 additions & 2 deletions __tests__/UITests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ describe("LibraryContainer UI", function () {
};

libController = LibraryEntryPoint.CreateLibraryController();
libContainer = mount(libController.createLibraryContainer())
});

it("should recognize mouse click event and change expand state", function () {
Expand All @@ -117,7 +118,7 @@ describe("LibraryContainer UI", function () {
// If you are testing full React components,
// mount is used to do rendering and test actions are simulated on mounted html

let libraryItem = mount(<LibraryItem libraryContainer={libController} data={data} showItemSummary={false} />);
let libraryItem = mount(<LibraryItem libraryContainer={libContainer as any} data={data} showItemSummary={false} />);

expect(libraryItem).to.have.lengthOf(1);
expect(libraryItem.props().data.childItems).to.have.lengthOf(2);
Expand All @@ -137,7 +138,7 @@ describe("LibraryContainer UI", function () {
let data = createLibraryItem(ItemData);

//pass a callback which if called will end the test
let libraryItem = mount(<LibraryItem libraryContainer={libController} data={data} showItemSummary={false} onItemWillExpand={() => { done() }} />);
let libraryItem = mount(<LibraryItem libraryContainer={libContainer} data={data} showItemSummary={false} onItemWillExpand={() => { done() }} />);

let header = libraryItem.find(('div.LibraryItemHeader')).at(0);// the state of LibraryItem is changed when clicking on header
expect(header).to.have.lengthOf(1); // verify that there is a header
Expand Down
6 changes: 4 additions & 2 deletions docs/RawTypeData.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"itemType": "action",
"keywords": "Dynamo.Nodes.Symbol, Input, variable, argument, parameter",
"weight": 0,
"description": "A function parameter, use with custom nodes.\n\nYou can specify the type and default value for parameter. E.g.,\n\ninput : var[]..[]\nvalue : bool = false"
"description": "A function parameter, use with custom nodes.\n\nYou can specify the type and default value for parameter. E.g.,\n\ninput : var[]..[]\nvalue : bool = false",
"hiddenInWorkspaceContext":true
},
{
"fullyQualifiedName": "Core.Input.Output",
Expand All @@ -28,7 +29,8 @@
"itemType": "action",
"keywords": "Dynamo.Nodes.Output, Output",
"weight": 0,
"description": "A function output, use with custom nodes"
"description": "A function output, use with custom nodes",
"hiddenInWorkspaceContext":true
},
{
"fullyQualifiedName": "Core.Units.Convert Between Units",
Expand Down
5 changes: 5 additions & 0 deletions src/LibraryUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class TypeListNode {
description: string = "";
processed: boolean = false;
weight: number = 0;
hiddenInWorkspaceContext:boolean

constructor(data: any) {
this.fullyQualifiedName = data.fullyQualifiedName;
Expand All @@ -27,13 +28,15 @@ export class TypeListNode {
this.parameters = data.parameters;
this.description = data.description;
this.weight = data.weight;
this.hiddenInWorkspaceContext = data.hiddenInWorkspaceContext;
}
}

export interface IncludeInfo {
path: string;
iconUrl?: string;
inclusive?: boolean;
hiddenInWorkspaceContext?:boolean
}

export class IncludeItemPair {
Expand Down Expand Up @@ -91,6 +94,7 @@ export class ItemData {
childItems: ItemData[] = [];
pathToItem: ItemData[] = [];
weight: number = 0;
hiddenInWorkspaceContext:boolean = false

constructor(public text: string) {
this.keywords.push(text ? text.toLowerCase() : text);
Expand Down Expand Up @@ -118,6 +122,7 @@ export class ItemData {
this.keywords.push(keyword.toLowerCase().replace(/ /g, ''));
});
this.keywords.push(typeListNode.fullyQualifiedName.toLowerCase().replace(/ /g, ''));
this.hiddenInWorkspaceContext = typeListNode.hiddenInWorkspaceContext;
}

appendChild(childItem: ItemData) {
Expand Down
7 changes: 7 additions & 0 deletions src/SharedTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

/**
* Hosting contexts for the library. These represent
* Dynamo home and custom workspaces, none is the default.
*/
export enum HostingContextType { home ="home", custom = "custom", none = "none"}

29 changes: 27 additions & 2 deletions src/components/LibraryContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Searcher } from "../Searcher";
import { SearchBar, CategoryData } from "./SearchBar";
import { SearchResultItem } from "./SearchResultItem";
import * as ReactDOM from "react-dom";
import { HostingContextType } from "../SharedTypes";

declare global {
interface Window { setTooltipText: any; }
Expand Down Expand Up @@ -41,6 +42,16 @@ export interface LibraryContainerStates {
action: string;
query: string;
}
/**
* context that the library is currently displayed in, currently used to hide
* some loadedtypes in certain contexts.
*/
hostingContext:HostingContextType
/**
* used to control legacy props overriding state behavior. (see UNSAFE_componentWillMount)
* TODO (get rid of this and the unsafe lifecycle hook while retaining behavior.)
*/
shouldOverrideExpandedState:boolean
}

export class LibraryContainer extends React.Component<LibraryContainerProps, LibraryContainerStates> {
Expand Down Expand Up @@ -72,12 +83,13 @@ export class LibraryContainer extends React.Component<LibraryContainerProps, Lib
this.handleKeyDown = this.handleKeyDown.bind(this);
this.scrollToExpandedItem = this.scrollToExpandedItem.bind(this);
this.setTooltipText = this.setTooltipText.bind(this);
this.setHostContext = this.setHostContext.bind(this);

// Set handlers after methods are bound.
this.props.libraryController.setLoadedTypesJsonHandler = this.setLoadedTypesJson;
this.props.libraryController.setLayoutSpecsJsonHandler = this.setLayoutSpecsJson;
this.props.libraryController.refreshLibraryViewHandler = this.refreshLibraryView;

this.props.libraryController.setHostContextHandler = this.setHostContext;

// Initialize the search utilities with empty data
this.searcher = new Searcher();
Expand All @@ -93,7 +105,9 @@ export class LibraryContainer extends React.Component<LibraryContainerProps, Lib
create: ClusterTypeDescription.create,
action: ClusterTypeDescription.action,
query: ClusterTypeDescription.query
}
},
hostingContext: "none" as HostingContextType,
shouldOverrideExpandedState : true
};
window.setTooltipText = this.setTooltipText;
}
Expand Down Expand Up @@ -202,6 +216,13 @@ export class LibraryContainer extends React.Component<LibraryContainerProps, Lib
this.updateSections(this.generatedSections);
}

setHostContext(context:HostingContextType){
//besides setting the host context we also set the expanded state override mode to false
//so that the currently expanded library items retain their state and don't all close
//as a result of this top level state update.
this.setState({shouldOverrideExpandedState:false, hostingContext:context})
}

updateSections(sections: any): void {
// Obtain the categories from each section to be added into the filtering options for search
for (let section of sections) {
Expand Down Expand Up @@ -284,8 +305,12 @@ export class LibraryContainer extends React.Component<LibraryContainerProps, Lib
//Needs to be done inside the callback because the callback is executed in a async way otherwise we don't have control when this method will be executed
this.updateSearchViewDelayed(text);
}.bind(this));
//this else block is only hit in the libjs test app, not usually in Dynamo.
} else {
LibraryUtilities.searchItemResursive(this.generatedSections, text);
if(text.length == 0){
LibraryUtilities.setItemStateRecursive(this.generatedSections, true, false);
}
this.updateSearchViewDelayed(text);
}
}.bind(this), 300);
Expand Down
36 changes: 19 additions & 17 deletions src/components/LibraryItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import * as ReactDOM from "react-dom";
import { ClusterView } from "./ClusterView";
import * as LibraryUtilities from "../LibraryUtilities";
import { ArrowIcon } from "./icons";
import { LibraryContainer } from "./LibraryContainer";
import { HostingContextType } from "../SharedTypes";

export interface LibraryItemProps {
libraryContainer: any,
libraryContainer: LibraryContainer,
data: LibraryUtilities.ItemData,
showItemSummary: boolean,
onItemWillExpand?: Function,
Expand Down Expand Up @@ -83,24 +85,26 @@ export class LibraryItem extends React.Component<LibraryItemProps, LibraryItemSt
this.onLibraryItemMouseLeave = this.onLibraryItemMouseLeave.bind(this);
this.onSectionIconClicked = this.onSectionIconClicked.bind(this);
this.onSingleChildItemWillExpand = this.onSingleChildItemWillExpand.bind(this);

}

// By default all items in search view will be expanded. In search view,
// By default all items in search view will be expanded. In search view,
// user is still able to expand/unexpand the item, which will toggle the
// expansion state. This will make sure that the expansion state of an item
// in search view will not be affected by the previous user click.
UNSAFE_componentWillReceiveProps(nextProps: LibraryItemProps) {
if (nextProps.data.expanded !== this.state.expanded) {
if (nextProps.data.expanded !== this.state.expanded &&
this.props.libraryContainer.state.shouldOverrideExpandedState)
{
this.setState({ expanded: nextProps.data.expanded });
}
//keep the core group defined in layoutspec always expanded.
//Commented as part of the task : https://jira.autodesk.com/browse/QNTM-2975
// if(nextProps.data.itemType == "coregroup") {
// this.setState({expanded:true});
// }
}
}

render() {
if ((this.props.libraryContainer.state?.hostingContext == HostingContextType.home)
&& this.props.data.hiddenInWorkspaceContext){
return null;
}
if (!this.props.data.visible) {
return null;
}
Expand Down Expand Up @@ -393,13 +397,10 @@ export class LibraryItem extends React.Component<LibraryItemProps, LibraryItemSt
if(this.props.data.text == "Add-ons") return;
// Toggle expansion state.
let currentlyExpanded = this.state.expanded;

if (this.props.data.childItems.length > 0 && !currentlyExpanded && this.props.onItemWillExpand) {
this.props.onItemWillExpand(ReactDOM.findDOMNode(this));
}

this.setState({ expanded: !currentlyExpanded });

//auto expand the coregroup elements
//commenting as part of the task : https://jira.autodesk.com/browse/QNTM-2975
// if(this.props.data.itemType === "category" ) {
Expand All @@ -415,6 +416,10 @@ export class LibraryItem extends React.Component<LibraryItemProps, LibraryItemSt
libraryContainer.raiseEvent(libraryContainer.props.libraryController.ItemClickedEventName,
this.props.data.contextData);
}
//not ideal, but we set the state without setState here to avoid triggering a render so
//that the item we just clicked will stay expanded.
// @ts-ignore
this.props.libraryContainer.state.shouldOverrideExpandedState = true
}

onSectionIconClicked(event: any) {
Expand All @@ -423,14 +428,11 @@ export class LibraryItem extends React.Component<LibraryItemProps, LibraryItemSt
event.stopPropagation(); // Prevent the onClick event of its parent item from being called.
}

// Collapse all child items when one of the child items is expanded
onSingleChildItemWillExpand() {
for (let item of this.props.data.childItems) {
item.expanded = false;
}
//"this" here refers to the parent library item, and will expand it and kick off a render cycle
//for all children below it.
this.setState({ expanded: true }); // Make the current item (parent) expanded.
}

onLibraryItemMouseLeave() {
let libraryContainer = this.props.libraryContainer;
if (this.props.data.childItems.length == 0) {
Expand Down
Loading

0 comments on commit ea43d0b

Please sign in to comment.