import { upperFirst } from 'lodash';
import * as React from 'react';
import { Link } from 'react-router-dom';
import { Subject, Subscription } from 'rxjs';
import { catchError, filter, map, mapTo, startWith, switchMap, tap } from 'rxjs/operators';
import { gql, mutateGraphQL } from '../../backend/graphql';
import { FilteredConnection } from '../../components/FilteredConnection';
import { Timestamp } from '../../components/time/Timestamp';
import { userURL } from '../../user';
import { asError, createAggregateError, isErrorLike } from '../../util/errors';
import { AccessTokenCreatedAlert } from './AccessTokenCreatedAlert';
export const accessTokenFragment = gql `
    fragment AccessTokenFields on AccessToken {
        id
        scopes
        note
        createdAt
        lastUsedAt
        subject {
            username
        }
        creator {
            username
        }
    }
`;
function deleteAccessToken(tokenID) {
    return mutateGraphQL(gql `
            mutation DeleteAccessToken($tokenID: ID!) {
                deleteAccessToken(byID: $tokenID) {
                    alwaysNil
                }
            }
        `, { tokenID }).pipe(map(({ data, errors }) => {
        if (!data || !data.deleteAccessToken || (errors && errors.length > 0)) {
            throw createAggregateError(errors);
        }
    }));
}
export class AccessTokenNode extends React.PureComponent {
    constructor() {
        super(...arguments);
        this.state = { deletionOrError: null };
        this.deletes = new Subject();
        this.subscriptions = new Subscription();
        this.deleteAccessToken = () => this.deletes.next();
    }
    componentDidMount() {
        this.subscriptions.add(this.deletes
            .pipe(filter(() => window.confirm('Delete and revoke this token? Any clients using it will no longer be able to access the Sourcegraph API.')), switchMap(() => deleteAccessToken(this.props.node.id).pipe(mapTo(null), catchError(error => [asError(error)]), map(c => ({ deletionOrError: c })), tap(() => {
            if (this.props.onDidUpdate) {
                this.props.onDidUpdate();
            }
        }), startWith({ deletionOrError: undefined }))))
            .subscribe(stateUpdate => this.setState(stateUpdate), error => console.error(error)));
    }
    componentWillUnmount() {
        this.subscriptions.unsubscribe();
    }
    render() {
        const note = this.props.node.note || '(no description)';
        const loading = this.state.deletionOrError === undefined;
        return (React.createElement("li", { className: "list-group-item p-3 d-block" },
            React.createElement("div", { className: "d-flex w-100 justify-content-between" },
                React.createElement("div", { className: "mr-2" },
                    this.props.showSubject ? (React.createElement(React.Fragment, null,
                        React.createElement("strong", null,
                            React.createElement(Link, { to: userURL(this.props.node.subject.username) }, this.props.node.subject.username)),
                        ' ',
                        "\u2014 ",
                        note)) : (React.createElement("strong", null, note)),
                    ' ',
                    React.createElement("small", { className: "text-muted" },
                        ' ',
                        "\u2014 ",
                        React.createElement("em", null, this.props.node.scopes && this.props.node.scopes.join(', ')),
                        React.createElement("br", null),
                        this.props.node.lastUsedAt ? (React.createElement(React.Fragment, null,
                            "Last used ",
                            React.createElement(Timestamp, { date: this.props.node.lastUsedAt }))) : ('Never used'),
                        ", created ",
                        React.createElement(Timestamp, { date: this.props.node.createdAt }),
                        this.props.node.subject.username !== this.props.node.creator.username && (React.createElement(React.Fragment, null,
                            ' ',
                            "by",
                            ' ',
                            React.createElement(Link, { to: userURL(this.props.node.creator.username) }, this.props.node.creator.username))))),
                React.createElement("div", null,
                    React.createElement("button", { className: "btn btn-danger", onClick: this.deleteAccessToken, disabled: loading }, "Delete"),
                    isErrorLike(this.state.deletionOrError) && (React.createElement("div", { className: "alert alert-danger mt-2" },
                        "Error: ",
                        upperFirst(this.state.deletionOrError.message))))),
            this.props.newToken &&
                this.props.node.id === this.props.newToken.id && (React.createElement(AccessTokenCreatedAlert, { className: "alert alert-success mt-4", tokenSecret: this.props.newToken.token, token: this.props.node }))));
    }
}
export class FilteredAccessTokenConnection extends FilteredConnection {
}
//# sourceMappingURL=AccessTokenNode.js.map