From 0888006a7412625946f444e2c76c7b53b185db00 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Tue, 14 Jan 2020 18:07:57 +0100 Subject: [PATCH] refactor code section --- .../codeSection/components/CodeActionBar.tsx | 50 ++++++ .../components/CodeViewSwitcher.tsx | 55 +++---- .../codeSection/containers/CodeOverview.tsx | 78 ++-------- .../src/repos/containers/ChangesetsRoot.tsx | 72 +++++++-- .../src/repos/sources/containers/Sources.tsx | 147 +++++++++--------- 5 files changed, 208 insertions(+), 194 deletions(-) create mode 100644 scm-ui/ui-webapp/src/repos/codeSection/components/CodeActionBar.tsx diff --git a/scm-ui/ui-webapp/src/repos/codeSection/components/CodeActionBar.tsx b/scm-ui/ui-webapp/src/repos/codeSection/components/CodeActionBar.tsx new file mode 100644 index 0000000000..15d2f18be4 --- /dev/null +++ b/scm-ui/ui-webapp/src/repos/codeSection/components/CodeActionBar.tsx @@ -0,0 +1,50 @@ +import React, { FC } from "react"; +import styled from "styled-components"; +import { RouteComponentProps, withRouter } from "react-router-dom"; +import { Level, BranchSelector } from "@scm-manager/ui-components"; +import CodeViewSwitcher from "./CodeViewSwitcher"; +import { useTranslation } from "react-i18next"; +import { Branch } from "@scm-manager/ui-types"; + +const ActionBar = styled.div.attrs(() => ({}))` + background-color: whitesmoke; + border: 1px solid #dbdbdb; + border-radius: 4px; + color: #363636; + font-size: 1.25em; + font-weight: 300; + line-height: 1.25; + padding: 0.5em 0.75em; + margin-bottom: 1em; +`; + +type Props = RouteComponentProps & { + selectedBranch?: string; + branches: Branch[]; + onSelectBranch: () => void; + switchViewLink: string; +}; + +const CodeActionBar: FC = ({ selectedBranch, branches, onSelectBranch, switchViewLink, location }) => { + const { t } = useTranslation("repos"); + + return ( + + 0 && ( + + ) + } + right={} + /> + + ); +}; + +export default withRouter(CodeActionBar); diff --git a/scm-ui/ui-webapp/src/repos/codeSection/components/CodeViewSwitcher.tsx b/scm-ui/ui-webapp/src/repos/codeSection/components/CodeViewSwitcher.tsx index baea31d5be..c604a5db2e 100644 --- a/scm-ui/ui-webapp/src/repos/codeSection/components/CodeViewSwitcher.tsx +++ b/scm-ui/ui-webapp/src/repos/codeSection/components/CodeViewSwitcher.tsx @@ -15,40 +15,29 @@ const ButtonAddonsMarginRight = styled(ButtonAddons)` `; type Props = { - baseUrl: string; currentUrl: string; - branches: Branch[]; - selectedBranch: string; + switchViewLink: string; }; -const CodeViewSwitcher: FC = ({ baseUrl, currentUrl, branches, selectedBranch }) => { +const CodeViewSwitcher: FC = ({ currentUrl, switchViewLink }) => { const [t] = useTranslation("repos"); - const createDestinationUrl = (destination: string, branch?: string, suffix?: string) => { - if (!branches) { - return baseUrl + "/" + destination + "/"; + const resolveLocation = () => { + if (currentUrl.includes("/code/branch") || currentUrl.includes("/code/changesets")) { + return "changesets"; } - let splittedUrl = currentUrl.split("/"); - splittedUrl[5] = destination; - splittedUrl.splice(6, splittedUrl.length); - if (branch) { - splittedUrl[6] = branch; + if (currentUrl.includes("/code/sources")) { + return "sources"; } - if (suffix) { - splittedUrl.push(suffix); - } - return splittedUrl.join("/"); + return ""; }; - const evaluateDestinationBranch = () => { - return ( - branches && - encodeURIComponent( - branches.filter(branch => branch.name === selectedBranch).length === 0 - ? branches.filter(branch => branch.defaultBranch === true)[0].name - : branches.filter(branch => branch.name === selectedBranch)[0].name - ) - ); + const isSourcesTab = () => { + return resolveLocation() === "sources"; + }; + + const isChangesetsTab = () => { + return resolveLocation() === "changesets"; }; return ( @@ -56,22 +45,14 @@ const CodeViewSwitcher: FC = ({ baseUrl, currentUrl, branches, selectedBr ); diff --git a/scm-ui/ui-webapp/src/repos/codeSection/containers/CodeOverview.tsx b/scm-ui/ui-webapp/src/repos/codeSection/containers/CodeOverview.tsx index df87b69440..180d7b0659 100644 --- a/scm-ui/ui-webapp/src/repos/codeSection/containers/CodeOverview.tsx +++ b/scm-ui/ui-webapp/src/repos/codeSection/containers/CodeOverview.tsx @@ -1,11 +1,9 @@ import React from "react"; -import styled from "styled-components"; import { Route, RouteComponentProps, withRouter } from "react-router-dom"; import Sources from "../../sources/containers/Sources"; import ChangesetsRoot from "../../containers/ChangesetsRoot"; import { Branch, Repository } from "@scm-manager/ui-types"; -import { BranchSelector, ErrorPage, Level, Loading } from "@scm-manager/ui-components"; -import CodeViewSwitcher from "../components/CodeViewSwitcher"; +import { ErrorPage, Loading } from "@scm-manager/ui-components"; import { compose } from "redux"; import { WithTranslation, withTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -31,56 +29,12 @@ type Props = RouteComponentProps & fetchBranches: (p: Repository) => void; }; -const CodeActionBar = styled.div.attrs(() => ({}))` - background-color: whitesmoke; - border: 1px solid #dbdbdb; - border-radius: 4px; - color: #363636; - font-size: 1.25em; - font-weight: 300; - line-height: 1.25; - padding: 0.5em 0.75em; - margin-bottom: 1em; -`; - class CodeOverview extends React.Component { componentDidMount() { - const { repository, branches } = this.props; - new Promise(() => { - this.props.fetchBranches(repository); - }).then(() => { - if (this.props.branches?.length > 0) { - const defaultBranch = branches.filter((branch: Branch) => branch.defaultBranch === true)[0]; - this.branchSelected(defaultBranch); - } - }); + const { repository } = this.props; + this.props.fetchBranches(repository); } - findSelectedBranch = () => { - const { selectedBranch, branches } = this.props; - return branches?.find((branch: Branch) => branch.name === selectedBranch); - }; - - branchSelected = (branch?: Branch) => { - let splittedUrl = this.props.location.pathname.split("/"); - if ( - this.props.location.pathname.includes("/code/sources") || - this.props.location.pathname.includes("/code/branch") - ) { - if (branch) { - splittedUrl[6] = encodeURIComponent(branch.name); - } - this.props.history.push(splittedUrl.join("/")); - } - if (this.props.location.pathname.includes("/code/changesets")) { - this.props.history.push( - `${splittedUrl[0]}/${splittedUrl[1]}/${splittedUrl[2]}/${splittedUrl[3]}/${ - splittedUrl[4] - }/branch/${encodeURIComponent(branch.name)}/${splittedUrl[5]}/` - ); - } - }; - render() { const { repository, baseUrl, branches, selectedBranch, error, loading, t } = this.props; const url = baseUrl; @@ -97,39 +51,29 @@ class CodeOverview extends React.Component { return (
- - - } - right={} - /> - } + render={() => } /> } + render={() => ( + + )} /> } + render={() => } /> ( b.name === this.props.selectedBranch)[0]} + baseUrl={`${url}`} + branches={branches} + selectedBranch={selectedBranch} /> )} /> diff --git a/scm-ui/ui-webapp/src/repos/containers/ChangesetsRoot.tsx b/scm-ui/ui-webapp/src/repos/containers/ChangesetsRoot.tsx index dd81ef140a..17b3acc991 100644 --- a/scm-ui/ui-webapp/src/repos/containers/ChangesetsRoot.tsx +++ b/scm-ui/ui-webapp/src/repos/containers/ChangesetsRoot.tsx @@ -1,21 +1,28 @@ import React from "react"; -import { Route, withRouter } from "react-router-dom"; +import { Route, withRouter, RouteComponentProps } from "react-router-dom"; import { WithTranslation, withTranslation } from "react-i18next"; -import { Repository } from "@scm-manager/ui-types"; +import { Repository, Branch } from "@scm-manager/ui-types"; import Changesets from "./Changesets"; import { compose } from "redux"; +import CodeActionBar from "../codeSection/components/CodeActionBar"; -type Props = WithTranslation & { - repository: Repository; - selectedBranch: string; - baseUrl: string; - - // Context props - history: any; // TODO flow type - match: any; -}; +type Props = WithTranslation & + RouteComponentProps & { + repository: Repository; + selectedBranch: string; + baseUrl: string; + branches: Branch[]; + }; class ChangesetsRoot extends React.Component { + componentDidMount() { + const { branches, baseUrl } = this.props; + if (branches?.length > 0 && this.isSelectedBranchIsNotABranch()) { + const defaultBranch = branches?.filter(b => b.defaultBranch === true)[0]; + this.props.history.push(`${baseUrl}/branch/${encodeURIComponent(defaultBranch.name)}/changesets/`); + } + } + stripEndingSlash = (url: string) => { if (url.endsWith("/")) { return url.substring(0, url.length - 1); @@ -23,8 +30,29 @@ class ChangesetsRoot extends React.Component { return url; }; + isSelectedBranchIsNotABranch = () => { + const { branches, selectedBranch } = this.props; + return branches?.filter(b => b.name === selectedBranch).length === 0; + }; + + evaluateSwitchViewLink = () => { + const { baseUrl, selectedBranch } = this.props; + if (selectedBranch) { + return `${baseUrl}/sources/${encodeURIComponent(selectedBranch)}/`; + } + return `${baseUrl}/sources/`; + }; + + onSelectBranch = (branch?: Branch) => { + const { baseUrl, history } = this.props; + if (branch) { + let url = `${baseUrl}/branch/${encodeURIComponent(branch.name)}/changesets/`; + history.push(url); + } + }; + render() { - const { repository, match, selectedBranch } = this.props; + const { repository, branches, match, selectedBranch } = this.props; if (!repository) { return null; @@ -33,12 +61,22 @@ class ChangesetsRoot extends React.Component { const url = this.stripEndingSlash(match.url); return ( -
- } + <> + -
+
+ ( + b.name === selectedBranch)[0]} /> + )} + /> +
+ ); } } diff --git a/scm-ui/ui-webapp/src/repos/sources/containers/Sources.tsx b/scm-ui/ui-webapp/src/repos/sources/containers/Sources.tsx index ff2a4a5dbb..790d035ed3 100644 --- a/scm-ui/ui-webapp/src/repos/sources/containers/Sources.tsx +++ b/scm-ui/ui-webapp/src/repos/sources/containers/Sources.tsx @@ -1,6 +1,6 @@ import React from "react"; import { connect } from "react-redux"; -import { withRouter } from "react-router-dom"; +import { withRouter, RouteComponentProps } from "react-router-dom"; import { WithTranslation, withTranslation } from "react-i18next"; import { Branch, Repository } from "@scm-manager/ui-types"; import { Breadcrumb, ErrorNotification, Loading } from "@scm-manager/ui-components"; @@ -9,46 +9,33 @@ import { getFetchBranchesFailure, isFetchBranchesPending } from "../../branches/ import { compose } from "redux"; import Content from "./Content"; import { fetchSources, getSources, isDirectory } from "../modules/sources"; +import CodeActionBar from "../../codeSection/components/CodeActionBar"; -type Props = WithTranslation & { - repository: Repository; - loading: boolean; - error: Error; - baseUrl: string; - branches: Branch[]; - revision: string; - path: string; - currentFileIsDirectory: boolean; - sources: File; +type Props = WithTranslation & + RouteComponentProps & { + repository: Repository; + loading: boolean; + error: Error; + baseUrl: string; + branches: Branch[]; + revision: string; + path: string; + currentFileIsDirectory: boolean; + sources: File; + selectedBranch: string; - // dispatch props - fetchSources: (p1: Repository, p2: string, p3: string) => void; - - // Context props - history: any; - match: any; - location: any; -}; - -type State = { - selectedBranch: any; -}; - -class Sources extends React.Component { - constructor(props: Props) { - super(props); - - this.state = { - selectedBranch: null - }; - } + // dispatch props + fetchSources: (p1: Repository, p2: string, p3: string) => void; + }; +class Sources extends React.Component { componentDidMount() { - const { repository, revision, path, fetchSources } = this.props; - + const { repository, branches, selectedBranch, baseUrl, revision, path, fetchSources } = this.props; fetchSources(repository, this.decodeRevision(revision), path); - - this.redirectToDefaultBranch(); + if (branches?.length > 0 && !selectedBranch) { + const defaultBranch = branches?.filter(b => b.defaultBranch === true)[0]; + this.props.history.push(`${baseUrl}/sources/${encodeURIComponent(defaultBranch.name)}/`); + } } componentDidUpdate(prevProps: Props) { @@ -62,45 +49,42 @@ class Sources extends React.Component { return revision ? decodeURIComponent(revision) : revision; }; - redirectToDefaultBranch = () => { - const { branches } = this.props; - if (this.shouldRedirectToDefaultBranch()) { - const defaultBranches = branches.filter(b => b.defaultBranch); - - if (defaultBranches.length > 0) { - this.branchSelected(defaultBranches[0]); - } - } - }; - - shouldRedirectToDefaultBranch = () => { - const { branches, revision } = this.props; - return branches && !revision; - }; - - branchSelected = (branch?: Branch) => { + onSelectBranch = (branch?: Branch) => { const { baseUrl, history, path } = this.props; let url; if (branch) { - this.setState({ - selectedBranch: branch - }); if (path) { - url = `${baseUrl}/${encodeURIComponent(branch.name)}/${path}`; + url = `${baseUrl}/sources/${encodeURIComponent(branch.name)}/${path}`; + url = !url.endsWith("/") ? url + "/" : url; } else { - url = `${baseUrl}/${encodeURIComponent(branch.name)}/`; + url = `${baseUrl}/sources/${encodeURIComponent(branch.name)}/`; } } else { - this.setState({ - selectedBranch: null - }); - url = `${baseUrl}/`; + return; } history.push(url); }; + evaluateSwitchViewLink = () => { + const { baseUrl, selectedBranch } = this.props; + if (selectedBranch) { + return `${baseUrl}/branch/${encodeURIComponent(selectedBranch)}/changesets/`; + } + return `${baseUrl}/changesets/`; + }; + render() { - const { repository, baseUrl, loading, error, revision, path, currentFileIsDirectory } = this.props; + const { + repository, + baseUrl, + branches, + selectedBranch, + loading, + error, + revision, + path, + currentFileIsDirectory + } = this.props; if (error) { return ; @@ -112,28 +96,45 @@ class Sources extends React.Component { if (currentFileIsDirectory) { return ( -
- {this.renderBreadcrumb()} - -
+ <> + +
+ {this.renderBreadcrumb()} + +
+ ); } else { - return ; + return ( + <> + + + + ); } } renderBreadcrumb = () => { - const { revision, path, baseUrl, branches, sources, repository } = this.props; - const { selectedBranch } = this.state; + const { revision, selectedBranch, path, baseUrl, branches, sources, repository } = this.props; return ( b.defaultBranch === true)[0]} + baseUrl={baseUrl + "/sources"} + branch={branches?.filter(b => b.name === selectedBranch)[0]} + defaultBranch={branches?.filter(b => b.defaultBranch === true)[0]} sources={sources} /> );