Skip to content

Commit

Permalink
add sidebar and journal click-to-search
Browse files Browse the repository at this point in the history
- add sidebar to main view with journals
- add setSearch behavior to search store
- add "click to search", where clicking populates an in: search tag for only that journal
  • Loading branch information
cloverich committed Jan 21, 2024
1 parent 6e4d611 commit 5f4186a
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 8 deletions.
112 changes: 110 additions & 2 deletions src/views/documents/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
import React from "react";
import { Pane } from "evergreen-ui";
import React, { useContext } from "react";
import {
Pane,
SideSheet,
Card,
Heading,
UnorderedList,
ListItem,
FolderCloseIcon,
IconButton,
FolderOpenIcon,
} from "evergreen-ui";
import TagSearch from "./search";
import { Link } from "react-router-dom";
import { SearchV2Store } from "./SearchStore";
import { JournalsStoreContext } from "../../hooks/useJournalsLoader";
import { JournalResponse } from "../../hooks/useClient";

interface Props {
store: SearchV2Store;
Expand All @@ -11,9 +23,23 @@ interface Props {
}

export function Layout(props: Props) {
const [isSidebarOpen, setIsSidebarOpen] = React.useState(false);

return (
<Pane>
<Pane marginBottom={8}>
<IconButton
icon={FolderOpenIcon}
onClick={() => setIsSidebarOpen(true)}
marginRight={8}
>
Select Journals
</IconButton>
<JournalSelectionSidebar
isShown={isSidebarOpen}
setIsShown={setIsSidebarOpen}
search={props.store}
/>
<TagSearch store={props.store} />
</Pane>
<Pane>
Expand All @@ -23,3 +49,85 @@ export function Layout(props: Props) {
</Pane>
);
}

interface SidebarProps {
isShown: boolean;
setIsShown: (isShown: boolean) => void;
search: SearchV2Store;
}

/**
* Sidebar for selecting journals to search.
*/
function JournalSelectionSidebar(props: SidebarProps) {
const { isShown, setIsShown } = props;
const jstore = useContext(JournalsStoreContext);
const searchStore = props.search;

function search(journal: string) {
searchStore.setSearch([`in:${journal}`]);
setIsShown(false);
return false;
}

return (
<React.Fragment>
<SideSheet
position="left"
isShown={isShown}
onCloseComplete={() => setIsShown(false)}
preventBodyScrolling
containerProps={{
display: "flex",
flex: "1",
flexDirection: "column",
}}
>
<Pane zIndex={1} flexShrink={0} elevation={0} backgroundColor="white">
<Pane padding={16}>
<Heading size={600}>Journals</Heading>
</Pane>
</Pane>
<Pane flex="1" overflowY="scroll" background="tint1" padding={16}>
<JournalsCard
journals={jstore.active}
title="Active Journals"
search={search}
/>
<JournalsCard
journals={jstore.archived}
title="Archived Journals"
search={search}
/>
</Pane>
</SideSheet>
</React.Fragment>
);
}

function JournalsCard(props: {
journals: JournalResponse[];
title: string;
search: (journalName: string) => boolean;
}) {
if (!props.journals.length) {
return null;
}

const journals = props.journals.map((j) => {
return (
<ListItem key={j.id} icon={FolderCloseIcon}>
<a href="" onClick={() => props.search(j.name)}>
{j.name}
</a>
</ListItem>
);
});

return (
<Card backgroundColor="white" elevation={0} padding={16} marginBottom={16}>
<Heading>{props.title}</Heading>
<UnorderedList>{journals}</UnorderedList>
</Card>
);
}
12 changes: 11 additions & 1 deletion src/views/documents/SearchStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ export class SearchV2Store {
this.tagSeachStore.addTokens(tokens);
}

/**
* NOTE: This should be private, or refactored to trigger a search
*/
@action
setTokens = (tokens: SearchToken[]) => {
// Filter out invalid in: journal tokens
Expand Down Expand Up @@ -86,7 +89,6 @@ export class SearchV2Store {
/**
* Execute a search with the current tokens.
*
* @param limit
* @param resetPagination - By default execute a fresh search. When paginating,
* we don't want to reset the pagination state.
*/
Expand Down Expand Up @@ -146,6 +148,14 @@ export class SearchV2Store {
this.search(100, resetPagination);
};

/**
* Replace the current search with a new one.
*/
setSearch = (searchStr: string[]) => {
this.setTokens([]);
this.addTokens(searchStr);
};

@computed
get searchTokens() {
return this.tagSeachStore.searchTokens;
Expand Down
8 changes: 3 additions & 5 deletions src/views/documents/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useContext } from "react";
import { observer } from "mobx-react-lite";
import { Heading, Paragraph, Pane } from "evergreen-ui";
import { JournalsStoreContext } from "../../hooks/useJournalsLoader";

import { JournalsStoreContext } from "../../hooks/useJournalsLoader";
import { SearchV2Store } from "./SearchStore";
import { DocumentItem } from "./DocumentItem";
import { useNavigate } from "react-router-dom";
Expand All @@ -25,11 +25,9 @@ function DocumentsContainer(props: { store: SearchV2Store }) {

// When hitting "back" from an edit note, the search state is maintained.
// When navigating to other pages (preferences) and back, the search
// state needs reset. This resets the state in that case. This is
// not the correct place to do this.
// state needs reset. This resets the state in that case.
if (!tokens.length) {
searchStore.setTokens([]);
searchStore.search();
searchStore.setSearch([]);
}
}, []);

Expand Down

0 comments on commit 5f4186a

Please sign in to comment.