diff --git a/scm-ui/ui-components/src/BranchSelector.stories.tsx b/scm-ui/ui-components/src/BranchSelector.stories.tsx new file mode 100644 index 0000000000..5abc1a2202 --- /dev/null +++ b/scm-ui/ui-components/src/BranchSelector.stories.tsx @@ -0,0 +1,47 @@ +/* + * 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 { storiesOf } from "@storybook/react"; +import { BranchSelector } from "./index"; +import { Branch } from "@scm-manager/ui-types/src"; +import * as React from "react"; +import styled from "styled-components"; + +const master = { name: "master", revision: "1", defaultBranch: true, _links: {} }; +const develop = { name: "develop", revision: "2", defaultBranch: false, _links: {} }; + +const branchSelected = (branch?: Branch) => {}; + +const branches = [master, develop]; + +const Wrapper = styled.div` + margin: 2rem; + max-width: 400px; +`; + +storiesOf("BranchSelector", module) + .addDecorator(storyFn => {storyFn()}) + .add("Default", () => ( + +)); diff --git a/scm-ui/ui-components/src/Breadcrumb.stories.tsx b/scm-ui/ui-components/src/Breadcrumb.stories.tsx new file mode 100644 index 0000000000..d832081d8d --- /dev/null +++ b/scm-ui/ui-components/src/Breadcrumb.stories.tsx @@ -0,0 +1,57 @@ +/* + * 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 { storiesOf } from "@storybook/react"; +import * as React from "react"; +import styled from "styled-components"; +import Breadcrumb from "./Breadcrumb"; +import repository from "./__resources__/repository"; +// @ts-ignore ignore unknown png +import Git from "./__resources__/git-logo.png"; +import { MemoryRouter } from "react-router-dom"; + +const Wrapper = styled.div` + margin: 2rem; + max-width: 800px; +`; + +const master = { name: "master", revision: "1", defaultBranch: true, _links: {} }; +const path = "src/main/java/com/cloudogu"; +const baseUrl = "scm-manager.org/scm/repo/hitchhiker/heartOfGold/sources"; +const sources = Git; + +storiesOf("BreadCrumb", module) + .addDecorator(story => {story()}) + .addDecorator(storyFn => {storyFn()}) + .add("Default", () => ( + + )); diff --git a/scm-ui/ui-components/src/Breadcrumb.tsx b/scm-ui/ui-components/src/Breadcrumb.tsx index 05fecaff99..75142a2af8 100644 --- a/scm-ui/ui-components/src/Breadcrumb.tsx +++ b/scm-ui/ui-components/src/Breadcrumb.tsx @@ -59,24 +59,23 @@ class Breadcrumb extends React.Component { if (path) { const paths = path.split("/"); - const map = paths.map((path, index) => { + return paths.map((pathFragment, index) => { const currPath = paths.slice(0, index + 1).join("/"); if (paths.length - 1 === index) { return (
  • - {path} + {pathFragment}
  • ); } return (
  • - {path} + {pathFragment}
  • ); }); - return map; } return null; } diff --git a/scm-ui/ui-components/src/Notification.stories.tsx b/scm-ui/ui-components/src/Notification.stories.tsx new file mode 100644 index 0000000000..efce4ee6c5 --- /dev/null +++ b/scm-ui/ui-components/src/Notification.stories.tsx @@ -0,0 +1,71 @@ +/* + * 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 styled from "styled-components"; +import * as React from "react"; +import { ReactNode, useState } from "react"; +import { MemoryRouter } from "react-router-dom"; +import { storiesOf } from "@storybook/react"; +import Notification from "./Notification"; + +const Wrapper = styled.div` + margin: 2rem; + max-width: 400px; +`; + +const content = + "Cleverness nuclear genuine static irresponsibility invited President Zaphod\n" + + "Beeblebrox hyperspace ship. Another custard through computer-generated universe\n" + + "shapes field strong disaster parties Russell’s ancestors infinite colour\n" + + "imaginative generator sweep."; + +const RoutingDecorator = (story: () => ReactNode) => {story()}; + +storiesOf("Notification", module) + .addDecorator(RoutingDecorator) + .addDecorator(storyFn => {storyFn()}) + .add("Primary", () => {content}) + .add("Success", () => {content}) + .add("Info", () => {content}) + .add("Warning", () => {content}) + .add("Danger", () => {content}) + .add("Closeable", () => ); + +const Closeable = () => { + const [show, setShow] = useState(true); + + const hide = () => { + setShow(false); + }; + + if (!show) { + return null; + } + + return ( + hide()}> + {content} + + ); +}; diff --git a/scm-ui/ui-components/src/Tag.stories.tsx b/scm-ui/ui-components/src/Tag.stories.tsx new file mode 100644 index 0000000000..1c5c51497a --- /dev/null +++ b/scm-ui/ui-components/src/Tag.stories.tsx @@ -0,0 +1,60 @@ +/* + * 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 styled from "styled-components"; +import { storiesOf } from "@storybook/react"; +import * as React from "react"; +import Tag from "./Tag"; +import { ReactNode } from "react"; +import { MemoryRouter } from "react-router-dom"; + +const Wrapper = styled.div` + margin: 2rem; + max-width: 400px; +`; + +const Spacing = styled.div` + padding: 1em; +`; + +const colors = ["primary", "link", "info", "success", "warning", "danger"]; + +const RoutingDecorator = (story: () => ReactNode) => {story()}; + +storiesOf("Tag", module) + .addDecorator(RoutingDecorator) + .addDecorator(storyFn => {storyFn()}) + .add("Default", () => ) + .add("With Icon", () => ) + .add("Colors", () => ( +
    + {colors.map(color => ( + + + + ))} +
    + )) + .add("With title", () => ) + .add("Clickable", () => alert("Not so fast")}/>); diff --git a/scm-ui/ui-components/src/Tooltip.stories.tsx b/scm-ui/ui-components/src/Tooltip.stories.tsx new file mode 100644 index 0000000000..f6f4cbad5b --- /dev/null +++ b/scm-ui/ui-components/src/Tooltip.stories.tsx @@ -0,0 +1,61 @@ +/* + * 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 styled from "styled-components"; +import * as React from "react"; +import { ReactNode } from "react"; +import { MemoryRouter } from "react-router-dom"; +import { storiesOf } from "@storybook/react"; +import Tooltip from "./Tooltip"; +import Button from "./buttons/Button"; + +const Wrapper = styled.div` + margin: 2rem; + max-width: 400px; +`; + +const Spacing = styled.div` + padding: 2em 6em; +`; + +const positions = ["right", "top", "left", "bottom"]; + +const message = "Heart of Gold"; + +const RoutingDecorator = (story: () => ReactNode) => {story()}; + +storiesOf("Tooltip", module) + .addDecorator(RoutingDecorator) + .addDecorator(storyFn => {storyFn()}) + .add("Default", () => ( +
    + {positions.map(position => ( + + +
    + )); diff --git a/scm-ui/ui-components/src/__resources__/repository.ts b/scm-ui/ui-components/src/__resources__/repository.ts index 8facf86e57..5f3cc930e1 100644 --- a/scm-ui/ui-components/src/__resources__/repository.ts +++ b/scm-ui/ui-components/src/__resources__/repository.ts @@ -22,12 +22,12 @@ * SOFTWARE. */ export default { - contact: "heart-of-gold@hitchhiher.com", + contact: "heart-of-gold@hitchhiker.com", creationDate: "2020-03-23T08:26:01.164Z", description: "The starship Heart of Gold was the first spacecraft to make use of the Infinite Improbability Drive", healthCheckFailures: [], lastModified: "2020-03-23T08:26:01.876Z", - namespace: "hitchhiher", + namespace: "hitchhiker", name: "heartOfGold", type: "git", _links: { diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index 963d715e57..e9e4792aef 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -1,5 +1,134 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Storyshots BranchSelector Default 1`] = ` +
    +
    +
    + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +`; + +exports[`Storyshots BreadCrumb Default 1`] = ` +
    +
    + +
    +
    +
    +`; + exports[`Storyshots Buttons|AddButton Default 1`] = `
    `; +exports[`Storyshots Modal|ConfirmAlert Default 1`] = ` +
    +
    +
    +
    +

    + Are you sure about that? +

    +
    +
    + Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows + hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance with + Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly + ordinary mob. +
    + +
    +
    +`; + +exports[`Storyshots Modal|Modal Default 1`] = ` +
    +
    +
    +
    +

    + Hitchhiker Modal +

    +
    +
    +

    + Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance.with Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly ordinary mob. +

    +
    +
    +
    +`; + exports[`Storyshots Navigation|Secondary Default 1`] = `
    `; +exports[`Storyshots Notification Closeable 1`] = ` +
    +
    +
    +
    +`; + +exports[`Storyshots Notification Danger 1`] = ` +
    +
    + + Cleverness nuclear genuine static irresponsibility invited President Zaphod +Beeblebrox hyperspace ship. Another custard through computer-generated universe +shapes field strong disaster parties Russell’s ancestors infinite colour +imaginative generator sweep. +
    +
    +`; + +exports[`Storyshots Notification Info 1`] = ` +
    +
    + + Cleverness nuclear genuine static irresponsibility invited President Zaphod +Beeblebrox hyperspace ship. Another custard through computer-generated universe +shapes field strong disaster parties Russell’s ancestors infinite colour +imaginative generator sweep. +
    +
    +`; + +exports[`Storyshots Notification Primary 1`] = ` +
    +
    + + Cleverness nuclear genuine static irresponsibility invited President Zaphod +Beeblebrox hyperspace ship. Another custard through computer-generated universe +shapes field strong disaster parties Russell’s ancestors infinite colour +imaginative generator sweep. +
    +
    +`; + +exports[`Storyshots Notification Success 1`] = ` +
    +
    + + Cleverness nuclear genuine static irresponsibility invited President Zaphod +Beeblebrox hyperspace ship. Another custard through computer-generated universe +shapes field strong disaster parties Russell’s ancestors infinite colour +imaginative generator sweep. +
    +
    +`; + +exports[`Storyshots Notification Warning 1`] = ` +
    +
    + + Cleverness nuclear genuine static irresponsibility invited President Zaphod +Beeblebrox hyperspace ship. Another custard through computer-generated universe +shapes field strong disaster parties Russell’s ancestors infinite colour +imaginative generator sweep. +
    +
    +`; + exports[`Storyshots RepositoryEntry Avatar EP 1`] = `
    @@ -34989,7 +35316,7 @@ exports[`Storyshots RepositoryEntry Before Title EP 1`] = ` >
    `; +exports[`Storyshots Tag Clickable 1`] = ` +
    + + Click here + +
    +`; + +exports[`Storyshots Tag Colors 1`] = ` +
    +
    +
    + + primary + +
    +
    + + link + +
    +
    + + info + +
    +
    + + success + +
    +
    + + warning + +
    +
    + + danger + +
    +
    +
    +`; + +exports[`Storyshots Tag Default 1`] = ` +
    + + Default tag + +
    +`; + +exports[`Storyshots Tag With Icon 1`] = ` +
    + + +   + System + +
    +`; + +exports[`Storyshots Tag With title 1`] = ` +
    + + hover me + +
    +`; + exports[`Storyshots Toast Click to close 1`] = `null`; exports[`Storyshots Toast Danger 1`] = `null`; @@ -36513,3 +36957,84 @@ exports[`Storyshots Toast Primary 1`] = `null`; exports[`Storyshots Toast Success 1`] = `null`; exports[`Storyshots Toast Warning 1`] = `null`; + +exports[`Storyshots Tooltip Default 1`] = ` +
    +
    +
    + + + + +
    +
    + + + + +
    +
    + + + + +
    +
    + + + + +
    +
    +
    +`; diff --git a/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx b/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx new file mode 100644 index 0000000000..b450153c3b --- /dev/null +++ b/scm-ui/ui-components/src/modals/ConfirmAlert.stories.tsx @@ -0,0 +1,50 @@ +/* + * 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 { storiesOf } from "@storybook/react"; +import { MemoryRouter } from "react-router-dom"; +import * as React from "react"; +import ConfirmAlert from "./ConfirmAlert"; + +const body = + "Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows\n " + + "hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance with\n " + + "Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly\n " + + "ordinary mob."; + +const buttons = [ + { + className: "is-outlined", + label: "Cancel", + onClick: () => null + }, + { + label: "Submit", + onClick: () => {} + } +]; + +storiesOf("Modal|ConfirmAlert", module) + .addDecorator(story => {story()}) + .add("Default", () => ); diff --git a/scm-ui/ui-components/src/modals/Modal.stories.tsx b/scm-ui/ui-components/src/modals/Modal.stories.tsx new file mode 100644 index 0000000000..f620e7fd30 --- /dev/null +++ b/scm-ui/ui-components/src/modals/Modal.stories.tsx @@ -0,0 +1,52 @@ +/* + * 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 { storiesOf } from "@storybook/react"; +import { MemoryRouter } from "react-router-dom"; +import * as React from "react"; +import { useState } from "react"; +import Modal from "./Modal"; + +const body = ( +

    + Mind-paralyzing change needed improbability vortex machine sorts sought same theory upending job just allows + hostess’s really oblong Infinite Improbability thing into the starship against which behavior accordance.with + Kakrafoon humanoid undergarment ship powered by GPP-guided bowl of petunias nothing was frequently away incredibly + ordinary mob. +

    +); + +storiesOf("Modal|Modal", module) + .addDecorator(story => {story()}) + .add("Default", () => ); + +const CloseableModal = () => { + const [show, setShow] = useState(true); + + const toggleModal = () => { + setShow(!show); + }; + + return ; +}; diff --git a/scm-ui/ui-components/src/repos/RepositoryEntry.stories.tsx b/scm-ui/ui-components/src/repos/RepositoryEntry.stories.tsx index 4954d765ed..d10e7282cb 100644 --- a/scm-ui/ui-components/src/repos/RepositoryEntry.stories.tsx +++ b/scm-ui/ui-components/src/repos/RepositoryEntry.stories.tsx @@ -60,10 +60,10 @@ const bindQuickLink = (binder: Binder, extension: ReactNode) => { }); }; -const withBinder = (binder: Binder, repository: Repository) => { +const withBinder = (binder: Binder, repo: Repository) => { return ( - + ); }; @@ -87,7 +87,7 @@ storiesOf("RepositoryEntry", module) }) .add("Before Title EP", () => { const binder = new Binder("title"); - bindBeforeTitle(binder, ); + bindBeforeTitle(binder, ); return withBinder(binder, repository); }) .add("Quick Link EP", () => {