import { LoadingSpinner } from '@sourcegraph/react-loading-spinner';
import { upperFirst } from 'lodash';
import ChevronRightIcon from 'mdi-react/ChevronRightIcon';
import * as React from 'react';
import { Link } from 'react-router-dom';
import { Subject, Subscription } from 'rxjs';
import { catchError, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
import { gql, queryGraphQL } from '../../backend/graphql';
import { PageTitle } from '../../components/PageTitle';
import { eventLogger } from '../../tracking/eventLogger';
import { createAggregateError, isErrorLike } from '../../util/errors';
import { memoizeObservable } from '../../util/memoize';
import { gitRefFragment, GitRefNode } from '../GitRef';
const queryGitBranches = memoizeObservable((args) => queryGraphQL(gql `
                query RepositoryGitBranchesOverview($repo: ID!, $first: Int!, $withBehindAhead: Boolean!) {
                    node(id: $repo) {
                        ... on Repository {
                            defaultBranch {
                                ...GitRefFields
                            }
                            gitRefs(first: $first, type: GIT_BRANCH, orderBy: AUTHORED_OR_COMMITTED_AT) {
                                nodes {
                                    ...GitRefFields
                                }
                                pageInfo {
                                    hasNextPage
                                }
                            }
                        }
                    }
                }
                ${gitRefFragment}
            `, Object.assign({}, args, { withBehindAhead: true })).pipe(map(({ data, errors }) => {
    if (!data || !data.node) {
        throw createAggregateError(errors);
    }
    const repo = data.node;
    if (!repo.gitRefs || !repo.gitRefs.nodes) {
        throw createAggregateError(errors);
    }
    return {
        defaultBranch: repo.defaultBranch,
        activeBranches: repo.gitRefs.nodes.filter(
        // Filter out default branch from activeBranches.
        ({ id }) => !repo.defaultBranch || repo.defaultBranch.id !== id),
        hasMoreActiveBranches: repo.gitRefs.pageInfo.hasNextPage,
    };
})), args => `${args.repo}:${args.first}`);
/** A page with an overview of the repository's branches. */
export class RepositoryBranchesOverviewPage extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = {};
        this.componentUpdates = new Subject();
        this.subscriptions = new Subscription();
    }
    componentDidMount() {
        eventLogger.logViewEvent('RepositoryBranchesOverview');
        this.subscriptions.add(this.componentUpdates
            .pipe(distinctUntilChanged((a, b) => a.repo.id === b.repo.id), switchMap(({ repo }) => {
            return queryGitBranches({ repo: repo.id, first: 10 }).pipe(catchError(error => [error]), map(c => ({ dataOrError: c })), startWith({ dataOrError: undefined }));
        }))
            .subscribe(stateUpdate => this.setState(stateUpdate), error => console.error(error)));
        this.componentUpdates.next(this.props);
    }
    componentWillUpdate(nextProps) {
        this.componentUpdates.next(nextProps);
    }
    componentWillUnmount() {
        this.subscriptions.unsubscribe();
    }
    render() {
        return (React.createElement("div", { className: "repository-branches-page" },
            React.createElement(PageTitle, { title: "Branches" }),
            this.state.dataOrError === undefined ? (React.createElement(LoadingSpinner, { className: "icon-inline mt-2" })) : isErrorLike(this.state.dataOrError) ? (React.createElement("div", { className: "alert alert-danger mt-2" },
                "Error: ",
                upperFirst(this.state.dataOrError.message))) : (React.createElement("div", { className: "repository-branches-page__cards" },
                this.state.dataOrError.defaultBranch && (React.createElement("div", { className: "card repository-branches-page__card" },
                    React.createElement("div", { className: "card-header" }, "Default branch"),
                    React.createElement("ul", { className: "list-group list-group-flush" },
                        React.createElement(GitRefNode, { node: this.state.dataOrError.defaultBranch })))),
                this.state.dataOrError.activeBranches.length > 0 && (React.createElement("div", { className: "card repository-branches-page__card" },
                    React.createElement("div", { className: "card-header" }, "Active branches"),
                    React.createElement("div", { className: "list-group list-group-flush" },
                        this.state.dataOrError.activeBranches.map((b, i) => (React.createElement(GitRefNode, { key: i, node: b }))),
                        this.state.dataOrError.hasMoreActiveBranches && (React.createElement(Link, { className: "list-group-item list-group-item-action py-2 d-flex", to: `/${this.props.repo.name}/-/branches/all` },
                            "View more branches",
                            React.createElement(ChevronRightIcon, { className: "icon-inline" }))))))))));
    }
}
//# sourceMappingURL=RepositoryBranchesOverviewPage.js.map