mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
142 lines
3.9 KiB
TypeScript
142 lines
3.9 KiB
TypeScript
import {Component} from 'react';
|
|
import * as qs from 'query-string';
|
|
|
|
import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
|
|
import {t} from 'sentry/locale';
|
|
import ConfigStore from 'sentry/stores/configStore';
|
|
import type {
|
|
IntegrationProvider,
|
|
IntegrationWithConfig,
|
|
Organization,
|
|
} from 'sentry/types';
|
|
import {trackIntegrationAnalytics} from 'sentry/utils/integrationUtil';
|
|
|
|
type Props = {
|
|
children: (
|
|
openDialog: (urlParams?: {[key: string]: string}) => void
|
|
) => React.ReactNode;
|
|
onInstall: (data: IntegrationWithConfig) => void;
|
|
organization: Organization;
|
|
provider: IntegrationProvider;
|
|
account?: string | null; // for analytics
|
|
analyticsParams?: {
|
|
already_installed: boolean;
|
|
view:
|
|
| 'integrations_directory_integration_detail'
|
|
| 'integrations_directory'
|
|
| 'onboarding'
|
|
| 'project_creation';
|
|
};
|
|
modalParams?: {[key: string]: string};
|
|
};
|
|
|
|
export default class AddIntegration extends Component<Props> {
|
|
componentDidMount() {
|
|
window.addEventListener('message', this.didReceiveMessage);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
window.removeEventListener('message', this.didReceiveMessage);
|
|
this.dialog?.close();
|
|
}
|
|
|
|
dialog: Window | null = null;
|
|
|
|
computeCenteredWindow(width: number, height: number) {
|
|
// Taken from: https://stackoverflow.com/questions/4068373/center-a-popup-window-on-screen
|
|
const screenLeft =
|
|
window.screenLeft !== undefined ? window.screenLeft : window.screenX;
|
|
|
|
const screenTop = window.screenTop !== undefined ? window.screenTop : window.screenY;
|
|
|
|
const innerWidth = window.innerWidth
|
|
? window.innerWidth
|
|
: document.documentElement.clientWidth
|
|
? document.documentElement.clientWidth
|
|
: screen.width;
|
|
|
|
const innerHeight = window.innerHeight
|
|
? window.innerHeight
|
|
: document.documentElement.clientHeight
|
|
? document.documentElement.clientHeight
|
|
: screen.height;
|
|
|
|
const left = innerWidth / 2 - width / 2 + screenLeft;
|
|
const top = innerHeight / 2 - height / 2 + screenTop;
|
|
|
|
return {left, top};
|
|
}
|
|
|
|
openDialog = (urlParams?: {[key: string]: string}) => {
|
|
const {account, analyticsParams, modalParams, organization, provider} = this.props;
|
|
|
|
trackIntegrationAnalytics('integrations.installation_start', {
|
|
integration: provider.key,
|
|
integration_type: 'first_party',
|
|
organization,
|
|
...analyticsParams,
|
|
});
|
|
const name = 'sentryAddIntegration';
|
|
const {url, width, height} = provider.setupDialog;
|
|
const {left, top} = this.computeCenteredWindow(width, height);
|
|
|
|
let query: {[key: string]: string} = {...urlParams};
|
|
|
|
if (account) {
|
|
query.account = account;
|
|
}
|
|
|
|
if (modalParams) {
|
|
query = {...query, ...modalParams};
|
|
}
|
|
|
|
const installUrl = `${url}?${qs.stringify(query)}`;
|
|
const opts = `scrollbars=yes,width=${width},height=${height},top=${top},left=${left}`;
|
|
|
|
this.dialog = window.open(installUrl, name, opts);
|
|
this.dialog?.focus();
|
|
};
|
|
|
|
didReceiveMessage = (message: MessageEvent) => {
|
|
const {analyticsParams, onInstall, organization, provider} = this.props;
|
|
const validOrigins = [
|
|
ConfigStore.get('links').sentryUrl,
|
|
ConfigStore.get('links').organizationUrl,
|
|
document.location.origin,
|
|
];
|
|
if (!validOrigins.includes(message.origin)) {
|
|
return;
|
|
}
|
|
|
|
if (message.source !== this.dialog) {
|
|
return;
|
|
}
|
|
|
|
const {success, data} = message.data;
|
|
this.dialog = null;
|
|
|
|
if (!success) {
|
|
addErrorMessage(data?.error ?? t('An unknown error occurred'));
|
|
return;
|
|
}
|
|
|
|
if (!data) {
|
|
return;
|
|
}
|
|
trackIntegrationAnalytics('integrations.installation_complete', {
|
|
integration: provider.key,
|
|
integration_type: 'first_party',
|
|
organization,
|
|
...analyticsParams,
|
|
});
|
|
addSuccessMessage(t('%s added', provider.name));
|
|
onInstall(data);
|
|
};
|
|
|
|
render() {
|
|
const {children} = this.props;
|
|
|
|
return children(this.openDialog);
|
|
}
|
|
}
|