diff --git a/LICENSE b/LICENSE index 5cac0ad6f3d13..331750698c211 100644 --- a/LICENSE +++ b/LICENSE @@ -16,7 +16,7 @@ Additional Use Grant: You may make use of the Licensed Work, provided that you d error-reporting or application monitoring features of the Licensed Work. -Change Date: 2026-08-15 +Change Date: 2026-09-19 Change License: Apache License, Version 2.0 diff --git a/gatsby-browser.tsx b/gatsby-browser.tsx index 7a9b945f6e4c2..7f4f7d31334ba 100644 --- a/gatsby-browser.tsx +++ b/gatsby-browser.tsx @@ -1,12 +1,16 @@ import React from 'react'; import {GatsbyBrowser} from 'gatsby'; +import {FeedbackWidgetLoader} from 'sentry-docs/components/feedback/feedbackWidgetLoader'; import PageContext from 'sentry-docs/components/pageContext'; export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = ({ element, props: {pageContext}, -}) => {element}; +}) => + + {element} + // Disable prefetching altogether so our bw is not destroyed. // If this turns out to hurt performance significantly, we can diff --git a/gatsby-ssr.tsx b/gatsby-ssr.tsx index 865768002530b..9d8bd11c4f78f 100644 --- a/gatsby-ssr.tsx +++ b/gatsby-ssr.tsx @@ -4,6 +4,7 @@ import React from 'react'; import {GatsbySSR} from 'gatsby'; +import {FeedbackWidgetLoader} from 'sentry-docs/components/feedback/feedbackWidgetLoader'; import {PageContext} from 'sentry-docs/components/pageContext'; const sentryEnvironment = process.env.GATSBY_ENV || process.env.NODE_ENV || 'development'; @@ -12,7 +13,12 @@ const sentryLoaderUrl = process.env.SENTRY_LOADER_URL; export const wrapPageElement: GatsbySSR['wrapPageElement'] = ({ element, props: {pageContext}, -}) => {element}; +}) => ( + + + {element} + +); export const onPreRenderHTML: GatsbySSR['onPreRenderHTML'] = ({getHeadComponents}) => { if (process.env.NODE_ENV !== 'production') { diff --git a/package.json b/package.json index 9c3110dd99972..5e50976cc7c45 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "@mdx-js/mdx": "^1.6.18", "@mdx-js/react": "^1.6.18", "@sentry-internal/global-search": "^0.5.7", - "@sentry/browser": "7.55.2", + "@sentry/browser": "7.69.0", + "@sentry/core": "7.69.0", "@sentry/webpack-plugin": "2.2.2", "@types/dompurify": "^3.0.2", "@types/js-cookie": "^3.0.3", diff --git a/src/components/feedback/feedbackButton.tsx b/src/components/feedback/feedbackButton.tsx new file mode 100644 index 0000000000000..8bc266d6fa05c --- /dev/null +++ b/src/components/feedback/feedbackButton.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import styled from '@emotion/styled'; + +const Button = styled.button` + position: fixed; + right: 0px; + bottom: 50%; + transform: translate(25%, 50%) rotate(-90deg); + background-color: #fff; + border: 1px solid #ccc; + border-radius: 4px; + color: #231c3d; + cursor: pointer; + font-size: 14px; + font-weight: 600; + padding: 6px 16px; + text-align: center; + text-decoration: none; + z-index: 9000; + &:hover { + background-color: #eee; + } + &:focus-visible { + outline: 1px solid #79628c; + background-color: #eee; + } +`; + +export function FeedbackButton(props) { + return ; +} diff --git a/src/components/feedback/feedbackForm.tsx b/src/components/feedback/feedbackForm.tsx new file mode 100644 index 0000000000000..5e1e4bb2bedfc --- /dev/null +++ b/src/components/feedback/feedbackForm.tsx @@ -0,0 +1,166 @@ +import React, {FormEvent, useRef} from 'react'; +import {css} from '@emotion/react'; +import styled from '@emotion/styled'; + +interface FeedbackFormProps { + onClose: () => void; + onSubmit: (data: {comment: string; email: string; name: string}) => void; +} + +const retrieveStringValue = (formData: FormData, key: string) => { + const value = formData.get(key); + if (typeof value === 'string') { + return value.trim(); + } + return ''; +}; + +export function FeedbackForm({onClose, onSubmit}: FeedbackFormProps) { + const formRef = useRef(null); + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + const formData = new FormData(e.target as HTMLFormElement); + onSubmit({ + name: retrieveStringValue(formData, 'name'), + email: retrieveStringValue(formData, 'email'), + comment: retrieveStringValue(formData, 'comment'), + }); + }; + + const user = window.Sentry?.getCurrentHub().getScope()?.getUser(); + + return ( +
+ + + + +