Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DYN-6956 - symbol nodes should not show in home workspace search/browse UI. #228

Merged
merged 16 commits into from
May 10, 2024
Merged
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;
mjkkirschner marked this conversation as resolved.
Show resolved Hide resolved

// 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
Loading