#90 #89 - Recoil implementation + Search sorting fix

This commit is contained in:
Elio Struyf
2021-09-03 17:46:18 +02:00
parent b8dee7a5c9
commit 60caf743c6
29 changed files with 219 additions and 130 deletions

View File

@@ -20,7 +20,7 @@
"export const ${1:CollectionData}Selector = selector({",
" key: '${1:CollectionData}Selector',",
" get: ({get}) => {",
" return get(${2:CollectionIdState});",
" return get(${1:CollectionData}Atom);",
" }",
"});"
],

View File

@@ -19,5 +19,9 @@
}
],
"eliostruyf.writingstyleguide.terms.isDisabled": true,
"eliostruyf.writingstyleguide.biasFree.isDisabled": true
"eliostruyf.writingstyleguide.biasFree.isDisabled": true,
"exportall.config.folderListener": [
"/src/pagesView/state/atom",
"/src/pagesView/state/selectors"
]
}

View File

@@ -3,13 +3,10 @@ import { Spinner } from './Spinner';
import useMessages from '../hooks/useMessages';
import { Overview } from './Overview';
import { Header } from './Header';
import { Tab } from '../constants/Tab';
import { SortOption } from '../constants/SortOption';
import useDarkMode from '../../hooks/useDarkMode';
import usePages from '../hooks/usePages';
import { SponsorMsg } from './SponsorMsg';
import { WelcomeScreen } from './WelcomeScreen';
import { GroupOption } from '../constants/GroupOption';
export interface IDashboardProps {
showWelcome: boolean;
@@ -17,14 +14,7 @@ export interface IDashboardProps {
export const Dashboard: React.FunctionComponent<IDashboardProps> = ({showWelcome}: React.PropsWithChildren<IDashboardProps>) => {
const { loading, pages, settings } = useMessages();
const [ tab, setTab ] = React.useState(Tab.All);
const [ sorting, setSorting ] = React.useState(SortOption.LastModified);
const [ folder, setFolder ] = React.useState<string | null>(null);
const [ search, setSearch ] = React.useState<string | null>(null);
const [ tag, setTag ] = React.useState<string | null>(null);
const [ category, setCategory ] = React.useState<string | null>(null);
const [ group, setGroup ] = React.useState<GroupOption>(GroupOption.none);
const { pageItems } = usePages(pages, tab, sorting, folder, search, tag, category);
const { pageItems } = usePages(pages);
useDarkMode();
const pageFolders = [...new Set(pages.map(page => page.fmFolder))];
@@ -44,26 +34,13 @@ export const Dashboard: React.FunctionComponent<IDashboardProps> = ({showWelcome
return (
<main className={`h-full w-full`}>
<div className="flex flex-col h-full overflow-auto">
<Header currentTab={tab}
currentSorting={sorting}
folders={pageFolders}
crntFolder={folder}
totalPages={pageItems.length}
crntTag={tag}
crntCategory={category}
crntGroup={group}
switchTab={(tabId: Tab) => setTab(tabId)}
switchSorting={(sortId: SortOption) => setSorting(sortId)}
switchFolder={(folderName: string | null) => setFolder(folderName)}
switchTag={(tagId: string | null) => setTag(tagId)}
switchCategory={(categoryId: string | null) => setCategory(categoryId)}
switchGroup={(groupId: GroupOption) => setGroup(groupId)}
onSearch={(value: string | null) => setSearch(value)}
settings={settings}
/>
<Header
folders={pageFolders}
totalPages={pageItems.length}
settings={settings} />
<div className="w-full flex-grow max-w-7xl mx-auto py-6 px-4">
{ loading ? <Spinner /> : <Overview pages={pageItems} settings={settings} grouping={group} /> }
{ loading ? <Spinner /> : <Overview pages={pageItems} settings={settings} /> }
</div>
<SponsorMsg />

View File

@@ -1,16 +1,18 @@
import { Menu, Transition } from '@headlessui/react';
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { FolderAtom } from '../../state';
import { MenuButton, MenuItem, MenuItems } from '../Menu';
export interface IFoldersProps {
folders: string[];
crntFolder: string | null;
switchFolder: (group: string | null) => void;
}
const DEFAULT_TYPE = "All types";
export const Folders: React.FunctionComponent<IFoldersProps> = ({folders, crntFolder, switchFolder}: React.PropsWithChildren<IFoldersProps>) => {
export const Folders: React.FunctionComponent<IFoldersProps> = ({folders}: React.PropsWithChildren<IFoldersProps>) => {
const [ crntFolder, setCrntFolder ] = useRecoilState(FolderAtom);
if (folders.length <= 1) {
return null;
}
@@ -25,7 +27,7 @@ export const Folders: React.FunctionComponent<IFoldersProps> = ({folders, crntFo
title={DEFAULT_TYPE}
value={null}
isCurrent={!crntFolder}
onClick={switchFolder} />
onClick={(value) => setCrntFolder(value)} />
{folders.map((option) => (
<MenuItem
@@ -33,7 +35,7 @@ export const Folders: React.FunctionComponent<IFoldersProps> = ({folders, crntFo
title={option}
value={option}
isCurrent={option === crntFolder}
onClick={switchFolder} />
onClick={(value) => setCrntFolder(value)} />
))}
</MenuItems>
</Menu>

View File

@@ -1,12 +1,11 @@
import { Menu } from '@headlessui/react';
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { GroupOption } from '../../constants/GroupOption';
import { GroupingAtom } from '../../state';
import { MenuButton, MenuItem, MenuItems } from '../Menu';
export interface IGroupingProps {
group: GroupOption;
switchGroup: (group: GroupOption) => void;
}
export interface IGroupingProps {}
export const groupOptions = [
{ name: "None", id: GroupOption.none },
@@ -14,7 +13,9 @@ export const groupOptions = [
{ name: "Draft/Published", id: GroupOption.Draft },
];
export const Grouping: React.FunctionComponent<IGroupingProps> = ({group, switchGroup}: React.PropsWithChildren<IGroupingProps>) => {
export const Grouping: React.FunctionComponent<IGroupingProps> = ({}: React.PropsWithChildren<IGroupingProps>) => {
const [ group, setGroup ] = useRecoilState(GroupingAtom);
const crntGroup = groupOptions.find(x => x.id === group);
return (
@@ -29,7 +30,7 @@ export const Grouping: React.FunctionComponent<IGroupingProps> = ({group, switch
title={option.name}
value={option.id}
isCurrent={option.id === crntGroup?.id}
onClick={switchGroup} />
onClick={(value) => setGroup(value)} />
))}
</MenuItems>
</Menu>

View File

@@ -4,51 +4,29 @@ import { Searchbox } from './Searchbox';
import { Filter } from './Filter';
import { Folders } from './Folders';
import { Settings } from '../../models';
import { Tab } from '../../constants/Tab';
import { SortOption } from '../../constants/SortOption';
import { MessageHelper } from '../../../helpers/MessageHelper';
import { DashboardMessage } from '../../DashboardMessage';
import { Startup } from '../Startup';
import { Button } from '../Button';
import { Navigation } from '../Navigation';
import { Grouping } from '.';
import { GroupOption } from '../../constants/GroupOption';
import { ViewSwitch } from './ViewSwitch';
import { useRecoilState } from 'recoil';
import { CategoryAtom, TagAtom } from '../../state';
export interface IHeaderProps {
settings: Settings;
// Navigation
currentTab: Tab;
totalPages: number;
switchTab: (tabId: Tab) => void;
// Sorting
currentSorting: SortOption;
switchSorting: (sortId: SortOption) => void;
// Grouping
// Page folders
folders: string[];
crntFolder: string | null;
switchFolder: (folderName: string | null) => void;
// Searching
onSearch: (value: string | null) => void;
// Tags
crntTag: string | null;
switchTag: (tag: string | null) => void;
// Categories
crntCategory: string | null;
switchCategory: (category: string | null) => void;
// Grouping
crntGroup: GroupOption;
switchGroup: (groupId: GroupOption) => void;
}
export const Header: React.FunctionComponent<IHeaderProps> = ({currentTab, currentSorting, switchSorting, switchTab, totalPages, crntFolder, folders, switchFolder, onSearch, settings, switchTag, crntTag, switchCategory, crntCategory, crntGroup, switchGroup}: React.PropsWithChildren<IHeaderProps>) => {
export const Header: React.FunctionComponent<IHeaderProps> = ({totalPages, folders, settings }: React.PropsWithChildren<IHeaderProps>) => {
const [ crntTag, setCrntTag ] = useRecoilState(TagAtom);
const [ crntCategory, setCrntCategory ] = useRecoilState(CategoryAtom);
const createContent = () => {
MessageHelper.sendMessage(DashboardMessage.createContent);
@@ -57,7 +35,7 @@ export const Header: React.FunctionComponent<IHeaderProps> = ({currentTab, curre
return (
<div className={`w-full max-w-7xl mx-auto sticky top-0 z-40 bg-gray-100 dark:bg-vulcan-500`}>
<div className={`px-4 my-2 flex items-center justify-between`}>
<Searchbox onSearch={onSearch} />
<Searchbox />
<div className={`flex items-center space-x-4`}>
<Startup settings={settings} />
@@ -68,19 +46,19 @@ export const Header: React.FunctionComponent<IHeaderProps> = ({currentTab, curre
<div className="px-4 flex flex-col lg:flex-row items-center border-b border-gray-200 dark:border-whisper-600">
<div className={`w-full lg:w-auto`}>
<Navigation currentTab={currentTab} totalPages={totalPages} switchTab={switchTab} />
<Navigation totalPages={totalPages} />
</div>
<div className={`my-4 lg:my-0 w-full flex items-center justify-end space-x-4 lg:space-x-6 xl:space-x-8 order-first lg:order-last`}>
<Folders crntFolder={crntFolder} folders={folders} switchFolder={switchFolder} />
<Folders folders={folders} />
<Filter label={`Tag filter`} activeItem={crntTag} items={settings.tags} onClick={switchTag} />
<Filter label={`Tag filter`} activeItem={crntTag} items={settings.tags} onClick={(value) => setCrntTag(value)} />
<Filter label={`Category filter`} activeItem={crntCategory} items={settings.categories} onClick={switchCategory} />
<Filter label={`Category filter`} activeItem={crntCategory} items={settings.categories} onClick={(value) => setCrntCategory(value)} />
<Grouping group={crntGroup} switchGroup={switchGroup} />
<Grouping />
<Sorting currentSorting={currentSorting} switchSorting={switchSorting} />
<Sorting />
<ViewSwitch />
</div>

View File

@@ -1,13 +1,14 @@
import { FilterIcon, SearchIcon } from '@heroicons/react/solid';
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { useDebounce } from '../../../hooks/useDebounce';
import { SearchAtom } from '../../state';
export interface ISearchboxProps {
onSearch: (searchText: string) => void;
}
export interface ISearchboxProps {}
export const Searchbox: React.FunctionComponent<ISearchboxProps> = ({onSearch}: React.PropsWithChildren<ISearchboxProps>) => {
export const Searchbox: React.FunctionComponent<ISearchboxProps> = ({}: React.PropsWithChildren<ISearchboxProps>) => {
const [ value, setValue ] = React.useState('');
const [ , setDebounceValue ] = useRecoilState(SearchAtom);
const debounceSearch = useDebounce<string>(value, 500);
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
@@ -15,7 +16,7 @@ export const Searchbox: React.FunctionComponent<ISearchboxProps> = ({onSearch}:
};
React.useEffect(() => {
onSearch(debounceSearch);
setDebounceValue(debounceSearch);
}, [debounceSearch]);
return (

View File

@@ -1,13 +1,11 @@
import { Menu } from '@headlessui/react';
import * as React from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { SortOption } from '../../constants/SortOption';
import { SearchSelector, SortingAtom } from '../../state';
import { MenuButton, MenuItem, MenuItems } from '../Menu';
export interface ISortingProps {
currentSorting: SortOption;
switchSorting: (sortId: SortOption) => void;
}
export interface ISortingProps {}
export const sortOptions = [
{ name: "Last modified", id: SortOption.LastModified },
@@ -15,14 +13,16 @@ export const sortOptions = [
{ name: "By filename (desc)", id: SortOption.FileNameDesc },
];
export const Sorting: React.FunctionComponent<ISortingProps> = ({currentSorting, switchSorting}: React.PropsWithChildren<ISortingProps>) => {
export const Sorting: React.FunctionComponent<ISortingProps> = ({}: React.PropsWithChildren<ISortingProps>) => {
const [ crntSorting, setCrntSorting ] = useRecoilState(SortingAtom);
const searchValue = useRecoilValue(SearchSelector);
const crntSort = sortOptions.find(x => x.id === currentSorting);
const crntSort = sortOptions.find(x => x.id === crntSorting);
return (
<div className="flex items-center">
<Menu as="div" className="relative z-10 inline-block text-left">
<MenuButton label={`Sort by`} title={crntSort?.name || ""} />
<MenuButton label={`Sort by`} title={crntSort?.name || ""} disabled={!!searchValue} />
<MenuItems>
{sortOptions.map((option) => (
@@ -30,8 +30,8 @@ export const Sorting: React.FunctionComponent<ISortingProps> = ({currentSorting,
key={option.id}
title={option.name}
value={option.id}
isCurrent={option.id === currentSorting}
onClick={switchSorting} />
isCurrent={option.id === crntSorting}
onClick={(value) => setCrntSorting(value)} />
))}
</MenuItems>
</Menu>

View File

@@ -12,13 +12,6 @@ export interface IItemProps extends Page {}
export const Item: React.FunctionComponent<IItemProps> = ({ fmFilePath, date, title, draft, description, preview }: React.PropsWithChildren<IItemProps>) => {
const view = useRecoilValue(ViewSelector);
let className = '';
if (view === ViewType.Grid) {
className = `grid grid-cols-2 gap-x-4 gap-y-8 sm:grid-cols-3 sm:gap-x-6 lg:grid-cols-4 xl:gap-x-8`;
} else if (view === ViewType.List) {
className = `divide-y divide-vulcan-200`;
}
const openFile = () => {
MessageHelper.sendMessage(DashboardMessage.openFile, fmFilePath);

View File

@@ -5,13 +5,14 @@ import * as React from 'react';
export interface IMenuButtonProps {
label: string;
title: string;
disabled?: boolean;
}
export const MenuButton: React.FunctionComponent<IMenuButtonProps> = ({label, title}: React.PropsWithChildren<IMenuButtonProps>) => {
export const MenuButton: React.FunctionComponent<IMenuButtonProps> = ({label, title, disabled}: React.PropsWithChildren<IMenuButtonProps>) => {
return (
<div>
<div className={`${disabled ? 'opacity-50' : ''}`}>
<span className={`text-gray-500 dark:text-whisper-700 mr-2 font-medium`}>{label}:</span>
<Menu.Button className="group inline-flex justify-center text-sm font-medium text-vulcan-500 hover:text-vulcan-600 dark:text-whisper-500 dark:hover:text-whisper-600">
<Menu.Button disabled={disabled} className="group inline-flex justify-center text-sm font-medium text-vulcan-500 hover:text-vulcan-600 dark:text-whisper-500 dark:hover:text-whisper-600">
{title}
<ChevronDownIcon
className="flex-shrink-0 -mr-1 ml-1 h-5 w-5 text-gray-400 group-hover:text-gray-500 dark:text-whisper-600 dark:group-hover:text-whisper-700"

View File

@@ -1,10 +1,10 @@
import * as React from 'react';
import { useRecoilState } from 'recoil';
import { Tab } from '../constants/Tab';
import { TabAtom } from '../state';
export interface INavigationProps {
currentTab: Tab;
totalPages: number;
switchTab: (tabId: Tab) => void;
}
export const tabs = [
@@ -13,18 +13,19 @@ export const tabs = [
{ name: 'In draft', id: Tab.Draft }
];
export const Navigation: React.FunctionComponent<INavigationProps> = ({currentTab, totalPages, switchTab}: React.PropsWithChildren<INavigationProps>) => {
export const Navigation: React.FunctionComponent<INavigationProps> = ({totalPages}: React.PropsWithChildren<INavigationProps>) => {
const [ crntTab, setCrntTab ] = useRecoilState(TabAtom);
return (
<nav className="flex-1 -mb-px flex space-x-6 xl:space-x-8" aria-label="Tabs">
{tabs.map((tab) => (
<button
key={tab.name}
className={`${tab.id === currentTab ? `border-teal-900 dark:border-teal-300 text-teal-900 dark:text-teal-300` : `border-transparent text-gray-500 dark:text-whisper-600 hover:text-gray-700 dark:hover:text-whisper-700 hover:border-gray-300 dark:hover:border-whisper-500`} whitespace-nowrap py-2 px-1 border-b-2 font-medium text-sm`}
aria-current={tab.id === currentTab ? 'page' : undefined}
onClick={() => switchTab(tab.id)}
className={`${tab.id === crntTab ? `border-teal-900 dark:border-teal-300 text-teal-900 dark:text-teal-300` : `border-transparent text-gray-500 dark:text-whisper-600 hover:text-gray-700 dark:hover:text-whisper-700 hover:border-gray-300 dark:hover:border-whisper-500`} whitespace-nowrap py-2 px-1 border-b-2 font-medium text-sm`}
aria-current={tab.id === crntTab ? 'page' : undefined}
onClick={() => setCrntTab(tab.id)}
>
{tab.name}{(tab.id === currentTab && totalPages) ? ` (${totalPages})` : ''}
{tab.name}{(tab.id === crntTab && totalPages) ? ` (${totalPages})` : ''}
</button>
))}
</nav>

View File

@@ -1,23 +1,23 @@
import { Disclosure } from '@headlessui/react';
import { ChevronRightIcon } from '@heroicons/react/solid';
import * as React from 'react';
import { useRecoilValue } from 'recoil';
import { groupBy } from '../../helpers/GroupBy';
import { FrontMatterIcon } from '../../viewpanel/components/Icons/FrontMatterIcon';
import { GroupOption } from '../constants/GroupOption';
import { Page } from '../models/Page';
import { Settings } from '../models/Settings';
import { GroupingSelector } from '../state';
import { Item } from './Item';
import { List } from './List';
export interface IOverviewProps {
pages: Page[];
grouping: GroupOption;
pages: Page[];
settings: Settings;
}
export const Overview: React.FunctionComponent<IOverviewProps> = ({pages, settings, grouping}: React.PropsWithChildren<IOverviewProps>) => {
const [ open, setOpen ] = React.useState(true);
export const Overview: React.FunctionComponent<IOverviewProps> = ({pages, settings}: React.PropsWithChildren<IOverviewProps>) => {
const grouping = useRecoilValue(GroupingSelector);
if (!pages || !pages.length) {
return (
@@ -65,7 +65,7 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({pages, settin
<Disclosure.Panel>
<List>
{groupedPages[groupId].map((page: Page) => (
<Item key={page.slug} {...page} />
<Item key={`${page.slug}-${idx}`} {...page} />
))}
</List>
</Disclosure.Panel>
@@ -80,8 +80,8 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({pages, settin
return (
<List>
{pages.map(page => (
<Item key={page.slug} {...page} />
{pages.map((page, idx) => (
<Item key={`${page.slug}-${idx}`} {...page} />
))}
</List>
);

View File

@@ -3,18 +3,25 @@ import { SortOption } from '../constants/SortOption';
import { Tab } from '../constants/Tab';
import { Page } from '../models/Page';
import Fuse from 'fuse.js';
import { useRecoilValue } from 'recoil';
import { CategorySelector, FolderSelector, SearchSelector, SortingSelector, TabSelector, TagSelector } from '../state';
const fuseOptions: Fuse.IFuseOptions<Page> = {
keys: [
"title",
"slug",
"description",
"fmFileName"
{ name: 'title', weight: 0.8 },
{ name: 'slug', weight: 0.8 },
{ name: 'description', weight: 0.5 }
]
};
export default function usePages(pages: Page[], tab: Tab, sorting: SortOption, folder: string | null, search: string | null, tag: string | null, category: string | null) {
export default function usePages(pages: Page[]) {
const [ pageItems, setPageItems ] = useState<Page[]>([]);
const tab = useRecoilValue(TabSelector);
const sorting = useRecoilValue(SortingSelector);
const folder = useRecoilValue(FolderSelector);
const search = useRecoilValue(SearchSelector);
const tag = useRecoilValue(TagSelector);
const category = useRecoilValue(CategorySelector);
useEffect(() => {
// Check if search needs to be performed
@@ -26,7 +33,7 @@ export default function usePages(pages: Page[], tab: Tab, sorting: SortOption, f
}
// Filter the pages
let pagesToShow = searchedPages;
let pagesToShow: Page[] = Object.assign([], searchedPages);
if (tab === Tab.Published) {
pagesToShow = searchedPages.filter(page => !page.draft);
} else if (tab === Tab.Draft) {
@@ -36,13 +43,15 @@ export default function usePages(pages: Page[], tab: Tab, sorting: SortOption, f
}
// Sort the pages
let pagesSorted = pagesToShow;
if (sorting === SortOption.FileNameAsc) {
pagesSorted = pagesToShow.sort((a, b) => a.fmFileName.toLowerCase().localeCompare(b.fmFileName.toLowerCase()));
} else if (sorting === SortOption.FileNameDesc) {
pagesSorted = pagesToShow.sort((a, b) => b.fmFileName.toLowerCase().localeCompare(a.fmFileName.toLowerCase()));
} else {
pagesSorted = pagesToShow.sort((a, b) => b.fmModified - a.fmModified);
let pagesSorted: Page[] = Object.assign([], pagesToShow);
if (!search) {
if (sorting === SortOption.FileNameAsc) {
pagesSorted = pagesToShow.sort((a, b) => a.fmFileName.toLowerCase().localeCompare(b.fmFileName.toLowerCase()));
} else if (sorting === SortOption.FileNameDesc) {
pagesSorted = pagesToShow.sort((a, b) => b.fmFileName.toLowerCase().localeCompare(a.fmFileName.toLowerCase()));
} else {
pagesSorted = pagesToShow.sort((a, b) => b.fmModified - a.fmModified);
}
}
if (folder) {

View File

@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const CategoryAtom = atom<string | null>({
key: 'CategoryAtom',
default: ""
});

View File

@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const FolderAtom = atom<string | null>({
key: 'FolderAtom',
default: null
});

View File

@@ -0,0 +1,7 @@
import { atom } from 'recoil';
import { GroupOption } from '../../constants/GroupOption';
export const GroupingAtom = atom<GroupOption>({
key: 'GroupingAtom',
default: GroupOption.none
});

View File

@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const SearchAtom = atom<string>({
key: 'SearchAtom',
default: ""
});

View File

@@ -0,0 +1,7 @@
import { atom } from 'recoil';
import { SortOption } from '../../constants/SortOption';
export const SortingAtom = atom<SortOption>({
key: 'SortingAtom',
default: SortOption.LastModified
});

View File

@@ -0,0 +1,7 @@
import { atom } from 'recoil';
import { Tab } from '../../constants/Tab';
export const TabAtom = atom<Tab>({
key: 'TabAtom',
default: Tab.All
});

View File

@@ -0,0 +1,6 @@
import { atom } from 'recoil';
export const TagAtom = atom<string | null>({
key: 'TagAtom',
default: ""
});

View File

@@ -1 +1,8 @@
export * from './CategoryAtom';
export * from './FolderAtom';
export * from './GroupingAtom';
export * from './SearchAtom';
export * from './SortingAtom';
export * from './TabAtom';
export * from './TagAtom';
export * from './ViewAtom';

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { CategoryAtom } from '..';
export const CategorySelector = selector({
key: 'CategorySelector',
get: ({get}) => {
return get(CategoryAtom);
}
});

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { FolderAtom } from '..';
export const FolderSelector = selector({
key: 'FolderSelector',
get: ({get}) => {
return get(FolderAtom);
}
});

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { GroupingAtom } from '..';
export const GroupingSelector = selector({
key: 'GroupingSelector',
get: ({get}) => {
return get(GroupingAtom);
}
});

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { SearchAtom } from '..';
export const SearchSelector = selector({
key: 'SearchSelector',
get: ({get}) => {
return get(SearchAtom);
}
});

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { SortingAtom } from '..';
export const SortingSelector = selector({
key: 'SortingSelector',
get: ({get}) => {
return get(SortingAtom);
}
});

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { TabAtom } from '..';
export const TabSelector = selector({
key: 'TabSelector',
get: ({get}) => {
return get(TabAtom);
}
});

View File

@@ -0,0 +1,9 @@
import { selector } from 'recoil';
import { TagAtom } from '..';
export const TagSelector = selector({
key: 'TagSelector',
get: ({get}) => {
return get(TagAtom);
}
});

View File

@@ -1 +1,8 @@
export * from './CategorySelector';
export * from './FolderSelector';
export * from './GroupingSelector';
export * from './SearchSelector';
export * from './SortingSelector';
export * from './TabSelector';
export * from './TagSelector';
export * from './ViewSelector';