diff --git a/gradle/changelog/search_parse_error.yaml b/gradle/changelog/search_parse_error.yaml new file mode 100644 index 0000000000..62da7080dd --- /dev/null +++ b/gradle/changelog/search_parse_error.yaml @@ -0,0 +1,2 @@ +- type: Fixed + description: Error message for parse error on search result page ([#1768](https://github.com/scm-manager/scm-manager/pull/1768)) diff --git a/scm-ui/ui-webapp/src/containers/OmniSearch.tsx b/scm-ui/ui-webapp/src/containers/OmniSearch.tsx index e6f0bca5d5..0972ce97d3 100644 --- a/scm-ui/ui-webapp/src/containers/OmniSearch.tsx +++ b/scm-ui/ui-webapp/src/containers/OmniSearch.tsx @@ -24,21 +24,14 @@ import React, { FC, KeyboardEvent as ReactKeyboardEvent, MouseEvent, useCallback, useEffect, useState } from "react"; import { Hit, Links, ValueHitField } from "@scm-manager/ui-types"; import styled from "styled-components"; -import { BackendError, useSearch } from "@scm-manager/ui-api"; +import { useSearch } from "@scm-manager/ui-api"; import classNames from "classnames"; import { Link, useHistory, useLocation } from "react-router-dom"; import { useTranslation } from "react-i18next"; -import { - Button, - ErrorNotification, - HitProps, - LinkStyleButton, - Notification, - RepositoryAvatar, - useStringHitFieldValue, -} from "@scm-manager/ui-components"; +import { Button, HitProps, Notification, RepositoryAvatar, useStringHitFieldValue } from "@scm-manager/ui-components"; import SyntaxHelp from "../search/SyntaxHelp"; import SyntaxModal from "../search/SyntaxModal"; +import SearchErrorNotification from "../search/SearchErrorNotification"; const Field = styled.div` margin-bottom: 0 !important; @@ -81,39 +74,6 @@ const EmptyHits: FC = () => { ); }; -type ErrorProps = { - error: Error; - showHelp: () => void; -}; - -const ParseErrorNotification: FC = ({ showHelp }) => { - const [t] = useTranslation("commons"); - return ( - - -

{t("search.quickSearch.parseError")}

- {t("search.quickSearch.parseErrorHelp")} -
-
- ); -}; - -const isBackendError = (error: Error | BackendError): error is BackendError => { - return (error as BackendError).errorCode !== undefined; -}; - -const SearchErrorNotification: FC = ({ error, showHelp }) => { - // 5VScek8Xp1 is the id of sonia.scm.search.QueryParseException - if (isBackendError(error) && error.errorCode === "5VScek8Xp1") { - return ; - } - return ( - - - - ); -}; - const ResultHeading = styled.h3` border-bottom: 1px solid lightgray; margin: 0 0.5rem; @@ -390,7 +350,11 @@ const OmniSearch: FC = () => { )} e.preventDefault()}> - {error ? : null} + {error ? ( + + + + ) : null} {!error && data ? ( = ({ selectedType, query }) => { const Search: FC = () => { const [t] = useTranslation(["commons", "plugins"]); + const [showHelp, setShowHelp] = useState(false); const { query, selectedType, page } = usePageParams(); const { data, isLoading, error } = useSearch(query, { type: selectedType, @@ -135,8 +138,9 @@ const Search: FC = () => { title={t("search.title")} subtitle={} loading={isLoading} - error={error} > + {showHelp ? setShowHelp(false)} /> : null} + setShowHelp(true)} /> {data ? ( diff --git a/scm-ui/ui-webapp/src/search/SearchErrorNotification.tsx b/scm-ui/ui-webapp/src/search/SearchErrorNotification.tsx new file mode 100644 index 0000000000..b81fe488e0 --- /dev/null +++ b/scm-ui/ui-webapp/src/search/SearchErrorNotification.tsx @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import React, { FC } from "react"; +import { useTranslation } from "react-i18next"; +import { BackendError, ErrorNotification, LinkStyleButton, Notification } from "@scm-manager/ui-components"; + +type Props = { + error?: Error | null; + showHelp: () => void; +}; + +const ParseErrorNotification: FC = ({ showHelp }) => { + const [t] = useTranslation("commons"); + return ( + +

{t("search.quickSearch.parseError")}

+ {t("search.quickSearch.parseErrorHelp")} +
+ ); +}; + +const isBackendError = (error: Error | BackendError): error is BackendError => { + return (error as BackendError).errorCode !== undefined; +}; + +const SearchErrorNotification: FC = ({ error, showHelp }) => { + if (!error) { + return null; + } + // 5VScek8Xp1 is the id of sonia.scm.search.QueryParseException + if (isBackendError(error) && error.errorCode === "5VScek8Xp1") { + return ; + } + return ; +}; + +export default SearchErrorNotification;