Skip to content

Commit 8db78b0

Browse files
committed
convert to new defineIntegration method
1 parent 2daf36b commit 8db78b0

File tree

8 files changed

+415
-487
lines changed

8 files changed

+415
-487
lines changed

packages/feedback2/src/core/integration.ts

Lines changed: 246 additions & 283 deletions
Large diffs are not rendered by default.

packages/feedback2/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ export {
1717
feedback2ScreenshotIntegration,
1818
} from './screenshot/integration';
1919

20-
export type { OverrideFeedbackConfiguration } from './types/index';
20+
export type { OptionalFeedbackConfiguration } from './types';

packages/feedback2/src/modal/components/Form.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ import { h } from 'preact'; // eslint-disable-line @typescript-eslint/no-unused-
44
import type { JSX, VNode } from 'preact';
55
import { useCallback, useState } from 'preact/hooks';
66
import { FEEDBACK_WIDGET_SOURCE } from '../../constants';
7-
import type { ScreenshotWidget } from '../../screenshot/integration';
8-
import type { FeedbackFormData, FeedbackInternalOptions, SendFeedbackOptions, SendFeedbackParams } from '../../types';
7+
import type {
8+
FeedbackFormData,
9+
FeedbackInternalOptions,
10+
ScreenshotWidget,
11+
SendFeedbackOptions,
12+
SendFeedbackParams,
13+
} from '../../types';
914
import { DEBUG_BUILD } from '../../util/debug-build';
1015
import { getMissingFields } from '../../util/validate';
1116

@@ -127,7 +132,7 @@ export function Form({
127132

128133
return (
129134
<form class="form" onSubmit={handleSubmit}>
130-
{ScreenshotInput && includeScreenshot ? <ScreenshotInput initialImage={undefined} /> : null}
135+
{ScreenshotInput && includeScreenshot ? <ScreenshotInput /> : null}
131136

132137
<div class="form__right">
133138
<div class="form__top">
Lines changed: 77 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import { getCurrentScope } from '@sentry/core';
2-
import type { Integration, IntegrationFn } from '@sentry/types';
3-
import { isBrowser } from '@sentry/utils';
1+
import { convertIntegrationFnToClass, defineIntegration, getCurrentScope } from '@sentry/core';
2+
import type { Integration, IntegrationClass, IntegrationFn, IntegrationFnResult } from '@sentry/types';
43
import { h } from 'preact';
54
import type { sendFeedback as sendFeedbackFn } from '../core/sendFeedback';
6-
import type { Feedback2Screenshot } from '../screenshot/integration';
5+
import type { IFeedback2ScreenshotIntegration } from '../screenshot/integration';
76
import type { FeedbackFormData, FeedbackInternalOptions } from '../types';
87
import { Dialog } from './components/Dialog';
98
import type { DialogComponent } from './components/Dialog';
@@ -22,110 +21,86 @@ interface CreateDialogProps {
2221
*/
2322
onDone: () => void;
2423

25-
// eslint-disable-next-line deprecation/deprecation
26-
screenshotIntegration: Feedback2Screenshot | undefined;
24+
screenshotIntegration: IFeedback2ScreenshotIntegration | undefined;
2725
}
2826

29-
export const feedback2ModalIntegration = (() => {
30-
// eslint-disable-next-line deprecation/deprecation
31-
return new Feedback2Modal();
32-
}) satisfies IntegrationFn;
27+
interface PublicFeedback2ModalIntegration {
28+
createDialog: (props: CreateDialogProps) => DialogComponent;
29+
}
3330

34-
/**
35-
* TODO
36-
*
37-
* @deprecated Use `feedbackIntegration()` instead.
38-
*/
39-
export class Feedback2Modal implements Integration {
40-
/**
41-
* @inheritDoc
42-
*/
43-
public static id: string = 'Feedback2Modal';
31+
export type IFeedback2ModalIntegration = IntegrationFnResult & PublicFeedback2ModalIntegration;
4432

45-
/**
46-
* @inheritDoc
47-
*/
48-
public name: string;
33+
export const _feedback2ModalIntegration = (() => {
34+
return {
35+
name: 'Feedback2Modal',
36+
// eslint-disable-next-line @typescript-eslint/no-empty-function
37+
setupOnce() {},
38+
createDialog({ shadow, sendFeedback, options, onDone, screenshotIntegration }: CreateDialogProps): DialogComponent {
39+
const userKey = options.useSentryUser;
40+
const scope = getCurrentScope();
41+
const user = scope && scope.getUser();
4942

50-
public constructor() {
51-
// eslint-disable-next-line deprecation/deprecation
52-
this.name = Feedback2Modal.id;
53-
}
43+
const screenshotWidget = screenshotIntegration && screenshotIntegration.createWidget(h);
5444

55-
/**
56-
* Setup and initialize feedback container
57-
*/
58-
public setupOnce(): void {
59-
if (!isBrowser()) {
60-
return;
61-
}
45+
const dialog = Dialog({
46+
screenshotWidget,
47+
colorScheme: options.colorScheme,
48+
showBranding: options.showBranding,
49+
showName: options.showName || options.isNameRequired,
50+
showEmail: options.showEmail || options.isEmailRequired,
51+
isNameRequired: options.isNameRequired,
52+
isEmailRequired: options.isEmailRequired,
53+
formTitle: options.formTitle,
54+
cancelButtonLabel: options.cancelButtonLabel,
55+
submitButtonLabel: options.submitButtonLabel,
56+
emailLabel: options.emailLabel,
57+
emailPlaceholder: options.emailPlaceholder,
58+
messageLabel: options.messageLabel,
59+
messagePlaceholder: options.messagePlaceholder,
60+
nameLabel: options.nameLabel,
61+
namePlaceholder: options.namePlaceholder,
62+
defaultName: (userKey && user && user[userKey.name]) || '',
63+
defaultEmail: (userKey && user && user[userKey.email]) || '',
64+
successMessageText: options.successMessageText,
65+
onFormClose: () => {
66+
shadow.removeChild(dialog.el);
67+
shadow.removeChild(dialog.style);
68+
screenshotWidget && shadow.removeChild(screenshotWidget.style);
69+
onDone();
70+
options.onFormClose && options.onFormClose();
71+
},
72+
onSubmit: sendFeedback,
73+
onSubmitSuccess: (data: FeedbackFormData) => {
74+
options.onSubmitSuccess && options.onSubmitSuccess(data);
75+
},
76+
onSubmitError: (error: Error) => {
77+
options.onSubmitError && options.onSubmitError(error);
78+
},
79+
onFormSubmitted: () => {
80+
shadow.removeChild(dialog.el);
81+
shadow.removeChild(dialog.style);
82+
screenshotWidget && shadow.removeChild(screenshotWidget.style);
83+
onDone();
84+
options.onFormSubmitted && options.onFormSubmitted();
85+
},
86+
});
87+
shadow.appendChild(dialog.style);
88+
screenshotWidget && shadow.appendChild(screenshotWidget.style);
89+
shadow.appendChild(dialog.el);
90+
options.onFormOpen && options.onFormOpen();
6291

63-
// Nothing?
64-
}
65-
66-
/**
67-
*
68-
*/
69-
public createDialog({
70-
shadow,
71-
sendFeedback,
72-
options,
73-
onDone,
74-
screenshotIntegration,
75-
}: CreateDialogProps): DialogComponent {
76-
const userKey = options.useSentryUser;
77-
const scope = getCurrentScope();
78-
const user = scope && scope.getUser();
79-
80-
const screenshotWidget = screenshotIntegration && screenshotIntegration.createWidget(h);
92+
return dialog;
93+
},
94+
};
95+
}) satisfies IntegrationFn;
8196

82-
const dialog = Dialog({
83-
screenshotWidget,
84-
colorScheme: options.colorScheme,
85-
showBranding: options.showBranding,
86-
showName: options.showName || options.isNameRequired,
87-
showEmail: options.showEmail || options.isEmailRequired,
88-
isNameRequired: options.isNameRequired,
89-
isEmailRequired: options.isEmailRequired,
90-
formTitle: options.formTitle,
91-
cancelButtonLabel: options.cancelButtonLabel,
92-
submitButtonLabel: options.submitButtonLabel,
93-
emailLabel: options.emailLabel,
94-
emailPlaceholder: options.emailPlaceholder,
95-
messageLabel: options.messageLabel,
96-
messagePlaceholder: options.messagePlaceholder,
97-
nameLabel: options.nameLabel,
98-
namePlaceholder: options.namePlaceholder,
99-
defaultName: (userKey && user && user[userKey.name]) || '',
100-
defaultEmail: (userKey && user && user[userKey.email]) || '',
101-
successMessageText: options.successMessageText,
102-
onFormClose: () => {
103-
shadow.removeChild(dialog.el);
104-
shadow.removeChild(dialog.style);
105-
screenshotWidget && shadow.removeChild(screenshotWidget.style);
106-
onDone();
107-
options.onFormClose && options.onFormClose();
108-
},
109-
onSubmit: sendFeedback,
110-
onSubmitSuccess: (data: FeedbackFormData) => {
111-
options.onSubmitSuccess && options.onSubmitSuccess(data);
112-
},
113-
onSubmitError: (error: Error) => {
114-
options.onSubmitError && options.onSubmitError(error);
115-
},
116-
onFormSubmitted: () => {
117-
shadow.removeChild(dialog.el);
118-
shadow.removeChild(dialog.style);
119-
screenshotWidget && shadow.removeChild(screenshotWidget.style);
120-
onDone();
121-
options.onFormSubmitted && options.onFormSubmitted();
122-
},
123-
});
124-
shadow.appendChild(dialog.style);
125-
screenshotWidget && shadow.appendChild(screenshotWidget.style);
126-
shadow.appendChild(dialog.el);
127-
options.onFormOpen && options.onFormOpen();
97+
export const feedback2ModalIntegration = defineIntegration(_feedback2ModalIntegration);
12898

129-
return dialog;
130-
}
131-
}
99+
/**
100+
* @deprecated Use `feedback2ModalIntegration()` instead
101+
*/
102+
// eslint-disable-next-line deprecation/deprecation
103+
export const Feedback2Modal = convertIntegrationFnToClass(
104+
'Feedback2Modal',
105+
feedback2ModalIntegration,
106+
) as IntegrationClass<Integration & PublicFeedback2ModalIntegration>;

packages/feedback2/src/screenshot/components/ScreenshotInput.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import type { ComponentType, VNode, h as hType } from 'preact';
22
import { useEffect, useRef } from 'preact/hooks';
33

4-
export interface Props {
5-
initialImage: unknown;
6-
}
7-
84
// eslint-disable-next-line @typescript-eslint/no-unused-vars
9-
export function makeInput(h: typeof hType, canvasEl: HTMLCanvasElement): ComponentType<Props> {
10-
return function ScreenshotToggle({ initialImage }: Props): VNode {
11-
console.log({ initialImage, canvasEl }); // eslint-disable-line no-console
5+
export function makeInput(h: typeof hType, canvasEl: HTMLCanvasElement): ComponentType {
6+
return function ScreenshotToggle(): VNode {
7+
console.log({ canvasEl }); // eslint-disable-line no-console
128

139
const canvasContainerRef = useRef<HTMLDivElement>(null);
1410
useEffect(() => {
Lines changed: 48 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,57 @@
1-
import type { Attachment, Integration, IntegrationFn } from '@sentry/types';
2-
import { isBrowser } from '@sentry/utils';
3-
import type { ComponentType, h as hType } from 'preact';
1+
import { convertIntegrationFnToClass, defineIntegration } from '@sentry/core';
2+
import type { Attachment, Integration, IntegrationClass, IntegrationFn, IntegrationFnResult } from '@sentry/types';
3+
import type { h as hType } from 'preact';
44
import { DOCUMENT } from '../constants';
5+
import type { ScreenshotWidget } from '../types';
56
import { makeInput } from './components/ScreenshotInput';
6-
import type { Props as ScreenshotInputProps } from './components/ScreenshotInput';
77
import { createScreenshotInputStyles } from './components/ScreenshotInput.css';
88
import { makeToggle } from './components/ScreenshotToggle';
9-
import type { Props as ScreenshotToggleProps } from './components/ScreenshotToggle';
109

11-
export const feedback2ScreenshotIntegration = (() => {
12-
// eslint-disable-next-line deprecation/deprecation
13-
return new Feedback2Screenshot();
10+
interface PublicFeedback2ScreenshotIntegration {
11+
createWidget: (h: typeof hType) => ScreenshotWidget;
12+
}
13+
export type IFeedback2ScreenshotIntegration = IntegrationFnResult & PublicFeedback2ScreenshotIntegration;
14+
15+
export const _feedback2ScreenshotIntegration = (() => {
16+
return {
17+
name: 'Feedback2Screenshot',
18+
// eslint-disable-next-line @typescript-eslint/no-empty-function
19+
setupOnce() {},
20+
createWidget(h: typeof hType): ScreenshotWidget {
21+
const canvasEl = DOCUMENT.createElement('canvas');
22+
23+
return {
24+
style: createScreenshotInputStyles(),
25+
input: makeInput(h, canvasEl),
26+
toggle: makeToggle(h),
27+
value: async () => {
28+
const blob = await new Promise<Parameters<BlobCallback>[0]>(resolve => {
29+
canvasEl.toBlob(resolve, 'image/png');
30+
});
31+
if (blob) {
32+
const data = new Uint8Array(await blob.arrayBuffer());
33+
const attachment: Attachment = {
34+
data,
35+
filename: 'screenshot.png',
36+
contentType: 'application/png',
37+
// attachmentType?: string;
38+
};
39+
return attachment;
40+
}
41+
return;
42+
},
43+
};
44+
},
45+
};
1446
}) satisfies IntegrationFn;
1547

48+
export const feedback2ScreenshotIntegration = defineIntegration(_feedback2ScreenshotIntegration);
49+
1650
/**
17-
* TODO
18-
*
19-
* @deprecated Use `feedback2ScreenshotIntegration()` instead.
51+
* @deprecated Use `feedback2ScreenshotIntegration()` instead
2052
*/
21-
export class Feedback2Screenshot implements Integration {
22-
/**
23-
* @inheritDoc
24-
*/
25-
public static id: string = 'Feedback2Screenshot';
26-
27-
/**
28-
* @inheritDoc
29-
*/
30-
public name: string;
31-
32-
public constructor() {
33-
// eslint-disable-next-line deprecation/deprecation
34-
this.name = Feedback2Screenshot.id;
35-
}
36-
37-
/**
38-
* Setupand initialize feedback container
39-
*/
40-
public setupOnce(): void {
41-
if (!isBrowser()) {
42-
return;
43-
}
44-
// Nothing?
45-
}
46-
47-
/**
48-
*
49-
*/
50-
public createWidget(h: typeof hType): ScreenshotWidget {
51-
const canvasEl = DOCUMENT.createElement('canvas');
52-
53-
return {
54-
style: createScreenshotInputStyles(),
55-
input: makeInput(h, canvasEl),
56-
toggle: makeToggle(h),
57-
value: async () => {
58-
const blob = await new Promise<Parameters<BlobCallback>[0]>(resolve => {
59-
canvasEl.toBlob(resolve, 'image/png');
60-
});
61-
if (blob) {
62-
const data = new Uint8Array(await blob.arrayBuffer());
63-
const attachment: Attachment = {
64-
data,
65-
filename: 'screenshot.png',
66-
contentType: 'application/png',
67-
// attachmentType?: string;
68-
};
69-
return attachment;
70-
}
71-
return;
72-
},
73-
};
74-
}
75-
}
76-
77-
export interface ScreenshotWidget {
78-
style: HTMLStyleElement;
79-
input: ComponentType<ScreenshotInputProps>;
80-
toggle: ComponentType<ScreenshotToggleProps>;
81-
value: () => Promise<Attachment | undefined>;
82-
}
53+
// eslint-disable-next-line deprecation/deprecation
54+
export const Feedback2Screenshot = convertIntegrationFnToClass(
55+
'Feedback2Screenshot',
56+
feedback2ScreenshotIntegration,
57+
) as IntegrationClass<Integration & PublicFeedback2ScreenshotIntegration>;

0 commit comments

Comments
 (0)