diff --git a/scm-ui/ui-components/src/CommaSeparatedList.tsx b/scm-ui/ui-components/src/CommaSeparatedList.tsx new file mode 100644 index 0000000000..a597ed0dc0 --- /dev/null +++ b/scm-ui/ui-components/src/CommaSeparatedList.tsx @@ -0,0 +1,51 @@ +/* + * 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"; + +const CommaSeparatedList: FC = ({ children }) => { + const [t] = useTranslation("commons"); + const childArray = React.Children.toArray(children); + return ( + <> + {childArray.map((p, i) => { + if (i === 0) { + return {p}; + } else if (i + 1 === childArray.length) { + return ( + + {" "} + {t("commaSeparatedList.lastDivider")} {p}{" "} + + ); + } else { + return , {p}; + } + })} + > + ); +}; + +export default CommaSeparatedList; diff --git a/scm-ui/ui-components/src/index.ts b/scm-ui/ui-components/src/index.ts index c31066edc1..8a2d9c1106 100644 --- a/scm-ui/ui-components/src/index.ts +++ b/scm-ui/ui-components/src/index.ts @@ -40,6 +40,7 @@ import { DiffEventHandler, DiffEventContext } from "./repos"; +import CommaSeparatedList from "./CommaSeparatedList"; export { validation, urls, repositories }; @@ -76,6 +77,7 @@ export { default as OverviewPageActions } from "./OverviewPageActions"; export { default as CardColumnGroup } from "./CardColumnGroup"; export { default as CardColumn } from "./CardColumn"; export { default as CardColumnSmall } from "./CardColumnSmall"; +export { default as CommaSeparatedList } from "./CommaSeparatedList"; export { default as comparators } from "./comparators"; diff --git a/scm-ui/ui-components/src/repos/changesets/ChangesetAuthor.tsx b/scm-ui/ui-components/src/repos/changesets/ChangesetAuthor.tsx index d2bc793be4..27fd850b1b 100644 --- a/scm-ui/ui-components/src/repos/changesets/ChangesetAuthor.tsx +++ b/scm-ui/ui-components/src/repos/changesets/ChangesetAuthor.tsx @@ -28,6 +28,7 @@ import { useBinder } from "@scm-manager/ui-extensions"; import { EXTENSION_POINT, Person } from "../../avatar/Avatar"; import Image from "../../Image"; import styled from "styled-components"; +import CommaSeparatedList from "../../CommaSeparatedList"; type Props = { changeset: Changeset; @@ -119,7 +120,7 @@ const Persons: FC = ({ persons, label, displayTextOnly }) => { {t(label)}{" "} {persons.map(p => ( - + ))} > @@ -128,7 +129,7 @@ const Persons: FC = ({ persons, label, displayTextOnly }) => { return ( <> {t(label)}{" "} - "- " + person.name).join("\n")}> + "- " + person.name).join("\n")}> {t("changesets.authors.more", { count: persons.length })} > @@ -175,24 +176,7 @@ const ChangesetAuthor: FC = ({ changeset }) => { coAuthors.push(...extensions); } - return ( - <> - {authorLine.map((p, i) => { - if (i === 0) { - return <>{p}>; - } else if (i + 1 === authorLine.length) { - return ( - <> - {" "} - {t("changesets.authors.and")} {p}{" "} - > - ); - } else { - return <>, {p}>; - } - })} - > - ); + return {authorLine} }; export default ChangesetAuthor; diff --git a/scm-ui/ui-webapp/public/locales/de/commons.json b/scm-ui/ui-webapp/public/locales/de/commons.json index d88b77b850..158d5e6420 100644 --- a/scm-ui/ui-webapp/public/locales/de/commons.json +++ b/scm-ui/ui-webapp/public/locales/de/commons.json @@ -104,5 +104,8 @@ "community": "Community", "enterprise": "Enterprise" } + }, + "commaSeparatedList": { + "lastDivider": "und" } } diff --git a/scm-ui/ui-webapp/public/locales/en/commons.json b/scm-ui/ui-webapp/public/locales/en/commons.json index 3d5af75f78..444de0bea5 100644 --- a/scm-ui/ui-webapp/public/locales/en/commons.json +++ b/scm-ui/ui-webapp/public/locales/en/commons.json @@ -105,5 +105,8 @@ "community": "Community", "enterprise": "Enterprise" } + }, + "commaSeparatedList": { + "lastDivider": "and" } } diff --git a/scm-ui/ui-webapp/public/locales/es/commons.json b/scm-ui/ui-webapp/public/locales/es/commons.json index 47638c1d6e..33c8b70dd5 100644 --- a/scm-ui/ui-webapp/public/locales/es/commons.json +++ b/scm-ui/ui-webapp/public/locales/es/commons.json @@ -89,5 +89,8 @@ "passwordConfirmFailed": "Las contraseñas deben ser identicas", "submit": "Guardar", "changedSuccessfully": "Contraseña cambiada correctamente" + }, + "commaSeparatedList": { + "lastDivider": "y" } } diff --git a/scm-ui/ui-webapp/src/repos/components/changesets/ContributorTable.tsx b/scm-ui/ui-webapp/src/repos/components/changesets/ContributorTable.tsx index 09a966a9ef..11d843428f 100644 --- a/scm-ui/ui-webapp/src/repos/components/changesets/ContributorTable.tsx +++ b/scm-ui/ui-webapp/src/repos/components/changesets/ContributorTable.tsx @@ -26,7 +26,7 @@ import { Changeset } from "@scm-manager/ui-types"; import styled from "styled-components"; import { useTranslation } from "react-i18next"; import { useBinder } from "@scm-manager/ui-extensions"; -import { Image } from "@scm-manager/ui-components"; +import { Image, CommaSeparatedList } from "@scm-manager/ui-components"; type Props = { changeset: Changeset; @@ -104,14 +104,14 @@ const ContributorTable: FC = ({ changeset }) => { {getTrailersByType().map(trailer => ( - + {t("changeset.trailer.type." + trailer.type) + ":"} - {trailer.persons - .map(person => ( - - )) - .reduce((prev, curr) => [prev, ", ", curr])} + + {trailer.persons.map(person => ( + + ))} + ))}