<commit_before>import {Box} from 'grid-emotion';
import PropTypes from 'prop-types';
import React from 'react';

import {
  Panel,
  PanelAlert,
  PanelBody,
  PanelHeader,
  PanelItem,
} from 'app/components/panels';
import {t} from 'app/locale';
import AsyncComponent from 'app/components/asyncComponent';
import Button from 'app/components/buttons/button';
import Confirm from 'app/components/confirm';
import DropdownAutoComplete from 'app/components/dropdownAutoComplete';
import DropdownButton from 'app/components/dropdownButton';
import EmptyMessage from 'app/views/settings/components/emptyMessage';
import IndicatorStore from 'app/stores/indicatorStore';
import ProjectBadge from 'app/components/idBadge/projectBadge';
import withProjects from 'app/utils/withProjects';

class IntegrationProjects extends AsyncComponent {
  static propTypes = {
    integrationId: PropTypes.string.isRequired,
  };

  static contextTypes = {
    organization: PropTypes.object.isRequired,
  };

  constructor(props, context) {
    super(props, context);
    this.state = {adding: false};
  }

  getEndpoints() {
    const orgId = this.context.organization.slug;
    const {integrationId} = this.props;

    return [['integration', `/organizations/${orgId}/integrations/${integrationId}/`]];
  }

  removeProject = project => {
    const orgId = this.context.organization.slug;
    const {integration} = this.state;
    const saveIndicator = IndicatorStore.add(t('Removing integration from %s', project));

    const options = {
      method: 'DELETE',
      success: () => {
        this.setState({
          integration: {
            ...integration,
            projects: integration.projects.filter(p => p !== project),
          },
        });
        IndicatorStore.addSuccess(t('Removed integration from %s', project));
      },
      error: () =>
        IndicatorStore.addError(t('Failed to remove integration from %s', project)),
      complete: () => IndicatorStore.remove(saveIndicator),
    };

    this.api.request(
      `/projects/${orgId}/${project}/integrations/${integration.id}/`,
      options
    );
  };

  addProject = ({value}) => {
    const project = value;
    const orgId = this.context.organization.slug;
    const {integration} = this.state;
    const saveIndicator = IndicatorStore.add(t('Adding integration to %s', project));
    this.setState({adding: true});

    const options = {
      method: 'PUT',
      success: () => {
        this.setState({
          integration: {
            ...integration,
            projects: [...integration.projects, project],
          },
        });
        IndicatorStore.addSuccess(t('Added integration to %s', project));
      },
      error: () => IndicatorStore.addError(t('Failed to add integration to %s', project)),
      complete: () => {
        IndicatorStore.remove(saveIndicator);
        this.setState({adding: false});
      },
    };

    this.api.request(
      `/projects/${orgId}/${project}/integrations/${integration.id}/`,
      options
    );
  };

  renderDropdown() {
    const enabled = new Set(this.context.organization.access).has('project:integrations');
    const items = this.props.projects
      .filter(p => !this.state.integration.projects.includes(p.slug))
      .map(p => ({
        searchKey: p.slug,
        value: p.slug,
        label: <ProjectBadge project={p} avatarSize={16} />,
      }));

    return (
      <DropdownAutoComplete
        items={items}
        onSelect={this.addProject}
        emptyMessage={t('Enabled for all projects')}
      >
        {({isOpen}) => (
          <DropdownButton
            size="xsmall"
            isOpen={isOpen}
            disabled={!enabled}
            busy={this.state.adding}
          >
            {t('Enable for Project')}
          </DropdownButton>
        )}
      </DropdownAutoComplete>
    );
  }

  renderBody() {
    const {integration} = this.state;
    const orgId = this.context.organization.slug;
    const projects = this.state.integration.projects.map(p => {
      return this.props.projects.find(pp => pp.slug === p);
    });

    return (
      <Panel>
        <PanelHeader disablePadding hasButtons>
          <Box pl={2}>{t('Projects')}</Box>
          <Box pr={1} style={{textTransform: 'none'}}>
            {this.renderDropdown()}
          </Box>
        </PanelHeader>
        <PanelAlert type="info">
          {t(
            'Adding the integration to a project will enable project specific ' +
              'integration functionality and configuration.'
          )}
        </PanelAlert>
        <PanelBody>
          {projects.length === 0 && (
            <EmptyMessage size="large">
              {t('Integration is not enabled for any Projects')}
            </EmptyMessage>
          )}
          {projects.map(project => (
            <PanelItem key={project.slug} align="center">
              <Box flex="1">
                <ProjectBadge project={project} avatarSize={16} />
              </Box>
              <Box pr={1}>
                <Button
                  to={`/settings/${orgId}/${project.slug}/integrations/${integration
                    .provider.key}/${integration.id}/`}
                  size="xsmall"
                >
                  {t('Configure')}
                </Button>
              </Box>
              <Box>
                <Confirm
                  onConfirm={() => this.removeProject(project.slug)}
                  message={
                    <React.Fragment>
                      <p>
                        <strong>
                          {t(
                            'Are you sure you want to remove the integration from %s?',
                            project.slug
                          )}}
                        </strong>
                      </p>
                      <p>
                        {t(
                          'Removing the this integration from the project will clear any project specific configurations and functionality for this project'
                        )}
                      </p>
                    </React.Fragment>
                  }
                >
                  <Button size="xsmall" icon="icon-circle-close" />
                </Confirm>
              </Box><commit_msg>fix(integrations): Remove trailing curly brace<commit_after>import {Box} from 'grid-emotion';
import PropTypes from 'prop-types';
import React from 'react';

import {
  Panel,
  PanelAlert,
  PanelBody,
  PanelHeader,
  PanelItem,
} from 'app/components/panels';
import {t} from 'app/locale';
import AsyncComponent from 'app/components/asyncComponent';
import Button from 'app/components/buttons/button';
import Confirm from 'app/components/confirm';
import DropdownAutoComplete from 'app/components/dropdownAutoComplete';
import DropdownButton from 'app/components/dropdownButton';
import EmptyMessage from 'app/views/settings/components/emptyMessage';
import IndicatorStore from 'app/stores/indicatorStore';
import ProjectBadge from 'app/components/idBadge/projectBadge';
import withProjects from 'app/utils/withProjects';

class IntegrationProjects extends AsyncComponent {
  static propTypes = {
    integrationId: PropTypes.string.isRequired,
  };

  static contextTypes = {
    organization: PropTypes.object.isRequired,
  };

  constructor(props, context) {
    super(props, context);
    this.state = {adding: false};
  }

  getEndpoints() {
    const orgId = this.context.organization.slug;
    const {integrationId} = this.props;

    return [['integration', `/organizations/${orgId}/integrations/${integrationId}/`]];
  }

  removeProject = project => {
    const orgId = this.context.organization.slug;
    const {integration} = this.state;
    const saveIndicator = IndicatorStore.add(t('Removing integration from %s', project));

    const options = {
      method: 'DELETE',
      success: () => {
        this.setState({
          integration: {
            ...integration,
            projects: integration.projects.filter(p => p !== project),
          },
        });
        IndicatorStore.addSuccess(t('Removed integration from %s', project));
      },
      error: () =>
        IndicatorStore.addError(t('Failed to remove integration from %s', project)),
      complete: () => IndicatorStore.remove(saveIndicator),
    };

    this.api.request(
      `/projects/${orgId}/${project}/integrations/${integration.id}/`,
      options
    );
  };

  addProject = ({value}) => {
    const project = value;
    const orgId = this.context.organization.slug;
    const {integration} = this.state;
    const saveIndicator = IndicatorStore.add(t('Adding integration to %s', project));
    this.setState({adding: true});

    const options = {
      method: 'PUT',
      success: () => {
        this.setState({
          integration: {
            ...integration,
            projects: [...integration.projects, project],
          },
        });
        IndicatorStore.addSuccess(t('Added integration to %s', project));
      },
      error: () => IndicatorStore.addError(t('Failed to add integration to %s', project)),
      complete: () => {
        IndicatorStore.remove(saveIndicator);
        this.setState({adding: false});
      },
    };

    this.api.request(
      `/projects/${orgId}/${project}/integrations/${integration.id}/`,
      options
    );
  };

  renderDropdown() {
    const enabled = new Set(this.context.organization.access).has('project:integrations');
    const items = this.props.projects
      .filter(p => !this.state.integration.projects.includes(p.slug))
      .map(p => ({
        searchKey: p.slug,
        value: p.slug,
        label: <ProjectBadge project={p} avatarSize={16} />,
      }));

    return (
      <DropdownAutoComplete
        items={items}
        onSelect={this.addProject}
        emptyMessage={t('Enabled for all projects')}
      >
        {({isOpen}) => (
          <DropdownButton
            size="xsmall"
            isOpen={isOpen}
            disabled={!enabled}
            busy={this.state.adding}
          >
            {t('Enable for Project')}
          </DropdownButton>
        )}
      </DropdownAutoComplete>
    );
  }

  renderBody() {
    const {integration} = this.state;
    const orgId = this.context.organization.slug;
    const projects = this.state.integration.projects.map(p => {
      return this.props.projects.find(pp => pp.slug === p);
    });

    return (
      <Panel>
        <PanelHeader disablePadding hasButtons>
          <Box pl={2}>{t('Projects')}</Box>
          <Box pr={1} style={{textTransform: 'none'}}>
            {this.renderDropdown()}
          </Box>
        </PanelHeader>
        <PanelAlert type="info">
          {t(
            'Adding the integration to a project will enable project specific ' +
              'integration functionality and configuration.'
          )}
        </PanelAlert>
        <PanelBody>
          {projects.length === 0 && (
            <EmptyMessage size="large">
              {t('Integration is not enabled for any Projects')}
            </EmptyMessage>
          )}
          {projects.map(project => (
            <PanelItem key={project.slug} align="center">
              <Box flex="1">
                <ProjectBadge project={project} avatarSize={16} />
              </Box>
              <Box pr={1}>
                <Button
                  to={`/settings/${orgId}/${project.slug}/integrations/${integration
                    .provider.key}/${integration.id}/`}
                  size="xsmall"
                >
                  {t('Configure')}
                </Button>
              </Box>
              <Box>
                <Confirm
                  onConfirm={() => this.removeProject(project.slug)}
                  message={
                    <React.Fragment>
                      <p>
                        <strong>
                          {t(
                            'Are you sure you want to remove the integration from %s?',
                            project.slug
                          )}
                        </strong>
                      </p>
                      <p>
                        {t(
                          'Removing the this integration from the project will clear any project specific configurations and functionality for this project'
                        )}
                      </p>
                    </React.Fragment>
                  }
                >
                  <Button size="xsmall" icon="icon-circle-close" />
                </Confirm>
              </Box>
{'fraction_non_alphanumeric': 0.13078758949880667, 'fraction_numerical': 0.001431980906921241, 'mean_word_length': 1.8998846597462515, 'pattern_counts': {'":': 0, '<': 79, '<?xml version=': 0, '>': 111, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5329260', 'n_tokens_mistral': 3369, 'n_tokens_neox': 3297, 'n_words': 705}