123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- import * as React from 'react';
- import {addErrorMessage, addSuccessMessage} from 'app/actionCreators/indicator';
- import {openModal} from 'app/actionCreators/modal';
- import AsyncComponent from 'app/components/asyncComponent';
- import IntegrationExternalMappingForm from 'app/components/integrationExternalMappingForm';
- import IntegrationExternalMappings from 'app/components/integrationExternalMappings';
- import {t} from 'app/locale';
- import {ExternalActorMapping, Integration, Organization, Team} from 'app/types';
- import withOrganization from 'app/utils/withOrganization';
- import FormModel from 'app/views/settings/components/forms/model';
- type Props = AsyncComponent['props'] & {
- integration: Integration;
- organization: Organization;
- };
- type State = AsyncComponent['state'] & {
- teams: Team[];
- queryResults: Team[];
- };
- class IntegrationExternalTeamMappings extends AsyncComponent<Props, State> {
- getDefaultState() {
- return {
- ...super.getDefaultState(),
- teams: [],
- queryResults: [],
- };
- }
- getEndpoints(): ReturnType<AsyncComponent['getEndpoints']> {
- const {organization} = this.props;
- return [
- [
- 'teams',
- `/organizations/${organization.slug}/teams/`,
- {query: {query: 'hasExternalTeams:true'}},
- ],
- ];
- }
- handleDelete = async (mapping: ExternalActorMapping) => {
- try {
- const {organization} = this.props;
- const {teams} = this.state;
- const team = teams.find(item => item.id === mapping.teamId);
- if (!team) {
- throw new Error('Cannot find correct team slug.');
- }
- const endpoint = `/teams/${organization.slug}/${team.slug}/external-teams/${mapping.id}/`;
- await this.api.requestPromise(endpoint, {
- method: 'DELETE',
- });
- // remove config and update state
- addSuccessMessage(t('Deletion successful'));
- this.fetchData();
- } catch {
- //no 4xx errors should happen on delete
- addErrorMessage(t('An error occurred'));
- }
- };
- handleSubmitSuccess = () => {
- this.fetchData();
- };
- get mappings() {
- const {integration} = this.props;
- const {teams} = this.state;
- const externalTeamMappings = teams.reduce((acc, team) => {
- const {externalTeams} = team;
- acc.push(
- ...externalTeams
- .filter(externalTeam => externalTeam.provider === integration.provider.key)
- .map(externalTeam => ({...externalTeam, sentryName: team.name}))
- );
- return acc;
- }, [] as ExternalActorMapping[]);
- return externalTeamMappings.sort((a, b) => parseInt(a.id, 10) - parseInt(b.id, 10));
- }
- sentryNamesMapper(teams: Team[]) {
- return teams.map(({id, name}) => ({id, name}));
- }
- handleSubmit = (
- data: Record<string, any>,
- onSubmitSuccess: (data: Record<string, any>) => void,
- onSubmitError: (error: any) => void,
- _: React.FormEvent<Element>,
- model: FormModel,
- mapping?: ExternalActorMapping
- ) => {
- // We need to dynamically set the endpoint bc it requires the slug of the selected team in the form.
- try {
- const {organization} = this.props;
- const {queryResults} = this.state;
- const team = queryResults.find(item => item.id === data.teamId);
- if (!team) {
- throw new Error('Cannot find team slug.');
- }
- const baseEndpoint = `/teams/${organization.slug}/${team.slug}/external-teams/`;
- const apiEndpoint = mapping ? `${baseEndpoint}${mapping.id}/` : baseEndpoint;
- const apiMethod = mapping ? 'PUT' : 'POST';
- model.setFormOptions({
- onSubmitSuccess,
- onSubmitError,
- apiEndpoint,
- apiMethod,
- });
- model.saveForm();
- } catch {
- //no 4xx errors should happen on delete
- addErrorMessage(t('An error occurred'));
- }
- };
- openModal = (mapping?: ExternalActorMapping) => {
- const {organization, integration} = this.props;
- openModal(({Body, Header, closeModal}) => (
- <React.Fragment>
- <Header closeButton>{t('Configure External Team Mapping')}</Header>
- <Body>
- <IntegrationExternalMappingForm
- organization={organization}
- integration={integration}
- onSubmitSuccess={() => {
- this.handleSubmitSuccess();
- closeModal();
- }}
- mapping={mapping}
- sentryNamesMapper={this.sentryNamesMapper}
- type="team"
- url={`/organizations/${organization.slug}/teams/`}
- onCancel={closeModal}
- onSubmit={(...args) => this.handleSubmit(...args, mapping)}
- onResults={results => this.setState({queryResults: results})}
- />
- </Body>
- </React.Fragment>
- ));
- };
- renderBody() {
- const {integration} = this.props;
- return (
- <IntegrationExternalMappings
- integration={integration}
- type="team"
- mappings={this.mappings}
- onCreateOrEdit={this.openModal}
- onDelete={this.handleDelete}
- />
- );
- }
- }
- export default withOrganization(IntegrationExternalTeamMappings);
|