Skip to content

Commit

Permalink
[Code] source view page branch selector (elastic#39238) (elastic#39758)
Browse files Browse the repository at this point in the history
* feature(code/frontend): source view page branch selector
  • Loading branch information
WangQianliang authored Jun 27, 2019
1 parent e481029 commit 0562b51
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 37 deletions.
8 changes: 8 additions & 0 deletions x-pack/legacy/plugins/code/common/uri_util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,11 @@ export function toCanonicalUrl(lspUrl: CompleteParsedUrl) {
const uri = decodeURIComponent(compiled(data));
return lspUrl.schema ? `${lspUrl.schema}/${uri}` : uri;
}

export const decodeRevisionString = (revision: string) => {
return revision.replace(/:/g, '/');
};

export const encodeRevisionString = (revision: string) => {
return revision.replace(/\//g, ':');
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { refUrlSelector } from '../../selectors';
import { history } from '../../utils/url';
import { Modifier, Shortcut } from '../shortcuts';
import { ReferencesPanel } from './references_panel';
import { encodeRevisionString } from '../../utils/url';
import { encodeRevisionString } from '../../../common/uri_util';

export interface EditorActions {
closeReferences(changeUrl: boolean): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { FileTree as Tree, FileTreeItemType } from '../../../model';
import { closeTreePath, openTreePath } from '../../actions';
import { EuiSideNavItem, MainRouteParams, PathTypes } from '../../common/types';
import { RootState } from '../../reducers';
import { encodeRevisionString } from '../../utils/url';
import { encodeRevisionString } from '../../../common/uri_util';

interface Props extends RouteComponentProps<MainRouteParams> {
node?: Tree;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { EuiBreadcrumbs } from '@elastic/eui';
import React from 'react';
import { MainRouteParams } from '../../common/types';
import { encodeRevisionString } from '../../utils/url';
import { encodeRevisionString } from '../../../common/uri_util';

interface Props {
routeParams: MainRouteParams;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import {
repoUriSelector,
statusSelector,
} from '../../selectors';
import { encodeRevisionString, history } from '../../utils/url';
import { encodeRevisionString } from '../../../common/uri_util';
import { history } from '../../utils/url';
import { Editor } from '../editor/editor';
import { CloneStatus } from './clone_status';
import { CommitHistory } from './commit_history';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import React from 'react';
import { Link, RouteComponentProps, withRouter } from 'react-router-dom';
import { FileTree, FileTreeItemType } from '../../../model';
import { MainRouteParams, PathTypes } from '../../common/types';
import { encodeRevisionString } from '../../utils/url';
import { encodeRevisionString } from '../../../common/uri_util';

interface DirectoryNodesProps {
title: string;
Expand Down
47 changes: 37 additions & 10 deletions x-pack/legacy/plugins/code/public/components/main/top_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React, { ChangeEvent } from 'react';
import { SearchOptions, SearchScope } from '../../../model';
import { ReferenceInfo } from '../../../model/commit';
import { MainRouteParams } from '../../common/types';
import { encodeRevisionString } from '../../utils/url';
import { encodeRevisionString, decodeRevisionString } from '../../../common/uri_util';
import { history } from '../../utils/url';
import { Breadcrumb } from './breadcrumb';
import { SearchBar } from '../search_bar';
Expand All @@ -24,22 +24,51 @@ interface Props {
}

export class TopBar extends React.Component<Props, { value: string }> {
static getDerivedStateFromProps(props: Props) {
return { value: decodeRevisionString(props.routeParams.revision) };
}
public state = {
value: 'master',
value: decodeRevisionString(this.props.routeParams.revision),
};

get branch() {
return this.getBranch(this.state.value);
}

getBranch = (revision: string) => {
const r = decodeRevisionString(revision);
const branch = this.props.branches.find(b => b.name === r);
if (branch) {
return branch.name;
} else {
return '';
}
};

get branchOptions() {
return this.props.branches.map(b => ({
value: b.name,
text: b.name,
['data-test-subj']: `codeBranchSelectOption-${b.name}${
this.branch === b.name ? 'Active' : ''
}`,
}));
}

public onChange = (e: ChangeEvent<HTMLSelectElement>) => {
const { resource, org, repo, path = '', pathType } = this.props.routeParams;
const { value } = e.target;
this.setState({
value: e.target.value,
value,
});
const revision = this.props.branches.find(b => b.name === e.target.value)!.commit.id;
const revision = this.props.branches.find(b => b.name === value)!.name;
history.push(
`/${resource}/${org}/${repo}/${pathType}/${encodeRevisionString(revision)}/${path}`
);
};

public render() {
const { branch } = this;
return (
<div className="code-top-bar__container">
<SearchBar
Expand All @@ -55,14 +84,12 @@ export class TopBar extends React.Component<Props, { value: string }> {
>
<EuiFlexItem>
<EuiFlexGroup gutterSize="none">
<EuiFlexItem
className="codeContainer__select"
grow={false}
style={{ display: 'none' }}
>
<EuiFlexItem className="codeContainer__select" grow={false}>
<EuiSelect
options={this.props.branches.map(b => ({ value: b.name, text: b.name }))}
options={this.branchOptions}
value={branch}
onChange={this.onChange}
data-test-subj="codeBranchSelector"
/>
</EuiFlexItem>
<Breadcrumb routeParams={this.props.routeParams} />
Expand Down
7 changes: 0 additions & 7 deletions x-pack/legacy/plugins/code/public/components/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,17 @@
import { connect } from 'react-redux';
import { Route as ReactRoute, RouteProps } from 'react-router-dom';
import { Match, routeChange } from '../actions';
import { decodeRevisionString } from '../utils/url';

interface Props extends RouteProps {
routeChange: (match: Match) => void;
}
class CSRoute extends ReactRoute<Props> {
// eslint-disable-next-line @typescript-eslint/camelcase
public UNSAFE_componentWillMount() {
if (this.state.match && this.state.match.params && this.state.match.params.revision) {
this.state.match.params.revision = decodeRevisionString(this.state.match.params.revision);
}
this.props.routeChange({ ...this.state.match, location: this.props.location });
}

public componentDidUpdate() {
if (this.state.match && this.state.match.params && this.state.match.params.revision) {
this.state.match.params.revision = decodeRevisionString(this.state.match.params.revision);
}
this.props.routeChange({ ...this.state.match, location: this.props.location });
}
}
Expand Down
2 changes: 1 addition & 1 deletion x-pack/legacy/plugins/code/public/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const statusSelector = (state: RootState, repoUri: RepositoryUri) => {

export const allStatusSelector = (state: RootState) => state.status.status;

export const currentPathSelector = (state: RootState) => state.route.match.params.path;
export const currentPathSelector = (state: RootState) => state.route.match.params.path || '';

export const treeCommitsSelector = (state: RootState) => {
const path = currentPathSelector(state);
Expand Down
1 change: 1 addition & 0 deletions x-pack/legacy/plugins/code/public/style/_layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@

.codeContainer__select {
margin-right: $euiSizeS;
min-width: 12rem;
}

.codeContainer__tabs {
Expand Down
8 changes: 0 additions & 8 deletions x-pack/legacy/plugins/code/public/utils/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,3 @@ import { createHashHistory } from 'history';
export const history = createHashHistory();

export const isImportRepositoryURLInvalid = (url: string) => url.trim() === '';

export const decodeRevisionString = (revision: string) => {
return revision.replace(':', '/');
};

export const encodeRevisionString = (revision: string) => {
return revision.replace('/', ':');
};
21 changes: 15 additions & 6 deletions x-pack/legacy/plugins/code/server/routes/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { RepositoryObjectClient } from '../search';
import { EsClientWithRequest } from '../utils/esclient_with_request';
import { TEXT_FILE_LIMIT } from '../../common/file';
import { ReferenceType } from '../../model/commit';
import { decodeRevisionString } from '../../common/uri_util';

export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
async function repoExists(req: hapi.Request, repoUri: string) {
Expand All @@ -40,6 +41,7 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
method: 'GET',
async handler(req: hapi.Request) {
const { uri, path, ref } = req.params;
const revision = decodeRevisionString(ref);
const queries = req.query as RequestQuery;
const limit = queries.limit
? parseInt(queries.limit as string, 10)
Expand All @@ -54,7 +56,7 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
}

try {
return await gitOps.fileTree(uri, path, ref, skip, limit, withParents, depth, flatten);
return await gitOps.fileTree(uri, path, revision, skip, limit, withParents, depth, flatten);
} catch (e) {
if (e.isBoom) {
return e;
Expand All @@ -70,12 +72,13 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
method: 'GET',
async handler(req: hapi.Request, h: hapi.ResponseToolkit) {
const { uri, path, ref } = req.params;
const revision = decodeRevisionString(ref);
const repoExist = await repoExists(req, uri);
if (!repoExist) {
return Boom.notFound(`repo ${uri} not found`);
}
try {
const blob = await gitOps.fileContent(uri, path, decodeURIComponent(ref));
const blob = await gitOps.fileContent(uri, path, decodeURIComponent(revision));
if (blob.isBinary()) {
const type = fileType(blob.content());
if (type && type.mime && type.mime.startsWith('image/')) {
Expand Down Expand Up @@ -129,12 +132,13 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
method: 'GET',
async handler(req, h: hapi.ResponseToolkit) {
const { uri, path, ref } = req.params;
const revision = decodeRevisionString(ref);
const repoExist = await repoExists(req, uri);
if (!repoExist) {
return Boom.notFound(`repo ${uri} not found`);
}
try {
const blob = await gitOps.fileContent(uri, path, ref);
const blob = await gitOps.fileContent(uri, path, revision);
if (blob.isBinary()) {
return h.response(blob.content()).type('application/octet-stream');
} else {
Expand Down Expand Up @@ -164,6 +168,7 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {

async function historyHandler(req: hapi.Request) {
const { uri, ref, path } = req.params;
const revision = decodeRevisionString(ref);
const queries = req.query as RequestQuery;
const count = queries.count ? parseInt(queries.count as string, 10) : 10;
const after = queries.after !== undefined;
Expand All @@ -173,7 +178,7 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
return Boom.notFound(`repo ${uri} not found`);
}
const repository = await gitOps.openRepo(uri);
const commit = await gitOps.getCommit(uri, decodeURIComponent(ref));
const commit = await gitOps.getCommit(uri, revision);
const walk = repository.createRevWalk();
walk.sorting(Revwalk.SORT.TIME);
walk.push(commit.id());
Expand Down Expand Up @@ -238,7 +243,7 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
return Boom.notFound(`repo ${uri} not found`);
}
try {
const diff = await gitOps.getCommitDiff(uri, revision);
const diff = await gitOps.getCommitDiff(uri, decodeRevisionString(revision));
return diff;
} catch (e) {
if (e.isBoom) {
Expand All @@ -260,7 +265,11 @@ export function fileRoute(server: CodeServerRouter, gitOps: GitOperations) {
return Boom.notFound(`repo ${uri} not found`);
}
try {
const blames = await gitOps.blame(uri, decodeURIComponent(revision), path);
const blames = await gitOps.blame(
uri,
decodeRevisionString(decodeURIComponent(revision)),
path
);
return blames;
} catch (e) {
if (e.isBoom) {
Expand Down
34 changes: 34 additions & 0 deletions x-pack/test/functional/apps/code/explore_repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,40 @@ export default function exploreRepositoryFunctionalTests({
expect(await testSubjects.exists('codeNotFoundErrorPage')).ok();
});
});

it('goes to a branch of a project', async () => {
log.debug('it goes to a branch of the repo');
await retry.try(async () => {
expect(testSubjects.exists('codeBranchSelector'));
});
await testSubjects.click('codeBranchSelector');
const branch = 'addAzure';
const branchOptionSelector = `codeBranchSelectOption-${branch}`;
await retry.try(async () => {
expect(testSubjects.exists(branchOptionSelector));
});
await testSubjects.click(branchOptionSelector);
await retry.try(async () => {
const currentUrl: string = await browser.getCurrentUrl();
expect(currentUrl.indexOf(branch.replace(/\//g, ':'))).to.greaterThan(0);
expect(testSubjects.exists(`codeBranchSelectOption-${branch}Active`)).to.be.ok();
});
await retry.try(async () => {
expect(testSubjects.exists('codeBranchSelector'));
});
await testSubjects.click('codeBranchSelector');
const anotherBranch = 'noDatabase';
const anotherBranchOptionSelector = `codeBranchSelectOption-${anotherBranch}`;
await retry.try(async () => {
expect(testSubjects.exists(anotherBranchOptionSelector));
});
await testSubjects.click(anotherBranchOptionSelector);
await retry.try(async () => {
const currentUrl: string = await browser.getCurrentUrl();
expect(currentUrl.indexOf(anotherBranch.replace(/\//g, ':'))).to.greaterThan(0);
expect(testSubjects.exists(`codeBranchSelectOption-${anotherBranch}Active`)).to.be.ok();
});
});
});
});
}

0 comments on commit 0562b51

Please sign in to comment.