diff --git a/app/components/Modal.js b/app/components/Modal.js
index 110320402..03b8518dc 100644
--- a/app/components/Modal.js
+++ b/app/components/Modal.js
@@ -3,6 +3,7 @@ import { observer } from "mobx-react";
import { CloseIcon, BackIcon } from "outline-icons";
import { transparentize } from "polished";
import * as React from "react";
+import { useTranslation } from "react-i18next";
import ReactModal from "react-modal";
import styled, { createGlobalStyle } from "styled-components";
import breakpoint from "styled-components-breakpoint";
@@ -65,6 +66,7 @@ const Modal = ({
onRequestClose,
...rest
}: Props) => {
+ const { t } = useTranslation();
if (!isOpen) return null;
return (
@@ -84,7 +86,7 @@ const Modal = ({
- Back
+ {t("Back")}
diff --git a/app/scenes/Search/components/CollectionFilter.js b/app/scenes/Search/components/CollectionFilter.js
index de7cad195..028a9c66f 100644
--- a/app/scenes/Search/components/CollectionFilter.js
+++ b/app/scenes/Search/components/CollectionFilter.js
@@ -1,39 +1,44 @@
// @flow
-import { observer, inject } from "mobx-react";
+import { observer } from "mobx-react";
import * as React from "react";
-import CollectionsStore from "stores/CollectionsStore";
+import { useTranslation } from "react-i18next";
import FilterOptions from "./FilterOptions";
+import useStores from "hooks/useStores";
-const defaultOption = {
- key: "",
- label: "Any collection",
-};
-
-type Props = {
- collections: CollectionsStore,
+type Props = {|
collectionId: ?string,
onSelect: (key: ?string) => void,
-};
+|};
-@observer
-class CollectionFilter extends React.Component {
- render() {
- const { onSelect, collectionId, collections } = this.props;
+function CollectionFilter(props: Props) {
+ const { t } = useTranslation();
+ const { collections } = useStores();
+ const { onSelect, collectionId } = props;
+
+ const options = React.useMemo(() => {
const collectionOptions = collections.orderedData.map((user) => ({
key: user.id,
label: user.name,
}));
- return (
-
- );
- }
+ return [
+ {
+ key: "",
+ label: t("Any collection"),
+ },
+ ...collectionOptions,
+ ];
+ }, [collections.orderedData, t]);
+
+ return (
+
+ );
}
-export default inject("collections")(CollectionFilter);
+export default observer(CollectionFilter);
diff --git a/app/scenes/Search/components/DateFilter.js b/app/scenes/Search/components/DateFilter.js
index f8fafff12..f4c477738 100644
--- a/app/scenes/Search/components/DateFilter.js
+++ b/app/scenes/Search/components/DateFilter.js
@@ -1,27 +1,33 @@
// @flow
import * as React from "react";
+import { useTranslation } from "react-i18next";
import FilterOptions from "./FilterOptions";
-const options = [
- { key: "", label: "Any time" },
- { key: "day", label: "Past day" },
- { key: "week", label: "Past week" },
- { key: "month", label: "Past month" },
- { key: "year", label: "Past year" },
-];
-
-type Props = {
+type Props = {|
dateFilter: ?string,
onSelect: (key: ?string) => void,
-};
+|};
const DateFilter = ({ dateFilter, onSelect }: Props) => {
+ const { t } = useTranslation();
+
+ const options = React.useMemo(
+ () => [
+ { key: "", label: t("Any time") },
+ { key: "day", label: t("Past day") },
+ { key: "week", label: t("Past week") },
+ { key: "month", label: t("Past month") },
+ { key: "year", label: t("Past year") },
+ ],
+ [t]
+ );
+
return (
);
};
diff --git a/app/scenes/Search/components/FilterOption.js b/app/scenes/Search/components/FilterOption.js
index 45265d55e..b46637e58 100644
--- a/app/scenes/Search/components/FilterOption.js
+++ b/app/scenes/Search/components/FilterOption.js
@@ -34,7 +34,9 @@ const FilterOption = ({ label, note, onSelect, active, ...rest }: Props) => {
};
const Description = styled(HelpText)`
+ margin-top: 2px;
margin-bottom: 0;
+ line-height: 1.2em;
`;
const Checkmark = styled(CheckmarkIcon)`
diff --git a/app/scenes/Search/components/StatusFilter.js b/app/scenes/Search/components/StatusFilter.js
index 7685d69ed..8c6aaf627 100644
--- a/app/scenes/Search/components/StatusFilter.js
+++ b/app/scenes/Search/components/StatusFilter.js
@@ -1,32 +1,38 @@
// @flow
import * as React from "react";
+import { useTranslation } from "react-i18next";
import FilterOptions from "./FilterOptions";
-const options = [
- {
- key: "",
- label: "Active documents",
- note: "Documents in collections you are able to access",
- },
- {
- key: "true",
- label: "All documents",
- note: "Include documents that are in the archive",
- },
-];
-
-type Props = {
- includeArchived: boolean,
+type Props = {|
+ includeArchived?: boolean,
onSelect: (key: ?string) => void,
-};
+|};
const StatusFilter = ({ includeArchived, onSelect }: Props) => {
+ const { t } = useTranslation();
+
+ const options = React.useMemo(
+ () => [
+ {
+ key: "",
+ label: t("Active documents"),
+ note: t("Documents in collections you are able to access"),
+ },
+ {
+ key: "true",
+ label: t("All documents"),
+ note: t("Include documents that are in the archive"),
+ },
+ ],
+ [t]
+ );
+
return (
);
};
diff --git a/app/scenes/Search/components/UserFilter.js b/app/scenes/Search/components/UserFilter.js
index 6f9c42e4f..f96997e4c 100644
--- a/app/scenes/Search/components/UserFilter.js
+++ b/app/scenes/Search/components/UserFilter.js
@@ -1,43 +1,48 @@
// @flow
-import { observer, inject } from "mobx-react";
+import { observer } from "mobx-react";
import * as React from "react";
-import UsersStore from "stores/UsersStore";
+import { useTranslation } from "react-i18next";
import FilterOptions from "./FilterOptions";
+import useStores from "hooks/useStores";
-const defaultOption = {
- key: "",
- label: "Any author",
-};
-
-type Props = {
- users: UsersStore,
+type Props = {|
userId: ?string,
onSelect: (key: ?string) => void,
-};
+|};
-@observer
-class UserFilter extends React.Component {
- componentDidMount() {
- this.props.users.fetchPage({ limit: 100 });
- }
+function UserFilter(props: Props) {
+ const { onSelect, userId } = props;
+ const { t } = useTranslation();
+ const { users } = useStores();
- render() {
- const { onSelect, userId, users } = this.props;
+ React.useEffect(() => {
+ users.fetchPage({ limit: 100 });
+ }, [users]);
+
+ const options = React.useMemo(() => {
const userOptions = users.all.map((user) => ({
key: user.id,
label: user.name,
}));
- return (
-
- );
- }
+ return [
+ {
+ key: "",
+ label: t("Any author"),
+ },
+ ...userOptions,
+ ];
+ }, [users.all, t]);
+
+ return (
+
+ );
}
-export default inject("users")(UserFilter);
+export default observer(UserFilter);
diff --git a/shared/i18n/locales/en_US/translation.json b/shared/i18n/locales/en_US/translation.json
index cf7d909c1..f3cbeb00a 100644
--- a/shared/i18n/locales/en_US/translation.json
+++ b/shared/i18n/locales/en_US/translation.json
@@ -90,6 +90,7 @@
"Change Language": "Change Language",
"Dismiss": "Dismiss",
"Keyboard shortcuts": "Keyboard shortcuts",
+ "Back": "Back",
"New collection": "New collection",
"Collections": "Collections",
"Untitled": "Untitled",
@@ -301,6 +302,18 @@
"Blockquote": "Blockquote",
"Horizontal divider": "Horizontal divider",
"Inline code": "Inline code",
+ "Any collection": "Any collection",
+ "Any time": "Any time",
+ "Past day": "Past day",
+ "Past week": "Past week",
+ "Past month": "Past month",
+ "Past year": "Past year",
+ "Active documents": "Active documents",
+ "Documents in collections you are able to access": "Documents in collections you are able to access",
+ "All documents": "All documents",
+ "Include documents that are in the archive": "Include documents that are in the archive",
+ "Any author": "Any author",
+ "Author": "Author",
"Not Found": "Not Found",
"We were unable to find the page you’re looking for.": "We were unable to find the page you’re looking for.",
"Use the {{ meta }}+K shortcut to search from anywhere in your knowledge base": "Use the {{ meta }}+K shortcut to search from anywhere in your knowledge base",