mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-21 05:59:35 +01:00
web: add support for sorting in search
This commit is contained in:
@@ -28,8 +28,7 @@ import {
|
|||||||
SortDesc,
|
SortDesc,
|
||||||
DetailedView,
|
DetailedView,
|
||||||
CompactView,
|
CompactView,
|
||||||
Icon,
|
Icon
|
||||||
Loading
|
|
||||||
} from "../icons";
|
} from "../icons";
|
||||||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { Button, Flex, Text } from "@theme-ui/components";
|
import { Button, Flex, Text } from "@theme-ui/components";
|
||||||
@@ -45,6 +44,7 @@ import {
|
|||||||
GroupingKey
|
GroupingKey
|
||||||
} from "@notesnook/core";
|
} from "@notesnook/core";
|
||||||
import { strings } from "@notesnook/intl";
|
import { strings } from "@notesnook/intl";
|
||||||
|
import { useStore as useSearchStore } from "../../stores/search-store";
|
||||||
|
|
||||||
const groupByToTitleMap = {
|
const groupByToTitleMap = {
|
||||||
none: "None",
|
none: "None",
|
||||||
@@ -60,12 +60,13 @@ type GroupingMenuOptions = {
|
|||||||
parentKey: keyof GroupOptions;
|
parentKey: keyof GroupOptions;
|
||||||
groupingKey: GroupingKey;
|
groupingKey: GroupingKey;
|
||||||
refresh: () => void;
|
refresh: () => void;
|
||||||
|
isSearching?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const groupByMenu: (options: GroupingMenuOptions) => MenuItem | null = (
|
const groupByMenu: (options: GroupingMenuOptions) => MenuItem | null = (
|
||||||
options
|
options
|
||||||
) =>
|
) =>
|
||||||
options.groupingKey === "reminders"
|
options.groupingKey === "reminders" || options.isSearching
|
||||||
? null
|
? null
|
||||||
: {
|
: {
|
||||||
type: "button",
|
type: "button",
|
||||||
@@ -105,6 +106,8 @@ const orderByMenu: (options: GroupingMenuOptions) => MenuItem = (options) => ({
|
|||||||
? strings.aToZ()
|
? strings.aToZ()
|
||||||
: options.groupOptions.sortBy === "dueDate"
|
: options.groupOptions.sortBy === "dueDate"
|
||||||
? strings.earliestFirst()
|
? strings.earliestFirst()
|
||||||
|
: options.groupOptions.sortBy === "relevance"
|
||||||
|
? strings.leastRelevantFirst()
|
||||||
: strings.oldestToNewest()
|
: strings.oldestToNewest()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -114,6 +117,8 @@ const orderByMenu: (options: GroupingMenuOptions) => MenuItem = (options) => ({
|
|||||||
? strings.zToA()
|
? strings.zToA()
|
||||||
: options.groupOptions.sortBy === "dueDate"
|
: options.groupOptions.sortBy === "dueDate"
|
||||||
? strings.latestFirst()
|
? strings.latestFirst()
|
||||||
|
: options.groupOptions.sortBy === "relevance"
|
||||||
|
? strings.mostRelevantFirst()
|
||||||
: strings.newestToOldest()
|
: strings.newestToOldest()
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
@@ -156,6 +161,11 @@ const sortByMenu: (options: GroupingMenuOptions) => MenuItem = (options) => ({
|
|||||||
{
|
{
|
||||||
key: "title",
|
key: "title",
|
||||||
title: strings.sortByStrings.title()
|
title: strings.sortByStrings.title()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "relevance",
|
||||||
|
title: strings.sortByStrings.relevance(),
|
||||||
|
isHidden: options.groupingKey !== "search"
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
@@ -198,6 +208,8 @@ async function changeGroupOptions(
|
|||||||
: groupOptions.sortBy;
|
: groupOptions.sortBy;
|
||||||
}
|
}
|
||||||
await db.settings.setGroupOptions(options.groupingKey, groupOptions);
|
await db.settings.setGroupOptions(options.groupingKey, groupOptions);
|
||||||
|
if (options.groupingKey === "search")
|
||||||
|
useSearchStore.setState({ sortOptions: groupOptions });
|
||||||
options.refresh();
|
options.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +221,7 @@ function map(
|
|||||||
item.isChecked = options.groupOptions[options.parentKey] === item.key;
|
item.isChecked = options.groupOptions[options.parentKey] === item.key;
|
||||||
item.onClick = () => changeGroupOptions(options, item);
|
item.onClick = () => changeGroupOptions(options, item);
|
||||||
return { ...item, type: "button" };
|
return { ...item, type: "button" };
|
||||||
}, []);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupHeaderProps = {
|
type GroupHeaderProps = {
|
||||||
@@ -222,6 +234,7 @@ type GroupHeaderProps = {
|
|||||||
refresh: () => void;
|
refresh: () => void;
|
||||||
onSelectGroup: () => void;
|
onSelectGroup: () => void;
|
||||||
isFocused: boolean;
|
isFocused: boolean;
|
||||||
|
isSearching?: boolean;
|
||||||
};
|
};
|
||||||
function GroupHeader(props: GroupHeaderProps) {
|
function GroupHeader(props: GroupHeaderProps) {
|
||||||
const {
|
const {
|
||||||
@@ -232,10 +245,11 @@ function GroupHeader(props: GroupHeaderProps) {
|
|||||||
groupingKey,
|
groupingKey,
|
||||||
refresh,
|
refresh,
|
||||||
onSelectGroup,
|
onSelectGroup,
|
||||||
isFocused
|
isFocused,
|
||||||
|
isSearching
|
||||||
} = props;
|
} = props;
|
||||||
const [groupOptions, setGroupOptions] = useState(
|
const [groupOptions, setGroupOptions] = useState(
|
||||||
db.settings.getGroupOptions(groupingKey)
|
db.settings.getGroupOptions(isSearching ? "search" : groupingKey)
|
||||||
);
|
);
|
||||||
const groupHeaderRef = useRef<HTMLDivElement>(null);
|
const groupHeaderRef = useRef<HTMLDivElement>(null);
|
||||||
const { openMenu, target } = useMenuTrigger();
|
const { openMenu, target } = useMenuTrigger();
|
||||||
@@ -270,21 +284,15 @@ function GroupHeader(props: GroupHeaderProps) {
|
|||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
ref={groupHeaderRef}
|
ref={groupHeaderRef}
|
||||||
onClick={(e) => {
|
onClick={async (e) => {
|
||||||
if (e.ctrlKey) {
|
if (e.ctrlKey) {
|
||||||
onSelectGroup();
|
onSelectGroup();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
const items: MenuItem[] = [
|
const groupItems = await groups();
|
||||||
{
|
const items: MenuItem[] = groupItems.map(({ group, index }) => {
|
||||||
key: "groups",
|
|
||||||
type: "lazy-loader",
|
|
||||||
loader: <Loading sx={{ my: 2 }} />,
|
|
||||||
async items() {
|
|
||||||
const items = await groups();
|
|
||||||
return items.map(({ group, index }) => {
|
|
||||||
const groupTitle = group.title.toString();
|
const groupTitle = group.title.toString();
|
||||||
return {
|
return {
|
||||||
type: "button",
|
type: "button",
|
||||||
@@ -294,9 +302,7 @@ function GroupHeader(props: GroupHeaderProps) {
|
|||||||
checked: group.title === title
|
checked: group.title === title
|
||||||
} as MenuItem;
|
} as MenuItem;
|
||||||
});
|
});
|
||||||
}
|
if (!items.length) return;
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
openMenu(items, {
|
openMenu(items, {
|
||||||
title: strings.jumpToGroup(),
|
title: strings.jumpToGroup(),
|
||||||
@@ -352,13 +358,16 @@ function GroupHeader(props: GroupHeaderProps) {
|
|||||||
groupByToTitleMap[groupOptions.groupBy || "default"]
|
groupByToTitleMap[groupOptions.groupBy || "default"]
|
||||||
}`}
|
}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const groupOptions = db.settings!.getGroupOptions(groupingKey);
|
const groupOptions = db.settings.getGroupOptions(
|
||||||
|
isSearching ? "search" : groupingKey
|
||||||
|
);
|
||||||
setGroupOptions(groupOptions);
|
setGroupOptions(groupOptions);
|
||||||
|
|
||||||
const menuOptions: Omit<GroupingMenuOptions, "parentKey"> = {
|
const menuOptions: Omit<GroupingMenuOptions, "parentKey"> = {
|
||||||
groupingKey,
|
groupingKey: isSearching ? "search" : groupingKey,
|
||||||
groupOptions,
|
groupOptions,
|
||||||
refresh
|
refresh,
|
||||||
|
isSearching
|
||||||
};
|
};
|
||||||
const groupBy = groupByMenu({
|
const groupBy = groupByMenu({
|
||||||
...menuOptions,
|
...menuOptions,
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ type ListContainerProps = {
|
|||||||
header?: JSX.Element;
|
header?: JSX.Element;
|
||||||
placeholder: JSX.Element;
|
placeholder: JSX.Element;
|
||||||
isLoading?: boolean;
|
isLoading?: boolean;
|
||||||
|
isSearching?: boolean;
|
||||||
onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;
|
onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;
|
||||||
button?: {
|
button?: {
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
@@ -91,7 +92,8 @@ function ListContainer(props: ListContainerProps) {
|
|||||||
button,
|
button,
|
||||||
compact,
|
compact,
|
||||||
sx,
|
sx,
|
||||||
Scroller
|
Scroller,
|
||||||
|
isSearching
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const [focusedGroupIndex, setFocusedGroupIndex] = useState(-1);
|
const [focusedGroupIndex, setFocusedGroupIndex] = useState(-1);
|
||||||
@@ -243,11 +245,14 @@ function ListContainer(props: ListContainerProps) {
|
|||||||
focusGroup: setFocusedGroupIndex,
|
focusGroup: setFocusedGroupIndex,
|
||||||
context,
|
context,
|
||||||
compact,
|
compact,
|
||||||
onMouseUp
|
onMouseUp,
|
||||||
|
isSearching
|
||||||
}}
|
}}
|
||||||
itemContent={(index, _data, context) => (
|
itemContent={(index, _data, context) =>
|
||||||
|
context ? (
|
||||||
<ItemRenderer context={context} index={index} />
|
<ItemRenderer context={context} index={index} />
|
||||||
)}
|
) : null
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
</>
|
</>
|
||||||
@@ -293,6 +298,7 @@ type ListContext = {
|
|||||||
focusGroup: (index: number) => void;
|
focusGroup: (index: number) => void;
|
||||||
context?: Context;
|
context?: Context;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
|
isSearching?: boolean;
|
||||||
|
|
||||||
onMouseUp: (e: MouseEvent, itemIndex: number) => void;
|
onMouseUp: (e: MouseEvent, itemIndex: number) => void;
|
||||||
};
|
};
|
||||||
@@ -312,8 +318,10 @@ function ItemRenderer({
|
|||||||
selectItems,
|
selectItems,
|
||||||
scrollToIndex,
|
scrollToIndex,
|
||||||
context: itemContext,
|
context: itemContext,
|
||||||
compact
|
compact,
|
||||||
|
isSearching
|
||||||
} = context;
|
} = context;
|
||||||
|
|
||||||
const resolvedItem = useResolvedItem({ index, items });
|
const resolvedItem = useResolvedItem({ index, items });
|
||||||
if (!resolvedItem || !resolvedItem.item) {
|
if (!resolvedItem || !resolvedItem.item) {
|
||||||
const placeholderData = getListItemPlaceholderData(group, compact);
|
const placeholderData = getListItemPlaceholderData(group, compact);
|
||||||
@@ -351,6 +359,7 @@ function ItemRenderer({
|
|||||||
{resolvedItem.group && group ? (
|
{resolvedItem.group && group ? (
|
||||||
<GroupHeader
|
<GroupHeader
|
||||||
groupingKey={group}
|
groupingKey={group}
|
||||||
|
isSearching={isSearching}
|
||||||
refresh={refresh}
|
refresh={refresh}
|
||||||
title={resolvedItem.group.title}
|
title={resolvedItem.group.title}
|
||||||
isFocused={index === focusedGroupIndex}
|
isFocused={index === focusedGroupIndex}
|
||||||
|
|||||||
@@ -18,25 +18,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
*/
|
*/
|
||||||
import { DependencyList, useEffect, useState } from "react";
|
import { DependencyList, useEffect, useState } from "react";
|
||||||
import { useStore as useSearchStore } from "../stores/search-store";
|
import { useStore as useSearchStore } from "../stores/search-store";
|
||||||
import { VirtualizedGrouping } from "@notesnook/core";
|
import { SortOptions, VirtualizedGrouping } from "@notesnook/core";
|
||||||
|
import { db } from "../common/db";
|
||||||
|
|
||||||
export function useSearch<T>(
|
export function useSearch<T>(
|
||||||
type: "notes" | "notebooks" | "notebook" | "reminders" | "trash" | "tags",
|
type: "notes" | "notebooks" | "notebook" | "reminders" | "trash" | "tags",
|
||||||
lookup: (query: string) => Promise<VirtualizedGrouping<T>> | undefined,
|
lookup: (
|
||||||
|
query: string,
|
||||||
|
sortOptions?: SortOptions
|
||||||
|
) => Promise<VirtualizedGrouping<T> | undefined>,
|
||||||
deps: DependencyList = []
|
deps: DependencyList = []
|
||||||
) {
|
) {
|
||||||
const isSearching = useSearchStore((store) => store.isSearching);
|
const isSearching = useSearchStore((store) => store.isSearching);
|
||||||
const query = useSearchStore((store) => store.query);
|
const query = useSearchStore((store) => store.query);
|
||||||
const searchType = useSearchStore((store) => store.searchType);
|
const searchType = useSearchStore((store) => store.searchType);
|
||||||
|
const sortOptions = useSearchStore((store) => store.sortOptions);
|
||||||
const [filteredItems, setFilteredItems] = useState<VirtualizedGrouping<T>>();
|
const [filteredItems, setFilteredItems] = useState<VirtualizedGrouping<T>>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async function () {
|
|
||||||
if (!query || !isSearching) return setFilteredItems(undefined);
|
if (!query || !isSearching) return setFilteredItems(undefined);
|
||||||
if (searchType !== type) return;
|
if (searchType !== type) return;
|
||||||
setFilteredItems(await lookup(query));
|
|
||||||
})();
|
lookup(query, sortOptions || db.settings.getGroupOptions("search")).then(
|
||||||
}, [isSearching, query, searchType, type, ...deps]);
|
(items) => setFilteredItems(items)
|
||||||
|
);
|
||||||
|
}, [isSearching, query, searchType, type, sortOptions, ...deps]);
|
||||||
|
|
||||||
return filteredItems;
|
return filteredItems;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,10 @@ export const useTip = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const tips: Tip[] = [
|
const tips: Tip[] = [
|
||||||
|
{
|
||||||
|
text: `Wrap a query in double quotes to search for an exact match.`,
|
||||||
|
contexts: ["search"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: "Hold Ctrl/Cmd & click on multiple items to select them.",
|
text: "Hold Ctrl/Cmd & click on multiple items to select them.",
|
||||||
contexts: ["notes", "notebooks", "tags"]
|
contexts: ["notes", "notebooks", "tags"]
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { SortOptions } from "@notesnook/core";
|
||||||
import createStore from "../common/store";
|
import createStore from "../common/store";
|
||||||
import BaseStore from "./index";
|
import BaseStore from "./index";
|
||||||
|
|
||||||
@@ -24,9 +25,15 @@ class SearchStore extends BaseStore<SearchStore> {
|
|||||||
isSearching = false;
|
isSearching = false;
|
||||||
query?: string;
|
query?: string;
|
||||||
searchType?: string;
|
searchType?: string;
|
||||||
|
sortOptions?: SortOptions;
|
||||||
|
|
||||||
resetSearch = () => {
|
resetSearch = () => {
|
||||||
this.set({ isSearching: false, query: undefined, searchType: undefined });
|
this.set({
|
||||||
|
isSearching: false,
|
||||||
|
query: undefined,
|
||||||
|
searchType: undefined,
|
||||||
|
sortOptions: undefined
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,9 @@ function Home() {
|
|||||||
const setContext = useStore((store) => store.setContext);
|
const setContext = useStore((store) => store.setContext);
|
||||||
const filteredItems = useSearch(
|
const filteredItems = useSearch(
|
||||||
"notes",
|
"notes",
|
||||||
(query) => {
|
async (query, sortOptions) => {
|
||||||
if (useStore.getState().context) return;
|
if (useStore.getState().context) return;
|
||||||
return db.lookup.notes(query).sorted();
|
return await db.lookup.notes(query).sorted(sortOptions);
|
||||||
},
|
},
|
||||||
[notes]
|
[notes]
|
||||||
);
|
);
|
||||||
@@ -72,7 +72,8 @@ function Home() {
|
|||||||
compact={isCompact}
|
compact={isCompact}
|
||||||
refresh={refresh}
|
refresh={refresh}
|
||||||
items={filteredItems || notes}
|
items={filteredItems || notes}
|
||||||
placeholder={<Placeholder context="notes" />}
|
isSearching={!!filteredItems}
|
||||||
|
placeholder={<Placeholder context={filteredItems ? "search" : "notes"} />}
|
||||||
button={{
|
button={{
|
||||||
onClick: () => useEditorStore.getState().newSession()
|
onClick: () => useEditorStore.getState().newSession()
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ function Notes(props: NotesProps) {
|
|||||||
const isCompact = useNotesStore((store) => store.viewMode === "compact");
|
const isCompact = useNotesStore((store) => store.viewMode === "compact");
|
||||||
const filteredItems = useSearch(
|
const filteredItems = useSearch(
|
||||||
context?.type === "notebook" ? "notebook" : "notes",
|
context?.type === "notebook" ? "notebook" : "notes",
|
||||||
(query) => {
|
async (query, sortOptions) => {
|
||||||
if (!context || !contextNotes) return;
|
if (!context || !contextNotes) return;
|
||||||
const notes = notesFromContext(context);
|
const notes = notesFromContext(context);
|
||||||
return db.lookup.notes(query, notes).sorted();
|
return await db.lookup.notes(query, notes).sorted(sortOptions);
|
||||||
},
|
},
|
||||||
[context, contextNotes]
|
[context, contextNotes]
|
||||||
);
|
);
|
||||||
@@ -58,6 +58,7 @@ function Notes(props: NotesProps) {
|
|||||||
type={type}
|
type={type}
|
||||||
group={type}
|
group={type}
|
||||||
refresh={refreshContext}
|
refresh={refreshContext}
|
||||||
|
isSearching={!!filteredItems}
|
||||||
compact={isCompact}
|
compact={isCompact}
|
||||||
context={context}
|
context={context}
|
||||||
items={filteredItems || contextNotes}
|
items={filteredItems || contextNotes}
|
||||||
@@ -65,7 +66,9 @@ function Notes(props: NotesProps) {
|
|||||||
placeholder={
|
placeholder={
|
||||||
<Placeholder
|
<Placeholder
|
||||||
context={
|
context={
|
||||||
context.type === "favorite"
|
filteredItems
|
||||||
|
? "search"
|
||||||
|
: context.type === "favorite"
|
||||||
? "favorites"
|
? "favorites"
|
||||||
: context.type === "archive"
|
: context.type === "archive"
|
||||||
? "archive"
|
? "archive"
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ function Reminders() {
|
|||||||
useNavigate("reminders", () => store.refresh());
|
useNavigate("reminders", () => store.refresh());
|
||||||
const reminders = useStore((state) => state.reminders);
|
const reminders = useStore((state) => state.reminders);
|
||||||
const refresh = useStore((state) => state.refresh);
|
const refresh = useStore((state) => state.refresh);
|
||||||
const filteredItems = useSearch("reminders", (query) =>
|
const filteredItems = useSearch("reminders", (query, sortOptions) =>
|
||||||
db.lookup.reminders(query).sorted()
|
db.lookup.reminders(query).sorted(sortOptions)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!reminders) return <ListLoader />;
|
if (!reminders) return <ListLoader />;
|
||||||
@@ -42,7 +42,10 @@ function Reminders() {
|
|||||||
group="reminders"
|
group="reminders"
|
||||||
refresh={refresh}
|
refresh={refresh}
|
||||||
items={filteredItems || reminders}
|
items={filteredItems || reminders}
|
||||||
placeholder={<Placeholder context="reminders" />}
|
isSearching={!!filteredItems}
|
||||||
|
placeholder={
|
||||||
|
<Placeholder context={filteredItems ? "search" : "reminders"} />
|
||||||
|
}
|
||||||
button={{
|
button={{
|
||||||
onClick: () => hashNavigate("/reminders/create")
|
onClick: () => hashNavigate("/reminders/create")
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ function Trash() {
|
|||||||
const items = useStore((store) => store.trash);
|
const items = useStore((store) => store.trash);
|
||||||
const refresh = useStore((store) => store.refresh);
|
const refresh = useStore((store) => store.refresh);
|
||||||
const clearTrash = useStore((store) => store.clear);
|
const clearTrash = useStore((store) => store.clear);
|
||||||
const filteredItems = useSearch("trash", (query) =>
|
const filteredItems = useSearch("trash", (query, sortOptions) =>
|
||||||
db.lookup.trash(query).sorted()
|
db.lookup.trash(query).sorted(sortOptions)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!items) return <ListLoader />;
|
if (!items) return <ListLoader />;
|
||||||
@@ -43,7 +43,8 @@ function Trash() {
|
|||||||
type="trash"
|
type="trash"
|
||||||
group="trash"
|
group="trash"
|
||||||
refresh={refresh}
|
refresh={refresh}
|
||||||
placeholder={<Placeholder context="trash" />}
|
isSearching={!!filteredItems}
|
||||||
|
placeholder={<Placeholder context={filteredItems ? "search" : "trash"} />}
|
||||||
items={filteredItems || items}
|
items={filteredItems || items}
|
||||||
button={{
|
button={{
|
||||||
onClick: function () {
|
onClick: function () {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -636,6 +636,8 @@ $headline$: Use starting line of the note as title.`,
|
|||||||
newOld: () => t`New - old`,
|
newOld: () => t`New - old`,
|
||||||
latestFirst: () => t`Latest first`,
|
latestFirst: () => t`Latest first`,
|
||||||
earliestFirst: () => t`Earliest first`,
|
earliestFirst: () => t`Earliest first`,
|
||||||
|
mostRelevantFirst: () => t`Most relevant first`,
|
||||||
|
leastRelevantFirst: () => t`Least relevant first`,
|
||||||
aToZ: () => t`A to Z`,
|
aToZ: () => t`A to Z`,
|
||||||
zToA: () => t`Z to A`,
|
zToA: () => t`Z to A`,
|
||||||
title: () => t`Title`,
|
title: () => t`Title`,
|
||||||
@@ -645,7 +647,8 @@ $headline$: Use starting line of the note as title.`,
|
|||||||
dateCreated: () => t`Date created`,
|
dateCreated: () => t`Date created`,
|
||||||
title: () => t`Title`,
|
title: () => t`Title`,
|
||||||
dueDate: () => t`Due date`,
|
dueDate: () => t`Due date`,
|
||||||
dateDeleted: () => t`Date deleted`
|
dateDeleted: () => t`Date deleted`,
|
||||||
|
relevance: () => t`Relevance`
|
||||||
},
|
},
|
||||||
groupByStrings: {
|
groupByStrings: {
|
||||||
default: () => t`Default`,
|
default: () => t`Default`,
|
||||||
|
|||||||
Reference in New Issue
Block a user