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",