diff --git a/scm-ui/src/repos/content/components/Content.js b/scm-ui/src/repos/content/components/Content.js index e99692974f..edf46454ae 100644 --- a/scm-ui/src/repos/content/components/Content.js +++ b/scm-ui/src/repos/content/components/Content.js @@ -23,14 +23,14 @@ class Content extends React.Component { componentDidMount() {} render() { - return null; + return "Hallo here is content"; } } export function getContentType(url: string) { return apiClient .head(url) - .then(response => response) + .then(response => response.headers.get("Content-Type")) .catch(err => { return null; }); diff --git a/scm-ui/src/repos/content/components/Content.test.js b/scm-ui/src/repos/content/components/Content.test.js index a1828b0872..ef115accd4 100644 --- a/scm-ui/src/repos/content/components/Content.test.js +++ b/scm-ui/src/repos/content/components/Content.test.js @@ -10,13 +10,17 @@ describe("get content type", () => { fetchMock.restore(); }); - xit("should return content", done => { + it("should return content", done => { + let headers = { + "Content-Type": "application/text" + }; + fetchMock.head("/api/v2" + CONTENT_URL, { - "Content-Type": "text/plain" + headers }); getContentType(CONTENT_URL).then(content => { - expect(content).toBe("This is a testContent"); + expect(content).toBe("application/text"); done(); }); }); diff --git a/scm-ui/src/repos/sources/components/FileTree.js b/scm-ui/src/repos/sources/components/FileTree.js index 02aa22f942..e9b5c70d3d 100644 --- a/scm-ui/src/repos/sources/components/FileTree.js +++ b/scm-ui/src/repos/sources/components/FileTree.js @@ -7,7 +7,6 @@ import FileTreeLeaf from "./FileTreeLeaf"; import type { Repository, File } from "@scm-manager/ui-types"; import { ErrorNotification, Loading } from "@scm-manager/ui-components"; import { - fetchSources, getFetchSourcesFailure, isFetchSourcesPending, getSources @@ -29,7 +28,6 @@ type Props = { revision: string, path: string, baseUrl: string, - fetchSources: (Repository, string, string) => void, // context props classes: any, t: string => string, @@ -49,19 +47,6 @@ export function findParent(path: string) { } class FileTree extends React.Component { - componentDidMount() { - const { fetchSources, repository, revision, path } = this.props; - - fetchSources(repository, revision, path); - } - - componentDidUpdate(prevProps) { - const { fetchSources, repository, revision, path } = this.props; - if (prevProps.revision !== revision || prevProps.path !== path) { - fetchSources(repository, revision, path); - } - } - render() { const { error, @@ -167,18 +152,7 @@ const mapStateToProps = (state: any, ownProps: Props) => { }; }; -const mapDispatchToProps = dispatch => { - return { - fetchSources: (repository: Repository, revision: string, path: string) => { - dispatch(fetchSources(repository, revision, path)); - } - }; -}; - export default compose( withRouter, - connect( - mapStateToProps, - mapDispatchToProps - ) + connect(mapStateToProps) )(injectSheet(styles)(translate("repos")(FileTree))); diff --git a/scm-ui/src/repos/sources/components/FileTreeLeaf.js b/scm-ui/src/repos/sources/components/FileTreeLeaf.js index 033d3b9b8a..b4e2ad59ea 100644 --- a/scm-ui/src/repos/sources/components/FileTreeLeaf.js +++ b/scm-ui/src/repos/sources/components/FileTreeLeaf.js @@ -49,14 +49,18 @@ class FileTreeLeaf extends React.Component { ); } - return ; + return ( + + + + ); }; createFileName = (file: File) => { if (file.directory) { return {file.name}; } - return file.name; + return {file.name}; }; render() { diff --git a/scm-ui/src/repos/sources/containers/Sources.js b/scm-ui/src/repos/sources/containers/Sources.js index cf072e958e..a31a15353f 100644 --- a/scm-ui/src/repos/sources/containers/Sources.js +++ b/scm-ui/src/repos/sources/containers/Sources.js @@ -13,6 +13,8 @@ import { isFetchBranchesPending } from "../../modules/branches"; import { compose } from "redux"; +import Content from "../../content/components/Content"; +import { fetchSources, isDirectory } from "../modules/sources"; type Props = { repository: Repository, @@ -22,9 +24,11 @@ type Props = { branches: Branch[], revision: string, path: string, + currentFileIsDirectory: boolean, // dispatch props fetchBranches: Repository => void, + fetchSources: (Repository, string, string) => void, // Context props history: any, @@ -33,14 +37,26 @@ type Props = { class Sources extends React.Component { componentDidMount() { - const { fetchBranches, repository } = this.props; + const { + fetchBranches, + repository, + revision, + path, + fetchSources + } = this.props; fetchBranches(repository); + fetchSources(repository, revision, path); + } + componentDidUpdate(prevProps) { + const { fetchSources, repository, revision, path } = this.props; + if (prevProps.revision !== revision || prevProps.path !== path) { + fetchSources(repository, revision, path); + } } branchSelected = (branch?: Branch) => { const { baseUrl, history, path } = this.props; - let url; if (branch) { if (path) { @@ -55,7 +71,15 @@ class Sources extends React.Component { }; render() { - const { repository, baseUrl, loading, error, revision, path } = this.props; + const { + repository, + baseUrl, + loading, + error, + revision, + path, + currentFileIsDirectory + } = this.props; if (error) { return ; @@ -65,21 +89,26 @@ class Sources extends React.Component { return ; } - return ( - <> - {this.renderBranchSelector()} - - - ); + if (currentFileIsDirectory) { + return ( + <> + {this.renderBranchSelector()} + + + ); + } else { + return ; + } } renderBranchSelector = () => { const { repository, branches, revision } = this.props; + if (repository._links.branches) { return ( { const { repository, match } = ownProps; const { revision, path } = match.params; const decodedRevision = revision ? decodeURIComponent(revision) : undefined; - const loading = isFetchBranchesPending(state, repository); const error = getFetchBranchesFailure(state, repository); const branches = getBranches(state, repository); + const currentFileIsDirectory = isDirectory(state, repository, revision, path); return { repository, @@ -110,7 +139,8 @@ const mapStateToProps = (state, ownProps) => { path, loading, error, - branches + branches, + currentFileIsDirectory }; }; @@ -118,6 +148,9 @@ const mapDispatchToProps = dispatch => { return { fetchBranches: (repository: Repository) => { dispatch(fetchBranches(repository)); + }, + fetchSources: (repository: Repository, revision: string, path: string) => { + dispatch(fetchSources(repository, revision, path)); } }; }; diff --git a/scm-ui/src/repos/sources/modules/sources.js b/scm-ui/src/repos/sources/modules/sources.js index 719770d75c..641c1550b6 100644 --- a/scm-ui/src/repos/sources/modules/sources.js +++ b/scm-ui/src/repos/sources/modules/sources.js @@ -102,6 +102,20 @@ export default function reducer( // selectors +export function isDirectory( + state: any, + repository: Repository, + revision: string, + path: string +): boolean { + const currentFile = getSources(state, repository, revision, path); + if (currentFile && !currentFile.directory) { + return false; + } else { + return true; //also return true if no currentFile is found since it is the "default" path + } +} + export function getSources( state: any, repository: Repository, diff --git a/scm-ui/src/repos/sources/modules/sources.test.js b/scm-ui/src/repos/sources/modules/sources.test.js index 068fa39e8f..f6336bba53 100644 --- a/scm-ui/src/repos/sources/modules/sources.test.js +++ b/scm-ui/src/repos/sources/modules/sources.test.js @@ -1,6 +1,6 @@ // @flow -import type { Repository } from "@scm-manager/ui-types"; +import type { Repository, File } from "@scm-manager/ui-types"; import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; import fetchMock from "fetch-mock"; @@ -14,7 +14,8 @@ import { isFetchSourcesPending, default as reducer, getSources, - fetchSourcesSuccess + fetchSourcesSuccess, + isDirectory } from "./sources"; const sourcesUrl = @@ -79,6 +80,42 @@ const collection = { } }; +const noDirectory: File = { + name: "src", + path: "src", + directory: true, + length: 176, + revision: "abc", + _links: { + self: { + href: + "http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/src" + } + }, + _embedded: collection +}; + +const directory: File = { + name: "package.json", + path: "package.json", + directory: false, + description: "bump version", + length: 780, + lastModified: "2017-07-31T11:17:19Z", + revision: "abc", + _links: { + self: { + href: + "http://localhost:8081/scm/rest/api/v2/repositories/scm/core/content/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/package.json" + }, + history: { + href: + "http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/history/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/package.json" + } + }, + _embedded: {} +}; + describe("sources fetch", () => { const mockStore = configureMockStore([thunk]); @@ -168,6 +205,28 @@ describe("reducer tests", () => { }); describe("selector tests", () => { + it("should return false if it is no directory", () => { + const state = { + sources: { + "scm/core/abc/src/main/package.json": { + noDirectory + } + } + }; + expect( + isDirectory(state, repository, "abc", "src/main/package.json") + ).toBeFalsy(); + }); + + it("should return true if it is directory", () => { + const state = { + sources: { + "scm/core/abc/src": noDirectory + } + }; + expect(isDirectory(state, repository, "abc", "src")).toBe(true); + }); + it("should return null", () => { expect(getSources({}, repository)).toBeFalsy(); }); @@ -181,7 +240,7 @@ describe("selector tests", () => { expect(getSources(state, repository)).toBe(collection); }); - it("should return the source collection without revision and path", () => { + it("should return the source collection with revision and path", () => { const state = { sources: { "scm/core/abc/src/main": collection