Skip to content

Commit

Permalink
Add list filtering to lane editor. (#50)
Browse files Browse the repository at this point in the history
* Add filter select to available lists on lane editor.

* Update tests.

* Add tests.

* Remove extra whitespace.

* Add share icon to lists that are not owned.

* Consolidate duplicate list info rendering code.
  • Loading branch information
ray-lee authored Oct 3, 2022
1 parent 820b17a commit ce8cafe
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 28 deletions.
81 changes: 64 additions & 17 deletions src/components/LaneCustomListsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ import * as React from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import { CustomListData } from "../interfaces";
import AddIcon from "./icons/AddIcon";
import ShareIcon from "./icons/ShareIcon";
import TrashIcon from "./icons/TrashIcon";
import GrabIcon from "./icons/GrabIcon";
import EditableInput from "./EditableInput";
import { Button } from "library-simplified-reusable-components";

export interface LaneCustomListsEditorProps
extends React.Props<LaneCustomListsEditor> {
allCustomLists: CustomListData[];
customListIds: number[];
filter?: string;
filteredCustomLists?: CustomListData[];
changeFilter?: (value: string) => void;
onUpdate?: (customListIds: number[]) => void;
}

Expand All @@ -22,6 +27,11 @@ export default class LaneCustomListsEditor extends React.Component<
LaneCustomListsEditorProps,
LaneCustomListsEditorState
> {
static defaultProps = {
filter: "owned",
filteredCustomLists: [],
};

constructor(props) {
super(props);
this.state = {
Expand All @@ -32,6 +42,56 @@ export default class LaneCustomListsEditor extends React.Component<
this.onDragEnd = this.onDragEnd.bind(this);
}

renderFilterSelect(): JSX.Element {
const filters = [
["All", ""],
["Owned", "owned"],
["Subscribed", "shared-in"],
];

return (
<fieldset>
<legend className="visuallyHidden">Select filter type</legend>

<EditableInput
elementType="select"
name="filter"
label="Show "
value={this.props.filter}
onChange={this.props.changeFilter}
>
{filters.map(([label, value]) => (
<option
key={value}
value={value}
aria-selected={this.props.filter === value}
>
{label}
</option>
))}
</EditableInput>
</fieldset>
);
}

renderListInfo(list): JSX.Element {
return (
<>
<GrabIcon />
<div className="list-info">
<div className="list-name">
{!list.is_owner && (
<ShareIcon title="This list is shared by another library." />
)}
{list.name}
</div>
<div className="list-count">Items in list: {list.entry_count}</div>
<div className="list-id">ID-{list.id}</div>
</div>
</>
);
}

render(): JSX.Element {
return (
<DragDropContext
Expand All @@ -42,6 +102,7 @@ export default class LaneCustomListsEditor extends React.Component<
<div className="available-lists">
<div className="droppable-header">
<h4>Available Lists ({this.listsNotInLane().length})</h4>
{this.renderFilterSelect()}
</div>
<Droppable
droppableId="available-lists"
Expand Down Expand Up @@ -73,14 +134,7 @@ export default class LaneCustomListsEditor extends React.Component<
style={provided.draggableStyle}
{...provided.dragHandleProps}
>
<GrabIcon />
<div className="list-info">
<div className="list-name">{list.name}</div>
<div className="list-count">
Items in list: {list.entry_count}
</div>
<div className="list-id">ID-{list.id}</div>
</div>
{this.renderListInfo(list)}
<div className="links">
<Button
className="inverted"
Expand Down Expand Up @@ -137,14 +191,7 @@ export default class LaneCustomListsEditor extends React.Component<
style={provided.draggableStyle}
{...provided.dragHandleProps}
>
<GrabIcon />
<div className="list-info">
<div className="list-name">{list.name}</div>
<div className="list-count">
Items in list: {list.entry_count}
</div>
<div className="list-id">ID-{list.id}</div>
</div>
{this.renderListInfo(list)}
<div className="links">
<Button
className="danger"
Expand Down Expand Up @@ -176,7 +223,7 @@ export default class LaneCustomListsEditor extends React.Component<

listsNotInLane(): CustomListData[] {
const lists = [];
for (const list of this.props.allCustomLists || []) {
for (const list of this.props.filteredCustomLists || []) {
let found = false;
for (const listId of this.getCustomListIds()) {
if (list.id === listId) {
Expand Down
28 changes: 28 additions & 0 deletions src/components/LaneEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface LaneEditorProps extends React.Props<LaneEditor> {
}

export interface LaneEditorState {
filter: string;
name: string;
customListIds: number[];
inheritParentRestrictions: boolean;
Expand All @@ -39,13 +40,15 @@ export default class LaneEditor extends React.Component<
constructor(props) {
super(props);
this.state = {
filter: "owned",
name: this.props.lane && this.props.lane.display_name,
customListIds: (this.props.lane && this.props.lane.custom_list_ids) || [],
inheritParentRestrictions:
this.props.lane && this.props.lane.inherit_parent_restrictions,
};
this.changeName = this.changeName.bind(this);
this.changeCustomLists = this.changeCustomLists.bind(this);
this.changeFilter = this.changeFilter.bind(this);
this.changeInheritParentRestrictions = this.changeInheritParentRestrictions.bind(
this
);
Expand All @@ -56,6 +59,24 @@ export default class LaneEditor extends React.Component<
this.renderInfo = this.renderInfo.bind(this);
}

filterLists(lists?: CustomListData[]) {
lists = lists || this.props.customLists || [];

const { filter } = this.state;

let selectedFilter = null;

if (filter === "owned") {
selectedFilter = (list) => list.is_owner;
} else if (filter === "shared-in") {
selectedFilter = (list) => !list.is_owner;
} else if (filter === "shared-out") {
selectedFilter = (list) => list.is_owner && list.is_shared;
}

return selectedFilter ? lists.filter(selectedFilter) : lists;
}

render(): JSX.Element {
const parent = this.props.findParentOfLane(this.props.lane);
return (
Expand Down Expand Up @@ -116,6 +137,9 @@ export default class LaneEditor extends React.Component<
<LaneCustomListsEditor
allCustomLists={this.props.customLists}
customListIds={this.state.customListIds}
filter={this.state.filter}
filteredCustomLists={this.filterLists()}
changeFilter={this.changeFilter}
onUpdate={this.changeCustomLists}
ref={this.laneCustomListsRef}
/>
Expand Down Expand Up @@ -205,6 +229,10 @@ export default class LaneEditor extends React.Component<
this.setState(Object.assign({}, this.state, { customListIds }));
}

changeFilter(filter) {
this.setState({ filter });
}

changeInheritParentRestrictions() {
const inheritParentRestrictions = !this.state.inheritParentRestrictions;
this.setState(Object.assign({}, this.state, { inheritParentRestrictions }));
Expand Down
Loading

0 comments on commit ce8cafe

Please sign in to comment.