import { ActionsNavItems } from '@sourcegraph/extensions-client-common/lib/app/actions/ActionsNavItems';
import ChevronRightIcon from 'mdi-react/ChevronRightIcon';
import SettingsIcon from 'mdi-react/SettingsIcon';
import * as React from 'react';
import { ContributableMenu } from 'sourcegraph/module/protocol';
import { ActionItem } from '../components/ActionItem';
import { PopoverButton } from '../components/PopoverButton';
import { displayRepoPath, splitPath } from '../components/RepoFileLink';
import { isErrorLike } from '../util/errors';
import { RepositoriesPopover } from './RepositoriesPopover';
/**
 * Stores the list of RepoHeaderContributions, manages addition/deletion, and ensures they are sorted.
 *
 * It should be instantiated in a private field of the common ancestor component of RepoHeader and all components
 * needing to contribute to RepoHeader.
 */
class RepoHeaderContributionStore {
    constructor(
    /** The common ancestor component's setState method. */
    setState) {
        this.setState = setState;
        /** Props to pass to the owner's children (that need to contribute to RepoHeader). */
        this.props = {
            repoHeaderContributionsLifecycleProps: {
                onRepoHeaderContributionAdd: this.onRepoHeaderContributionAdd.bind(this),
                onRepoHeaderContributionRemove: this.onRepoHeaderContributionRemove.bind(this),
            },
        };
    }
    onRepoHeaderContributionAdd(item) {
        if (!item.element) {
            throw new Error(`RepoHeaderContribution has no element`);
        }
        if (typeof item.element.key !== 'string') {
            throw new Error(`RepoHeaderContribution (${item.element.type.toString()}) element must have a string key`);
        }
        this.setState((prevState) => ({
            repoHeaderContributions: prevState.repoHeaderContributions
                .filter(({ element }) => element.key !== item.element.key)
                .concat(item)
                .sort(byPriority),
        }));
    }
    onRepoHeaderContributionRemove(key) {
        this.setState(prevState => ({
            repoHeaderContributions: prevState.repoHeaderContributions.filter(c => c.element.key !== key),
        }));
    }
}
function byPriority(a, b) {
    return (b.priority || 0) - (a.priority || 0);
}
/**
 * The repository header with the breadcrumb, revision switcher, and other items.
 *
 * Other components can contribute items to the repository header using RepoHeaderContribution.
 */
export class RepoHeader extends React.PureComponent {
    constructor(props) {
        super(props);
        this.state = {
            repoHeaderContributions: [],
        };
        this.repoHeaderContributionStore = new RepoHeaderContributionStore(stateUpdate => this.setState(stateUpdate));
        props.onLifecyclePropsChange(this.repoHeaderContributionStore.props);
    }
    render() {
        const navActions = this.state.repoHeaderContributions.filter(({ position }) => position === 'nav');
        const leftActions = this.state.repoHeaderContributions.filter(({ position }) => position === 'left');
        const rightActions = this.state.repoHeaderContributions.filter(({ position }) => position === 'right');
        const [repoDir, repoBase] = splitPath(displayRepoPath(this.props.repo.name));
        const context = {
            repoName: this.props.repo.name,
            encodedRev: this.props.rev,
        };
        return (React.createElement("nav", { className: "repo-header navbar navbar-expand" },
            React.createElement("div", { className: "navbar-nav" },
                React.createElement(PopoverButton, { className: "repo-header__section-btn repo-header__repo", globalKeyBinding: "r", link: this.props.resolvedRev && !isErrorLike(this.props.resolvedRev)
                        ? this.props.resolvedRev.rootTreeURL
                        : this.props.repo.url, popoverElement: React.createElement(RepositoriesPopover, { currentRepo: this.props.repo.id, history: this.props.history, location: this.props.location }), hideOnChange: this.props.repo.name },
                    repoDir ? `${repoDir}/` : '',
                    React.createElement("span", { className: "repo-header__repo-basename" }, repoBase)),
                !this.props.repo.enabled && (React.createElement("div", { className: "alert alert-danger repo-header__alert", "data-tooltip": this.props.repo.viewerCanAdminister
                        ? 'Only site admins can access disabled repositories. Go to Settings to enable it.'
                        : 'Ask the site admin to enable this repository to view and search it.' }, "Repository disabled"))),
            navActions.map((a, i) => (React.createElement("div", { className: "navbar-nav", key: a.element.key || i },
                React.createElement(ChevronRightIcon, { className: "icon-inline repo-header__icon-chevron" }),
                React.createElement("div", { className: "repo-header__rev" }, a.element)))),
            React.createElement("ul", { className: "navbar-nav" }, leftActions.map((a, i) => (React.createElement("li", { className: "nav-item", key: a.element.key || i }, a.element)))),
            React.createElement("div", { className: "repo-header__spacer" }),
            React.createElement("ul", { className: "navbar-nav" },
                React.createElement(ActionsNavItems, { menu: ContributableMenu.EditorTitle, extensionsController: this.props.extensionsController, extensions: this.props.extensions }),
                this.props.actionButtons.map(({ condition = () => true, label, tooltip, icon: Icon, to }) => condition(context) && (React.createElement("li", { className: "nav-item", key: label },
                    React.createElement(ActionItem, { to: to(context), "data-tooltip": tooltip },
                        Icon && React.createElement(Icon, { className: "icon-inline" }),
                        ' ',
                        React.createElement("span", { className: "d-none d-lg-inline" }, label))))),
                rightActions.map((a, i) => (React.createElement("li", { className: "nav-item", key: a.element.key || i }, a.element))),
                this.props.repo.viewerCanAdminister && (React.createElement("li", { className: "nav-item" },
                    React.createElement(ActionItem, { to: `/${this.props.repo.name}/-/settings`, "data-tooltip": "Repository settings" },
                        React.createElement(SettingsIcon, { className: "icon-inline" }),
                        ' ',
                        React.createElement("span", { className: "d-none d-lg-inline" }, "Settings")))))));
    }
}
//# sourceMappingURL=RepoHeader.js.map