Add search bar in ObjectsList and ObjectsGroupsList in newIDE

This commit is contained in:
Florian Rival
2017-10-22 21:36:03 +02:00
parent 87bffb4361
commit bf6ed92b1f
3 changed files with 202 additions and 84 deletions

View File

@@ -1,17 +1,29 @@
import React, { Component } from 'react';
import { AutoSizer, List } from 'react-virtualized';
import Paper from 'material-ui/Paper';
import SearchBar from 'material-ui-search-bar';
import GroupRow from './GroupRow';
import { ListItem } from 'material-ui/List';
import newNameGenerator from '../Utils/NewNameGenerator';
import { showWarningBox } from '../UI/Messages/MessageBox';
import { makeAddItem } from '../UI/ListAddItem';
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { enumerateObjectsAndGroups } from '../ObjectsList/EnumerateObjects';
import {
enumerateObjectsAndGroups,
filterGroupsList,
} from '../ObjectsList/EnumerateObjects';
const listItemHeight = 48;
const styles = {
container: { flex: 1, display: 'flex', height: '100%' },
container: {
flex: 1,
display: 'flex',
height: '100%',
flexDirection: 'column',
},
listContainer: {
flex: 1,
},
};
const AddGroupRow = makeAddItem(ListItem);
@@ -103,6 +115,7 @@ export default class GroupsListContainer extends React.Component {
this.projectGroupsList = [];
this.state = {
renamedGroupWithScope: false,
searchText: '',
};
}
@@ -114,7 +127,8 @@ export default class GroupsListContainer extends React.Component {
// If a change is made, the component won't notice it: you have to manually
// call forceUpdate.
if (this.state.renamedGroupWithScope !== nextState.renamedGroupWithScope)
if (this.state.renamedGroupWithScope !== nextState.renamedGroupWithScope ||
this.state.searchText !== nextState.searchText)
return true;
if (
@@ -227,11 +241,12 @@ export default class GroupsListContainer extends React.Component {
render() {
const { project, objectsContainer } = this.props;
const { searchText } = this.state;
const lists = enumerateObjectsAndGroups(project, objectsContainer);
this.containerGroupsList = lists.containerGroupsList;
this.projectGroupsList = lists.projectGroupsList;
const allGroupsList = lists.allGroupsList;
this.containerGroupsList = filterGroupsList(lists.containerGroupsList);
this.projectGroupsList = filterGroupsList(lists.projectGroupsList);
const allGroupsList = filterGroupsList(lists.allGroupsList);
const fullList = allGroupsList.concat({
key: 'add-groups-row',
object: null,
@@ -241,32 +256,42 @@ export default class GroupsListContainer extends React.Component {
// has been changed. Avoid accessing to invalid objects that could
// crash the app.
const listKey = project.ptr + ';' + objectsContainer.ptr;
console.log('Render');
return (
<Paper style={styles.container}>
<AutoSizer>
{({ height, width }) => (
<SortableGroupsList
key={listKey}
ref={sortableList => (this.sortableList = sortableList)}
fullList={fullList}
project={project}
width={width}
height={height}
renamedGroupWithScope={this.state.renamedGroupWithScope}
onEditGroup={this.props.onEditGroup}
onAddGroup={this.addGroup}
onEditName={this._onEditName}
onDelete={this._onDelete}
onRename={this._onRename}
onSortEnd={({ oldIndex, newIndex }) =>
this._onMove(oldIndex, newIndex)}
helperClass="sortable-helper"
distance={30}
/>
)}
</AutoSizer>
<div style={styles.listContainer}>
<AutoSizer>
{({ height, width }) => (
<SortableGroupsList
key={listKey}
ref={sortableList => (this.sortableList = sortableList)}
fullList={fullList}
project={project}
width={width}
height={height}
renamedGroupWithScope={this.state.renamedGroupWithScope}
onEditGroup={this.props.onEditGroup}
onAddGroup={this.addGroup}
onEditName={this._onEditName}
onDelete={this._onDelete}
onRename={this._onRename}
onSortEnd={({ oldIndex, newIndex }) =>
this._onMove(oldIndex, newIndex)}
helperClass="sortable-helper"
distance={30}
/>
)}
</AutoSizer>
</div>
<SearchBar
value={searchText}
onRequestSearch={() => {}}
onChange={text =>
this.setState({
searchText: text,
})}
style={styles.searchBar}
/>
</Paper>
);
}

View File

@@ -1,12 +1,33 @@
// @flow
import { mapFor } from '../Utils/MapFor';
const gd = global.gd;
type Object = {
getName: Function,
};
type Group = {
getName: Function,
};
type ObjectWithContext = {|
object: Object,
global: boolean,
|};
type GroupWithContext = {|
group: Group,
global: boolean,
|};
type ObjectWithContextList = Array<ObjectWithContext>;
type GroupWithContextList = Array<GroupWithContext>;
export const enumerateObjects = (
project,
objectsContainer,
type = undefined
project: any,
objectsContainer: any,
type: ?string = undefined
) => {
const filterObject = object => {
const filterObject = (object: Object): boolean => {
return (
!type ||
gd.getTypeOfObject(project, objectsContainer, object.getName(), false) ===
@@ -14,22 +35,27 @@ export const enumerateObjects = (
);
};
const containerObjectsList = mapFor(
const containerObjectsList: ObjectWithContextList = mapFor(
0,
objectsContainer.getObjectsCount(),
i => objectsContainer.getObjectAt(i)
)
.filter(filterObject)
.map(object => ({ object, global: false }));
.map((object: Object): ObjectWithContext => ({ object, global: false }));
const projectObjectsList =
const projectObjectsList: ObjectWithContextList =
project === objectsContainer
? []
: mapFor(0, project.getObjectsCount(), i => project.getObjectAt(i))
.filter(filterObject)
.map(object => ({ object, global: true }));
.map((object: Object): ObjectWithContext => ({
object,
global: true,
}));
const allObjectsList = containerObjectsList.concat(projectObjectsList);
const allObjectsList: ObjectWithContextList = containerObjectsList.concat(
projectObjectsList
);
return {
containerObjectsList,
@@ -38,19 +64,55 @@ export const enumerateObjects = (
};
};
export const filterObjectsList = (
list: ObjectWithContextList,
searchText: string
): ObjectWithContextList => {
if (!searchText) return list;
const lowercaseSearchText = searchText.toLowerCase();
return list.filter((objectWithContext: ObjectWithContext) => {
return (
objectWithContext.object
.getName()
.toLowerCase()
.indexOf(lowercaseSearchText) !== -1
);
});
};
export const filterGroupsList = (
list: GroupWithContextList,
searchText: string
): GroupWithContextList => {
if (!searchText) return list;
const lowercaseSearchText = searchText.toLowerCase();
return list.filter((groupWithContext: GroupWithContext) => {
return (
groupWithContext.group
.getName()
.toLowerCase()
.indexOf(lowercaseSearchText) !== -1
);
});
};
export const enumerateObjectsAndGroups = (
project,
objectsContainer,
type = undefined
project: any,
objectsContainer: any,
type: ?string = undefined
) => {
const filterObject = object => {
const filterObject = (object: Object): boolean => {
return (
!type ||
gd.getTypeOfObject(project, objectsContainer, object.getName(), false) ===
type
);
};
const filterGroup = group => {
const filterGroup = (group: Group): boolean => {
return (
!type ||
gd.getTypeOfObject(project, objectsContainer, group.getName(), true) ===
@@ -58,7 +120,7 @@ export const enumerateObjectsAndGroups = (
);
};
const containerObjectsList = mapFor(
const containerObjectsList: ObjectWithContextList = mapFor(
0,
objectsContainer.getObjectsCount(),
i => objectsContainer.getObjectAt(i)
@@ -67,13 +129,17 @@ export const enumerateObjectsAndGroups = (
.map(object => ({ object, global: false }));
const containerGroups = objectsContainer.getObjectGroups();
const containerGroupsList = mapFor(0, containerGroups.count(), i => {
return containerGroups.getAt(i);
})
const containerGroupsList: GroupWithContextList = mapFor(
0,
containerGroups.count(),
i => {
return containerGroups.getAt(i);
}
)
.filter(filterGroup)
.map(group => ({ group, global: false }));
const projectObjectsList =
const projectObjectsList: ObjectWithContextList =
project === objectsContainer
? []
: mapFor(0, project.getObjectsCount(), i => project.getObjectAt(i))
@@ -81,7 +147,7 @@ export const enumerateObjectsAndGroups = (
.map(object => ({ object, global: true }));
const projectGroups = project.getObjectGroups();
const projectGroupsList =
const projectGroupsList: GroupWithContextList =
project === objectsContainer
? []
: mapFor(0, projectGroups.count(), i => {
@@ -90,8 +156,12 @@ export const enumerateObjectsAndGroups = (
.filter(filterGroup)
.map(group => ({ group, global: true }));
const allObjectsList = containerObjectsList.concat(projectObjectsList);
const allGroupsList = containerGroupsList.concat(projectGroupsList);
const allObjectsList: ObjectWithContextList = containerObjectsList.concat(
projectObjectsList
);
const allGroupsList: GroupWithContextList = containerGroupsList.concat(
projectGroupsList
);
return {
containerObjectsList,

View File

@@ -2,6 +2,7 @@ import React, { Component } from 'react';
import { AutoSizer, List } from 'react-virtualized';
import { ListItem } from 'material-ui/List';
import Paper from 'material-ui/Paper';
import SearchBar from 'material-ui-search-bar';
import ObjectRow from './ObjectRow';
import NewObjectDialog from './NewObjectDialog';
import VariablesEditorDialog from '../VariablesList/VariablesEditorDialog';
@@ -9,11 +10,19 @@ import newNameGenerator from '../Utils/NewNameGenerator';
import { showWarningBox } from '../UI/Messages/MessageBox';
import { makeAddItem } from '../UI/ListAddItem';
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { enumerateObjects } from './EnumerateObjects';
import { enumerateObjects, filterObjectsList } from './EnumerateObjects';
const listItemHeight = 48;
const styles = {
container: { flex: 1, display: 'flex', height: '100%' },
container: {
flex: 1,
display: 'flex',
height: '100%',
flexDirection: 'column',
},
listContainer: {
flex: 1,
}
};
const AddObjectRow = makeAddItem(ListItem);
@@ -115,6 +124,7 @@ export default class ObjectsListContainer extends React.Component {
newObjectDialogOpen: false,
renamedObjectWithScope: false,
variablesEditedObject: null,
searchText: '',
};
}
@@ -129,7 +139,8 @@ export default class ObjectsListContainer extends React.Component {
if (
this.state.newObjectDialogOpen !== nextState.newObjectDialogOpen ||
this.state.renamedObjectWithScope !== nextState.renamedObjectWithScope ||
this.state.variablesEditedObject !== nextState.variablesEditedObject
this.state.variablesEditedObject !== nextState.variablesEditedObject ||
this.state.searchText !== nextState.searchText
)
return true;
@@ -267,11 +278,12 @@ export default class ObjectsListContainer extends React.Component {
render() {
const { project, objectsContainer } = this.props;
const { searchText } = this.state;
const lists = enumerateObjects(project, objectsContainer);
this.containerObjectsList = lists.containerObjectsList;
this.projectObjectsList = lists.projectObjectsList;
const allObjectsList = lists.allObjectsList;
this.containerObjectsList = filterObjectsList(lists.containerObjectsList, searchText);
this.projectObjectsList = filterObjectsList(lists.projectObjectsList, searchText);
const allObjectsList = filterObjectsList(lists.allObjectsList, searchText);
const fullList = allObjectsList.concat({
key: 'add-objects-row',
object: null,
@@ -281,36 +293,47 @@ export default class ObjectsListContainer extends React.Component {
// has been changed. Avoid accessing to invalid objects that could
// crash the app.
const listKey = project.ptr + ';' + objectsContainer.ptr;
console.log('Render');
return (
<Paper style={styles.container}>
<AutoSizer>
{({ height, width }) => (
<SortableObjectsList
key={listKey}
ref={sortableList => (this.sortableList = sortableList)}
fullList={fullList}
project={project}
width={width}
height={height}
renamedObjectWithScope={this.state.renamedObjectWithScope}
getThumbnail={this.props.getThumbnail}
selectedObjectName={this.props.selectedObjectName}
onObjectSelected={this.props.onObjectSelected}
onEditObject={this.props.onEditObject}
onAddNewObject={() => this.setState({ newObjectDialogOpen: true })}
onEditName={this._onEditName}
onEditVariables={this._onEditVariables}
onDelete={this._onDelete}
onRename={this._onRename}
onSortEnd={({ oldIndex, newIndex }) =>
this._onMove(oldIndex, newIndex)}
helperClass="sortable-helper"
distance={30}
/>
)}
</AutoSizer>
<div style={styles.listContainer}>
<AutoSizer>
{({ height, width }) => (
<SortableObjectsList
key={listKey}
ref={sortableList => (this.sortableList = sortableList)}
fullList={fullList}
project={project}
width={width}
height={height}
renamedObjectWithScope={this.state.renamedObjectWithScope}
getThumbnail={this.props.getThumbnail}
selectedObjectName={this.props.selectedObjectName}
onObjectSelected={this.props.onObjectSelected}
onEditObject={this.props.onEditObject}
onAddNewObject={() =>
this.setState({ newObjectDialogOpen: true })}
onEditName={this._onEditName}
onEditVariables={this._onEditVariables}
onDelete={this._onDelete}
onRename={this._onRename}
onSortEnd={({ oldIndex, newIndex }) =>
this._onMove(oldIndex, newIndex)}
helperClass="sortable-helper"
distance={30}
/>
)}
</AutoSizer>
</div>
<SearchBar
value={searchText}
onRequestSearch={() => {}}
onChange={text =>
this.setState({
searchText: text,
})}
style={styles.searchBar}
/>
{this.state.newObjectDialogOpen && (
<NewObjectDialog
open={this.state.newObjectDialogOpen}