- Capture and share video recordings of co-browsing sessions with your team for product feedback and training.
+ {t(
+ 'Capture and share video recordings of co-browsing sessions with your team for product feedback and training.',
+ )}
- Enter your Environment ID, Client ID, Client Secret, and Account URN
- in the form below.
+ {t(
+ 'Enter your Environment ID, Client ID, Client Secret, and Account URN in the form below.',
+ )}
- Create a custom Log attribute openReplaySessionToken in Dynatrace.
+ {t(
+ 'Create a custom Log attribute openReplaySessionToken in Dynatrace.',
+ )}
- Propagate openReplaySessionToken in your application's backend logs.
+ {t(
+ "Propagate openReplaySessionToken in your application's backend logs.",
+ )}
{allIntegrations.map((integration, i) => (
- cat.integrations.includes(integration)
+ cat.integrations.includes(integration),
)?.title === 'Plugins'
? 500
- : 350
+ : 350,
)
}
hide={
@@ -167,31 +169,34 @@ function Integrations(props: Props) {
}
export default withPageTitle('Integrations - OpenReplay Preferences')(
- observer(Integrations)
+ observer(Integrations),
);
-const integrations = [
+const integrations = (t: TFunction) => [
{
- title: 'Issue Reporting',
+ title: t('Issue Reporting'),
key: 'issue-reporting',
- description:
+ description: t(
'Seamlessly report issues or share issues with your team right from OpenReplay.',
+ ),
isProject: false,
icon: 'exclamation-triangle',
integrations: [
{
- title: 'Jira',
- subtitle:
+ title: t('Jira'),
+ subtitle: t(
'Integrate Jira with OpenReplay to enable the creation of a new ticket directly from a session.',
+ ),
slug: 'jira',
category: 'Errors',
icon: 'integrations/jira',
component: ,
},
{
- title: 'Github',
- subtitle:
+ title: t('Github'),
+ subtitle: t(
'Integrate GitHub with OpenReplay to enable the direct creation of a new issue from a session.',
+ ),
slug: 'github',
category: 'Errors',
icon: 'integrations/github',
@@ -200,52 +205,58 @@ const integrations = [
],
},
{
- title: 'Backend Logging',
+ title: t('Backend Logging'),
key: 'backend-logging',
isProject: true,
icon: 'terminal',
- description:
+ description: t(
'Sync your backend errors with sessions replays and see what happened front-to-back.',
+ ),
docs: () => (
- Sync your backend errors with sessions replays and see what happened
- front-to-back.
+ {t(
+ 'Sync your backend errors with sessions replays and see what happened front-to-back.',
+ )}
),
integrations: [
{
- title: 'Sentry',
- subtitle:
+ title: t('Sentry'),
+ subtitle: t(
'Integrate Sentry with session replays to seamlessly observe backend errors.',
+ ),
slug: 'sentry',
icon: 'integrations/sentry',
component: ,
},
{
- title: 'Elasticsearch',
- subtitle:
+ title: t('Elasticsearch'),
+ subtitle: t(
'Integrate Elasticsearch with session replays to seamlessly observe backend errors.',
+ ),
slug: 'elasticsearch',
icon: 'integrations/elasticsearch',
component: ,
},
{
- title: 'Datadog',
- subtitle:
+ title: t('Datadog'),
+ subtitle: t(
'Incorporate DataDog to visualize backend errors alongside session replay, for easy troubleshooting.',
+ ),
slug: 'datadog',
icon: 'integrations/datadog',
component: ,
},
{
- title: 'Dynatrace',
- subtitle:
+ title: t('Dynatrace'),
+ subtitle: t(
'Integrate Dynatrace with session replays to link backend logs with user sessions for faster issue resolution.',
+ ),
slug: 'dynatrace',
icon: 'integrations/dynatrace',
useIcon: true,
@@ -254,17 +265,19 @@ const integrations = [
],
},
{
- title: 'Collaboration',
+ title: t('Collaboration'),
key: 'collaboration',
isProject: false,
icon: 'file-code',
- description:
+ description: t(
'Share your sessions with your team and collaborate on issues.',
+ ),
integrations: [
{
- title: 'Slack',
- subtitle:
+ title: t('Slack'),
+ subtitle: t(
'Integrate Slack to empower every user in your org with the ability to send sessions to any Slack channel.',
+ ),
slug: 'slack',
category: 'Errors',
icon: 'integrations/slack',
@@ -272,9 +285,10 @@ const integrations = [
shared: true,
},
{
- title: 'MS Teams',
- subtitle:
+ title: t('MS Teams'),
+ subtitle: t(
'Integrate MS Teams to empower every user in your org with the ability to send sessions to any MS Teams channel.',
+ ),
slug: 'msteams',
category: 'Errors',
icon: 'integrations/teams',
@@ -292,84 +306,95 @@ const integrations = [
// integrations: []
// },
{
- title: 'Plugins',
+ title: t('Plugins'),
key: 'plugins',
isProject: true,
icon: 'chat-left-text',
docs: () => (
- Plugins capture your application’s store, monitor queries, track
- performance issues and even assist your end user through live sessions.
+ {t(
+ 'Plugins capture your application’s store, monitor queries, track performance issues and even assist your end user through live sessions.',
+ )}
),
- description:
+ description: t(
"Reproduce issues as if they happened in your own browser. Plugins help capture your application's store, HTTP requeets, GraphQL queries, and more.",
+ ),
integrations: [
{
- title: 'Redux',
- subtitle:
+ title: t('Redux'),
+ subtitle: t(
'Capture Redux actions/state and inspect them later on while replaying session recordings.',
+ ),
icon: 'integrations/redux',
component: ,
},
{
- title: 'VueX',
- subtitle:
+ title: t('VueX'),
+ subtitle: t(
'Capture VueX mutations/state and inspect them later on while replaying session recordings.',
+ ),
icon: 'integrations/vuejs',
component: ,
},
{
- title: 'Pinia',
- subtitle:
+ title: t('Pinia'),
+ subtitle: t(
'Capture Pinia mutations/state and inspect them later on while replaying session recordings.',
+ ),
icon: 'integrations/pinia',
component: ,
},
{
- title: 'GraphQL',
- subtitle:
+ title: t('GraphQL'),
+ subtitle: t(
'Capture GraphQL requests and inspect them later on while replaying session recordings. This plugin is compatible with Apollo and Relay implementations.',
+ ),
icon: 'integrations/graphql',
component: ,
},
{
- title: 'NgRx',
- subtitle:
+ title: t('NgRx'),
+ subtitle: t(
'Capture NgRx actions/state and inspect them later on while replaying session recordings.\n',
+ ),
icon: 'integrations/ngrx',
component: ,
},
{
- title: 'MobX',
- subtitle:
+ title: t('MobX'),
+ subtitle: t(
'Capture MobX mutations and inspect them later on while replaying session recordings.',
+ ),
icon: 'integrations/mobx',
component: ,
},
{
- title: 'Profiler',
- subtitle:
+ title: t('Profiler'),
+ subtitle: t(
'Plugin allows you to measure your JS functions performance and capture both arguments and result for each call.',
+ ),
icon: 'integrations/openreplay',
component: ,
},
{
- title: 'Assist',
- subtitle:
+ title: t('Assist'),
+ subtitle: t(
'OpenReplay Assist allows you to support your users by seeing their live screen and instantly hopping on call (WebRTC) with them without requiring any 3rd-party screen sharing software.\n',
+ ),
icon: 'integrations/openreplay',
component: ,
},
{
- title: 'Zustand',
- subtitle:
+ title: t('Zustand'),
+ subtitle: t(
'Capture Zustand mutations/state and inspect them later on while replaying session recordings.',
+ ),
icon: 'integrations/zustand',
// header: '🐻',
component: ,
diff --git a/frontend/app/components/Client/Integrations/JiraForm/JiraForm.js b/frontend/app/components/Client/Integrations/JiraForm/JiraForm.js
deleted file mode 100644
index dc8f3e49f..000000000
--- a/frontend/app/components/Client/Integrations/JiraForm/JiraForm.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import React from 'react';
-import IntegrationForm from '../IntegrationForm';
-import DocLink from 'Shared/DocLink/DocLink';
-import { useModal } from 'App/components/Modal';
-import IntegrationModalCard from 'Components/Client/Integrations/IntegrationModalCard';
-
-const JiraForm = (props) => {
- const { hideModal } = useModal();
- return (
-
-
-
-
-
-
How it works?
-
-
Create a new API token
-
Enter the token below
-
-
-
-
-
-
-
-
-
- );
-};
-
-JiraForm.displayName = 'JiraForm';
-
-export default JiraForm;
diff --git a/frontend/app/components/Client/Integrations/JiraForm/JiraForm.tsx b/frontend/app/components/Client/Integrations/JiraForm/JiraForm.tsx
new file mode 100644
index 000000000..5e10ff540
--- /dev/null
+++ b/frontend/app/components/Client/Integrations/JiraForm/JiraForm.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import DocLink from 'Shared/DocLink/DocLink';
+import { useModal } from 'App/components/Modal';
+import IntegrationModalCard from 'Components/Client/Integrations/IntegrationModalCard';
+import IntegrationForm from '../IntegrationForm';
+import { useTranslation } from 'react-i18next';
+
+function JiraForm(props) {
+ const { t } = useTranslation();
+ const { hideModal } = useModal();
+ return (
+
+
+
+
+
{t('How it works?')}
+
+
{t('Create a new API token')}
+
{t('Enter the token below')}
+
+
+
+
+
+
+
+
+ );
+}
+
+JiraForm.displayName = 'JiraForm';
+
+export default JiraForm;
diff --git a/frontend/app/components/Client/Integrations/JiraForm/index.js b/frontend/app/components/Client/Integrations/JiraForm/index.js
index d914b3234..8f007bd52 100644
--- a/frontend/app/components/Client/Integrations/JiraForm/index.js
+++ b/frontend/app/components/Client/Integrations/JiraForm/index.js
@@ -1 +1 @@
-export { default } from './JiraForm';
\ No newline at end of file
+export { default } from './JiraForm';
diff --git a/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js b/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx
similarity index 58%
rename from frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js
rename to frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx
index 171224871..eb6013a7c 100644
--- a/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js
+++ b/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.tsx
@@ -1,16 +1,20 @@
-import { useStore } from "App/mstore";
+import { useStore } from 'App/mstore';
import React from 'react';
import { observer } from 'mobx-react-lite';
import { CodeBlock } from 'UI';
import DocLink from 'Shared/DocLink/DocLink';
import ToggleContent from 'Shared/ToggleContent';
+import { useTranslation } from 'react-i18next';
-const ProfilerDoc = () => {
+function ProfilerDoc() {
+ const { t } = useTranslation();
const { integrationsStore, projectsStore } = useStore();
const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
const usage = `import OpenReplay from '@openreplay/tracker';
import trackerProfiler from '@openreplay/tracker-profiler';
@@ -48,43 +52,45 @@ const fn = profiler('call_name')(() => {
className="bg-white h-screen overflow-y-auto"
style={{ width: '500px' }}
>
-
Profiler
+
{t('Profiler')}
- The profiler plugin allows you to measure your JS functions'
- performance and capture both arguments and result for each function
- call.
+ {t(
+ 'The profiler plugin allows you to measure your JS functions performance and capture both arguments and result for each function call',
+ )}
+ .
-
Installation
+
{t('Installation')}
-
Usage
+
{t('Usage')}
- Initialize the tracker and load the plugin into it. Then decorate any
- function inside your code with the generated function.
+ {t(
+ 'Initialize the tracker and load the plugin into it. Then decorate any function inside your code with the generated function.',
+ )}
- Integrate MS Teams with OpenReplay and share insights with the
- rest of the team, directly from the recording page.
+ {t('Integrate MS Teams with OpenReplay and share insights with the rest of the team, directly from the recording page.')}
- OpenReplay Assist allows you to support your users by seeing their live screen and instantly hopping on call (WebRTC) with them
- without requiring any 3rd-party screen sharing software.
-
+ {t(
+ 'OpenReplay Assist allows you to support your users by seeing their live screen and instantly hopping on call (WebRTC) with them without requiring any 3rd-party screen sharing software.',
+ )}
+
+
+
{t('Installation')}
+
+
+
+
{t('Usage')}
+ setActiveTab(tab)}
+ />
+
+
{renderActiveTab()}
+
+
+
+
+ );
+}
+
+AssistDoc.displayName = 'AssistDoc';
+
+export default observer(AssistDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx
index 00fe1cb26..30893ba95 100644
--- a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx
+++ b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistNpm.tsx
@@ -3,8 +3,10 @@ import React from 'react';
import { CodeBlock } from 'UI';
import ToggleContent from 'Shared/ToggleContent';
+import { useTranslation } from 'react-i18next';
function AssistNpm(props) {
+ const { t } = useTranslation();
const usage = `import OpenReplay from '@openreplay/tracker';
import trackerAssist from '@openreplay/tracker-assist';
const tracker = new OpenReplay({
@@ -56,21 +58,23 @@ type ButtonOptions = HTMLButtonElement | string | {
innerHTML?: string, // to pass an svg string or text
style?: StyleObject, // style object (i.e {color: 'red', borderRadius: '10px'})
}
-`
+`;
return (
- Initialize the tracker then load the @openreplay/tracker-assist plugin.
+ {t(
+ 'Initialize the tracker then load the @openreplay/tracker-assist plugin.',
+ )}
-
Usage
+
{t('Usage')}
}
second={}
/>
-
Options
+
{t('Options')}
);
diff --git a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistScript.tsx b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistScript.tsx
index 23ce8ff02..4db279dff 100644
--- a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistScript.tsx
+++ b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/AssistScript.tsx
@@ -1,7 +1,9 @@
import React from 'react';
-import { CodeBlock } from "UI";
+import { useTranslation } from 'react-i18next';
+import { CodeBlock } from 'UI';
function AssistScript(props) {
+ const { t } = useTranslation();
const scriptCode = `
`
+`;
return (
-
If your OpenReplay tracker is set up using the JS snippet, then simply replace the .../openreplay.js occurrence with .../openreplay-assist.js. Below is an example of how the script should like after the change:
+
+ {t(
+ 'If your OpenReplay tracker is set up using the JS snippet, then simply replace the .../openreplay.js occurrence with .../openreplay-assist.js. Below is an example of how the script should like after the change:',
+ )}
+
-
+
);
}
-export default AssistScript;
\ No newline at end of file
+export default AssistScript;
diff --git a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/index.js b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/index.js
index 6086d5389..8d1c447e9 100644
--- a/frontend/app/components/Client/Integrations/Tracker/AssistDoc/index.js
+++ b/frontend/app/components/Client/Integrations/Tracker/AssistDoc/index.js
@@ -1 +1 @@
-export { default } from './AssistDoc'
\ No newline at end of file
+export { default } from './AssistDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.js b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.js
deleted file mode 100644
index 889ecfd1f..000000000
--- a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.js
+++ /dev/null
@@ -1,75 +0,0 @@
-import { useStore } from "App/mstore";
-import React from 'react';
-import { CodeBlock } from "UI";
-import DocLink from 'Shared/DocLink/DocLink';
-import ToggleContent from 'Shared/ToggleContent';
-import { observer } from 'mobx-react-lite'
-
-const GraphQLDoc = () => {
- const { integrationsStore, projectsStore } = useStore();
- const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
- const usage = `import OpenReplay from '@openreplay/tracker';
-import trackerGraphQL from '@openreplay/tracker-graphql';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-tracker.start()
-//...
-export const recordGraphQL = tracker.use(trackerGraphQL());`
- const usageCjs = `import OpenReplay from '@openreplay/tracker/cjs';
-import trackerGraphQL from '@openreplay/tracker-graphql/cjs';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-//...
-function SomeFunctionalComponent() {
- useEffect(() => { // or componentDidMount in case of Class approach
- tracker.start()
- }, [])
-}
-//...
-export const recordGraphQL = tracker.use(trackerGraphQL());`
- return (
-
-
GraphQL
-
-
- This plugin allows you to capture GraphQL requests and inspect them later on while replaying session recordings. This is very
- useful for understanding and fixing issues.
-
-
GraphQL plugin is compatible with Apollo and Relay implementations.
-
-
Installation
-
-
-
Usage
-
- The plugin call will return the function, which receives four variables operationKind, operationName, variables and result. It
- returns result without changes.
-
-
-
-
-
- }
- second={
-
- }
- />
-
-
-
-
- );
-};
-
-GraphQLDoc.displayName = 'GraphQLDoc';
-
-export default observer(GraphQLDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx
new file mode 100644
index 000000000..e47ab0c4a
--- /dev/null
+++ b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/GraphQLDoc.tsx
@@ -0,0 +1,91 @@
+import { useStore } from 'App/mstore';
+import React from 'react';
+import { CodeBlock } from 'UI';
+import DocLink from 'Shared/DocLink/DocLink';
+import ToggleContent from 'Shared/ToggleContent';
+import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
+
+function GraphQLDoc() {
+ const { t } = useTranslation();
+ const { integrationsStore, projectsStore } = useStore();
+ const sites = projectsStore.list;
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
+ const usage = `import OpenReplay from '@openreplay/tracker';
+import trackerGraphQL from '@openreplay/tracker-graphql';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+tracker.start()
+//...
+export const recordGraphQL = tracker.use(trackerGraphQL());`;
+ const usageCjs = `import OpenReplay from '@openreplay/tracker/cjs';
+import trackerGraphQL from '@openreplay/tracker-graphql/cjs';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+//...
+function SomeFunctionalComponent() {
+ useEffect(() => { // or componentDidMount in case of Class approach
+ tracker.start()
+ }, [])
+}
+//...
+export const recordGraphQL = tracker.use(trackerGraphQL());`;
+ return (
+
+
{t('GraphQL')}
+
+
+ {t(
+ 'This plugin allows you to capture GraphQL requests and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
+
+
+ {t(
+ 'GraphQL plugin is compatible with Apollo and Relay implementations.',
+ )}
+
+
+
{t('Installation')}
+
+
+
{t('Usage')}
+
+ {t(
+ 'The plugin call will return the function, which receives four variables operationKind, operationName, variables and result. It returns result without changes.',
+ )}
+
+
+
+
+ }
+ second={}
+ />
+
+
+
+
+ );
+}
+
+GraphQLDoc.displayName = 'GraphQLDoc';
+
+export default observer(GraphQLDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/index.js b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/index.js
index 6fe38bba7..f7317d7d4 100644
--- a/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/index.js
+++ b/frontend/app/components/Client/Integrations/Tracker/GraphQLDoc/index.js
@@ -1 +1 @@
-export { default } from './GraphQLDoc'
\ No newline at end of file
+export { default } from './GraphQLDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.js b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.js
deleted file mode 100644
index 2541aae2b..000000000
--- a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import React from 'react';
-import ToggleContent from 'Shared/ToggleContent';
-import DocLink from 'Shared/DocLink/DocLink';
-import { CodeBlock } from "UI";
-import { useStore } from 'App/mstore';
-import { observer } from 'mobx-react-lite';
-
-const MobxDoc = () => {
- const { integrationsStore, projectsStore } = useStore();
- const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
-
- const mobxUsage = `import OpenReplay from '@openreplay/tracker';
-import trackerMobX from '@openreplay/tracker-mobx';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-tracker.use(trackerMobX()); // check list of available options below
-tracker.start();
-`
-
- const mobxUsageCjs = `import OpenReplay from '@openreplay/tracker/cjs';
-import trackerMobX from '@openreplay/tracker-mobx/cjs';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-tracker.use(trackerMobX()); // check list of available options below
-//...
-function SomeFunctionalComponent() {
- useEffect(() => { // or componentDidMount in case of Class approach
- tracker.start()
- }, [])
-}`
-
- return (
-
-
MobX
-
-
- This plugin allows you to capture MobX events and inspect them later on while replaying session recordings. This is very useful
- for understanding and fixing issues.
-
-
-
Installation
-
-
-
Usage
-
- Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put the generated middleware into your Redux
- chain.
-
-
-
-
Usage
- }
- second={}
- />
-
-
-
-
- );
-};
-
-MobxDoc.displayName = 'MobxDoc';
-
-export default observer(MobxDoc)
diff --git a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx
new file mode 100644
index 000000000..e31a25b86
--- /dev/null
+++ b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/MobxDoc.tsx
@@ -0,0 +1,88 @@
+import React from 'react';
+import ToggleContent from 'Shared/ToggleContent';
+import DocLink from 'Shared/DocLink/DocLink';
+import { CodeBlock } from 'UI';
+import { useStore } from 'App/mstore';
+import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
+
+function MobxDoc() {
+ const { t } = useTranslation();
+ const { integrationsStore, projectsStore } = useStore();
+ const sites = projectsStore.list;
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
+
+ const mobxUsage = `import OpenReplay from '@openreplay/tracker';
+import trackerMobX from '@openreplay/tracker-mobx';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+tracker.use(trackerMobX()); // check list of available options below
+tracker.start();
+`;
+
+ const mobxUsageCjs = `import OpenReplay from '@openreplay/tracker/cjs';
+import trackerMobX from '@openreplay/tracker-mobx/cjs';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+tracker.use(trackerMobX()); // check list of available options below
+//...
+function SomeFunctionalComponent() {
+ useEffect(() => { // or componentDidMount in case of Class approach
+ tracker.start()
+ }, [])
+}`;
+
+ return (
+
+
{t('MobX')}
+
+
+ {t(
+ 'This plugin allows you to capture MobX events and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
+
+
+
{t('Installation')}
+
+
+
{t('Usage')}
+
+ {t(
+ 'Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put the generated middleware into your Redux chain.',
+ )}
+
+
+
+
{t('Usage')}
+ }
+ second={}
+ />
+
+
+
+
+ );
+}
+
+MobxDoc.displayName = 'MobxDoc';
+
+export default observer(MobxDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/index.js b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/index.js
index 51b6dedae..ed631b7b7 100644
--- a/frontend/app/components/Client/Integrations/Tracker/MobxDoc/index.js
+++ b/frontend/app/components/Client/Integrations/Tracker/MobxDoc/index.js
@@ -1 +1 @@
-export { default } from './MobxDoc'
\ No newline at end of file
+export { default } from './MobxDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.js b/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.js
deleted file mode 100644
index f960918b6..000000000
--- a/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import { useStore } from "App/mstore";
-import React from 'react';
-import { CodeBlock } from "UI";
-import ToggleContent from 'Shared/ToggleContent';
-import DocLink from 'Shared/DocLink/DocLink';
-import { observer } from 'mobx-react-lite'
-
-const NgRxDoc = () => {
- const { integrationsStore, projectsStore } = useStore();
- const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
- const usage = `import { StoreModule } from '@ngrx/store';
-import { reducers } from './reducers';
-import OpenReplay from '@openreplay/tracker';
-import trackerNgRx from '@openreplay/tracker-ngrx';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-tracker.start()
-//...
-const metaReducers = [tracker.use(trackerNgRx())]; // check list of available options below
-//...
-@NgModule({
- imports: [StoreModule.forRoot(reducers, { metaReducers })]
-})
-export class AppModule {}`
- const usageCjs = `import { StoreModule } from '@ngrx/store';
-import { reducers } from './reducers';
-import OpenReplay from '@openreplay/tracker/cjs';
-import trackerNgRx from '@openreplay/tracker-ngrx/cjs';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-//...
-function SomeFunctionalComponent() {
- useEffect(() => { // or componentDidMount in case of Class approach
- tracker.start()
- }, [])
-//...
-const metaReducers = [tracker.use(trackerNgRx())]; // check list of available options below
-//...
- @NgModule({
- imports: [StoreModule.forRoot(reducers, { metaReducers })]
- })
- export class AppModule {}
-}`
- return (
-
-
NgRx
-
-
- This plugin allows you to capture NgRx actions/state and inspect them later on while replaying session recordings. This is very
- useful for understanding and fixing issues.
-
-
-
Installation
-
-
-
Usage
-
Add the generated meta-reducer into your imports. See NgRx documentation for more details.
-
-
-
Usage
-
- }
- second={
-
- }
- />
-
-
-
-
- );
-};
-
-NgRxDoc.displayName = 'NgRxDoc';
-
-export default observer(NgRxDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx
new file mode 100644
index 000000000..d1401899f
--- /dev/null
+++ b/frontend/app/components/Client/Integrations/Tracker/NgRxDoc/NgRxDoc.tsx
@@ -0,0 +1,100 @@
+import { useStore } from 'App/mstore';
+import React from 'react';
+import { CodeBlock } from 'UI';
+import ToggleContent from 'Shared/ToggleContent';
+import DocLink from 'Shared/DocLink/DocLink';
+import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
+
+function NgRxDoc() {
+ const { t } = useTranslation();
+ const { integrationsStore, projectsStore } = useStore();
+ const sites = projectsStore.list;
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
+ const usage = `import { StoreModule } from '@ngrx/store';
+import { reducers } from './reducers';
+import OpenReplay from '@openreplay/tracker';
+import trackerNgRx from '@openreplay/tracker-ngrx';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+tracker.start()
+//...
+const metaReducers = [tracker.use(trackerNgRx())]; // check list of available options below
+//...
+@NgModule({
+ imports: [StoreModule.forRoot(reducers, { metaReducers })]
+})
+export class AppModule {}`;
+ const usageCjs = `import { StoreModule } from '@ngrx/store';
+import { reducers } from './reducers';
+import OpenReplay from '@openreplay/tracker/cjs';
+import trackerNgRx from '@openreplay/tracker-ngrx/cjs';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+//...
+function SomeFunctionalComponent() {
+ useEffect(() => { // or componentDidMount in case of Class approach
+ tracker.start()
+ }, [])
+//...
+const metaReducers = [tracker.use(trackerNgRx())]; // check list of available options below
+//...
+ @NgModule({
+ imports: [StoreModule.forRoot(reducers, { metaReducers })]
+ })
+ export class AppModule {}
+}`;
+ return (
+
+
{t('NgRx')}
+
+
+ {t(
+ 'This plugin allows you to capture NgRx actions/state and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
+
+
+
{t('Installation')}
+
+
+
{t('Usage')}
+
+ {t(
+ 'Add the generated meta-reducer into your imports. See NgRx documentation for more details.',
+ )}
+
- This plugin allows you to capture Pinia mutations + state and inspect
- them later on while replaying session recordings. This is very useful
- for understanding and fixing issues.
+ {t(
+ 'This plugin allows you to capture Pinia mutations + state and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
-
Installation
+
{t('Installation')}
-
Usage
+
{t('Usage')}
- Initialize the @openreplay/tracker package as usual and load the
- plugin into it. Then put the generated plugin into your plugins field
- of your store.
+ {t(
+ 'Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put the generated plugin into your plugins field of your store.',
+ )}
}
second={}
/>
);
-};
+}
PiniaDoc.displayName = 'PiniaDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/index.js b/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/index.js
index 730c76beb..95010dbc2 100644
--- a/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/index.js
+++ b/frontend/app/components/Client/Integrations/Tracker/PiniaDoc/index.js
@@ -1 +1 @@
-export { default } from './PiniaDoc'
+export { default } from './PiniaDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.js b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.js
deleted file mode 100644
index 5c69bec47..000000000
--- a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { useStore } from "App/mstore";
-import React from 'react';
-import { CodeBlock } from 'UI'
-import ToggleContent from 'Components/shared/ToggleContent';
-import DocLink from 'Shared/DocLink/DocLink';
-import { observer } from 'mobx-react-lite'
-
-const ReduxDoc = () => {
- const { integrationsStore, projectsStore } = useStore();
- const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
-
- const usage = `import { applyMiddleware, createStore } from 'redux';
-import OpenReplay from '@openreplay/tracker';
-import trackerRedux from '@openreplay/tracker-redux';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-tracker.start()
-//...
-const store = createStore(
- reducer,
- applyMiddleware(tracker.use(trackerRedux())) // check list of available options below
-);`
- const usageCjs = `import { applyMiddleware, createStore } from 'redux';
-import OpenReplay from '@openreplay/tracker/cjs';
-import trackerRedux from '@openreplay/tracker-redux/cjs';
-//...
-const tracker = new OpenReplay({
- projectKey: '${projectKey}'
-});
-//...
-function SomeFunctionalComponent() {
- useEffect(() => { // or componentDidMount in case of Class approach
- tracker.start()
- }, [])
-//...
-const store = createStore(
- reducer,
- applyMiddleware(tracker.use(trackerRedux())) // check list of available options below
- );
-}`
- return (
-
-
Redux
-
-
-
- This plugin allows you to capture Redux actions/state and inspect them later on while replaying session recordings. This is very
- useful for understanding and fixing issues.
-
-
-
Installation
-
-
-
Usage
-
Initialize the tracker then put the generated middleware into your Redux chain.
-
-
- }
- second={
-
- }
- />
-
-
-
-
- );
-};
-
-ReduxDoc.displayName = 'ReduxDoc';
-
-export default observer(ReduxDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx
new file mode 100644
index 000000000..35c2ad37a
--- /dev/null
+++ b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/ReduxDoc.tsx
@@ -0,0 +1,94 @@
+import { useStore } from 'App/mstore';
+import React from 'react';
+import { CodeBlock } from 'UI';
+import ToggleContent from 'Components/shared/ToggleContent';
+import DocLink from 'Shared/DocLink/DocLink';
+import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
+
+function ReduxDoc() {
+ const { t } = useTranslation();
+ const { integrationsStore, projectsStore } = useStore();
+ const sites = projectsStore.list;
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
+
+ const usage = `import { applyMiddleware, createStore } from 'redux';
+import OpenReplay from '@openreplay/tracker';
+import trackerRedux from '@openreplay/tracker-redux';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+tracker.start()
+//...
+const store = createStore(
+ reducer,
+ applyMiddleware(tracker.use(trackerRedux())) // check list of available options below
+);`;
+ const usageCjs = `import { applyMiddleware, createStore } from 'redux';
+import OpenReplay from '@openreplay/tracker/cjs';
+import trackerRedux from '@openreplay/tracker-redux/cjs';
+//...
+const tracker = new OpenReplay({
+ projectKey: '${projectKey}'
+});
+//...
+function SomeFunctionalComponent() {
+ useEffect(() => { // or componentDidMount in case of Class approach
+ tracker.start()
+ }, [])
+//...
+const store = createStore(
+ reducer,
+ applyMiddleware(tracker.use(trackerRedux())) // check list of available options below
+ );
+}`;
+ return (
+
+
{t('Redux')}
+
+
+
+ {t(
+ 'This plugin allows you to capture Redux actions/state and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
+
+
+
{t('Installation')}
+
+
+
{t('Usage')}
+
+ {t(
+ 'Initialize the tracker then put the generated middleware into your Redux chain.',
+ )}
+
+
+ }
+ second={}
+ />
+
+
+
+
+ );
+}
+
+ReduxDoc.displayName = 'ReduxDoc';
+
+export default observer(ReduxDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/index.js b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/index.js
index 3c6245bd8..76c8271d4 100644
--- a/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/index.js
+++ b/frontend/app/components/Client/Integrations/Tracker/ReduxDoc/index.js
@@ -1 +1 @@
-export { default } from './ReduxDoc'
\ No newline at end of file
+export { default } from './ReduxDoc.tsx';
diff --git a/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.js b/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx
similarity index 52%
rename from frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.js
rename to frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx
index f9e23c67a..b32e9f1f4 100644
--- a/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.js
+++ b/frontend/app/components/Client/Integrations/Tracker/VueDoc/VueDoc.tsx
@@ -1,15 +1,19 @@
-import { useStore } from "App/mstore";
+import { useStore } from 'App/mstore';
import React from 'react';
-import { CodeBlock } from "UI";
+import { CodeBlock } from 'UI';
import ToggleContent from 'Components/shared/ToggleContent';
import DocLink from 'Shared/DocLink/DocLink';
import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
-const VueDoc = () => {
+function VueDoc() {
+ const { t } = useTranslation();
const { integrationsStore, projectsStore } = useStore();
const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
const usage = `import Vuex from 'vuex'
import OpenReplay from '@openreplay/tracker';
@@ -23,7 +27,7 @@ tracker.start()
const store = new Vuex.Store({
//...
plugins: [tracker.use(trackerVuex())] // check list of available options below
-});`
+});`;
const usageCjs = `import Vuex from 'vuex'
import OpenReplay from '@openreplay/tracker/cjs';
import trackerVuex from '@openreplay/tracker-vuex/cjs';
@@ -41,45 +45,49 @@ const store = new Vuex.Store({
//...
plugins: [tracker.use(trackerVuex())] // check list of available options below
});
-}`
+}`;
return (
-
-
VueX
+
+
{t('VueX')}
- This plugin allows you to capture VueX mutations/state and inspect them later on while
- replaying session recordings. This is very useful for understanding and fixing issues.
+ {t(
+ 'This plugin allows you to capture VueX mutations/state and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
-
Installation
-
+
{t('Installation')}
+
-
Usage
+
{t('Usage')}
- Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put
- the generated plugin into your plugins field of your store.
+ {t(
+ 'Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put the generated plugin into your plugins field of your store.',
+ )}
);
-};
+}
VueDoc.displayName = 'VueDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/VueDoc/index.js b/frontend/app/components/Client/Integrations/Tracker/VueDoc/index.js
index 555e8acfb..b50d6d1dd 100644
--- a/frontend/app/components/Client/Integrations/Tracker/VueDoc/index.js
+++ b/frontend/app/components/Client/Integrations/Tracker/VueDoc/index.js
@@ -1 +1 @@
-export { default } from './VueDoc'
\ No newline at end of file
+export { default } from './VueDoc';
diff --git a/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.js b/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.js
deleted file mode 100644
index eb7dcd091..000000000
--- a/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.js
+++ /dev/null
@@ -1,104 +0,0 @@
-import { useStore } from "App/mstore";
-import React from 'react';
-import { CodeBlock } from "UI";
-import ToggleContent from 'Components//shared/ToggleContent';
-import DocLink from 'Shared/DocLink/DocLink';
-import { observer } from 'mobx-react-lite'
-
-const ZustandDoc = (props) => {
- const { integrationsStore, projectsStore } = useStore();
- const sites = projectsStore.list;
- const siteId = integrationsStore.integrations.siteId
- const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey
-
- const usage = `import create from "zustand";
-import Tracker from '@openreplay/tracker';
-import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand';
-
-
-const tracker = new Tracker({
- projectKey: ${projectKey},
-});
-
-// as per https://docs.pmnd.rs/zustand/guides/typescript#middleware-that-doesn't-change-the-store-type
-// cast type to new one
-// but this seems to not be required and everything is working as is
-const zustandPlugin = tracker.use(trackerZustand()) as unknown as StateLogger
-
-
-const useBearStore = create(
- zustandPlugin((set: any) => ({
- bears: 0,
- increasePopulation: () => set((state: any) => ({ bears: state.bears + 1 })),
- removeAllBears: () => set({ bears: 0 }),
- }),
- // store name is optional
- // and is randomly generated if undefined
- 'bear_store'
- )
-)
-`
- const usageCjs =`import create from "zustand";
-import Tracker from '@openreplay/tracker/cjs';
-import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand/cjs';
-
-
-const tracker = new Tracker({
- projectKey: ${projectKey},
-});
-
-// as per https://docs.pmnd.rs/zustand/guides/typescript#middleware-that-doesn't-change-the-store-type
-// cast type to new one
-// but this seems to not be required and everything is working as is
-const zustandPlugin = tracker.use(trackerZustand()) as unknown as StateLogger
-
-
-const useBearStore = create(
- zustandPlugin((set: any) => ({
- bears: 0,
- increasePopulation: () => set((state: any) => ({ bears: state.bears + 1 })),
- removeAllBears: () => set({ bears: 0 }),
- }),
- // store name is optional
- // and is randomly generated if undefined
- 'bear_store'
- )
-)`
- return (
-
-
Zustand
-
-
- This plugin allows you to capture Zustand mutations/state and inspect them later on while replaying session recordings. This is very
- useful for understanding and fixing issues.
-
-
-
Installation
-
-
-
Usage
-
- Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put the generated plugin into your plugins
- field of your store.
-
-
-
-
- }
- second={
-
- }
- />
-
-
-
-
- );
-};
-
-ZustandDoc.displayName = 'ZustandDoc';
-
-export default observer(ZustandDoc);
diff --git a/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx b/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx
new file mode 100644
index 000000000..b25f40dd6
--- /dev/null
+++ b/frontend/app/components/Client/Integrations/Tracker/ZustandDoc/ZustandDoc.tsx
@@ -0,0 +1,116 @@
+import { useStore } from 'App/mstore';
+import React from 'react';
+import { CodeBlock } from 'UI';
+import ToggleContent from 'Components//shared/ToggleContent';
+import DocLink from 'Shared/DocLink/DocLink';
+import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
+
+function ZustandDoc(props) {
+ const { t } = useTranslation();
+ const { integrationsStore, projectsStore } = useStore();
+ const sites = projectsStore.list;
+ const { siteId } = integrationsStore.integrations;
+ const projectKey = siteId
+ ? sites.find((site) => site.id === siteId)?.projectKey
+ : sites[0]?.projectKey;
+
+ const usage = `import create from "zustand";
+import Tracker from '@openreplay/tracker';
+import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand';
+
+
+const tracker = new Tracker({
+ projectKey: ${projectKey},
+});
+
+// as per https://docs.pmnd.rs/zustand/guides/typescript#middleware-that-doesn't-change-the-store-type
+// cast type to new one
+// but this seems to not be required and everything is working as is
+const zustandPlugin = tracker.use(trackerZustand()) as unknown as StateLogger
+
+
+const useBearStore = create(
+ zustandPlugin((set: any) => ({
+ bears: 0,
+ increasePopulation: () => set((state: any) => ({ bears: state.bears + 1 })),
+ removeAllBears: () => set({ bears: 0 }),
+ }),
+ // store name is optional
+ // and is randomly generated if undefined
+ 'bear_store'
+ )
+)
+`;
+ const usageCjs = `import create from "zustand";
+import Tracker from '@openreplay/tracker/cjs';
+import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand/cjs';
+
+
+const tracker = new Tracker({
+ projectKey: ${projectKey},
+});
+
+// as per https://docs.pmnd.rs/zustand/guides/typescript#middleware-that-doesn't-change-the-store-type
+// cast type to new one
+// but this seems to not be required and everything is working as is
+const zustandPlugin = tracker.use(trackerZustand()) as unknown as StateLogger
+
+
+const useBearStore = create(
+ zustandPlugin((set: any) => ({
+ bears: 0,
+ increasePopulation: () => set((state: any) => ({ bears: state.bears + 1 })),
+ removeAllBears: () => set({ bears: 0 }),
+ }),
+ // store name is optional
+ // and is randomly generated if undefined
+ 'bear_store'
+ )
+)`;
+ return (
+
+
{t('Zustand')}
+
+
+ {t(
+ 'This plugin allows you to capture Zustand mutations/state and inspect them later on while replaying session recordings. This is very useful for understanding and fixing issues.',
+ )}
+
+
+
{t('Installation')}
+
+
+
{t('Usage')}
+
+ {t(
+ 'Initialize the @openreplay/tracker package as usual and load the plugin into it. Then put the generated plugin into your plugins field of your store.',
+ )}
+
{'Your email address is your identity on OpenReplay and is used to login.'}
+
{t('Profile')}
+
+ {t(
+ 'Your email address is your identity on OpenReplay and is used to login.',
+ )}
+
@@ -34,8 +40,10 @@ function ProfileSettings() {
<>
-
{'Change Password'}
-
{'Updating your password from time to time enhances your account’s security.'}
+
{t('Change Password')}
+
+ {t('Updating your password from time to time enhances your account’s security.')}
+
@@ -48,8 +56,10 @@ function ProfileSettings() {
-
{'Organization API Key'}
-
{'Your API key gives you access to an extra set of services.'}
+
{t('Organization API Key')}
+
+ {t('Your API key gives you access to an extra set of services.')}
+
@@ -61,8 +71,10 @@ function ProfileSettings() {
-
{'Tenant Key'}
-
{'For SSO (SAML) authentication.'}
+
{t('Tenant Key')}
+
+ {t('For SSO (SAML) authentication.')}
+
@@ -76,9 +88,9 @@ function ProfileSettings() {
-
{'Data Collection'}
+
{t('Data Collection')}
- {'Enables you to control how OpenReplay captures data on your organization’s usage to improve our product.'}
+ {t('Enables you to control how OpenReplay captures data on your organization’s usage to improve our product.')}
- Choose data recording options
+ {t('Choose data recording options')}
@@ -98,7 +98,7 @@ const ProjectCodeSnippet: React.FC = (props) => {
onChange={(e) => onChangeOption('maskNumbers', e.target.checked)}
className="mr-2"
>
- Do not record any numeric text
+ {t('Do not record any numeric text')}
@@ -108,18 +108,31 @@ const ProjectCodeSnippet: React.FC = (props) => {
onChange={(e) => onChangeOption('maskEmails', e.target.checked)}
className="mr-2"
>
- Do not record email addresses
+ {t('Do not record email addresses')}
-
- The code snippet below changes based on the selected data recording options and should be used for implementation.
+
+ {t(
+ 'The code snippet below changes based on the selected data recording options and should be used for implementation.',
+ )}
- OpenReplay Assist allows you to support your users by seeing their
- live screen and instantly hopping on call (WebRTC) with them without
- requiring any 3rd-party screen sharing software.
+ {t(
+ 'OpenReplay Assist allows you to support your users by seeing their live screen and instantly hopping on call (WebRTC) with them without requiring any 3rd-party screen sharing software.',
+ )}
-
-
+
+
- Install SDK
+ {t('Install SDK')}
-
Paste this snippet {'before the '}
- {''}
- {' tag of your page.'}
+
+ {t('Paste this snippet')}
+ {t('before the')}
+
+
+ {' '}
+ {''}{' '}
+
+ {t('tag of your page.')}
-
-
- {showLoader ? (
-
-
- ) : (
-
- )}
+
+ {showLoader ? (
+
+
+
+ ) : (
+
+ )}
+
+
-
-
-
-
-
-
);
};
-export default observer(ProjectCodeSnippet);
\ No newline at end of file
+export default observer(ProjectCodeSnippet);
diff --git a/frontend/app/components/Client/Projects/ProjectForm.tsx b/frontend/app/components/Client/Projects/ProjectForm.tsx
index 879260022..f2ac053c4 100644
--- a/frontend/app/components/Client/Projects/ProjectForm.tsx
+++ b/frontend/app/components/Client/Projects/ProjectForm.tsx
@@ -5,6 +5,7 @@ import { projectStore, useStore } from '@/mstore';
import { App, Segmented, Form, Input, Button, Tooltip } from 'antd';
import { toast } from 'react-toastify';
import { observer } from 'mobx-react-lite';
+import { useTranslation } from 'react-i18next';
interface Props {
project?: Project;
@@ -12,18 +13,23 @@ interface Props {
}
function ProjectForm(props: Props) {
+ const { t } = useTranslation();
const [form] = Form.useForm();
const { onClose } = props;
const { projectsStore } = useStore();
- const [project, setProject] = React.useState(new Project(props.project || {}));
- const loading = projectsStore.loading;
+ const [project, setProject] = React.useState(
+ new Project(props.project || {}),
+ );
+ const { loading } = projectsStore;
const canDelete = projectsStore.list.length > 1;
// const pathname = window.location.pathname;
const mstore = useStore();
const { modal } = App.useApp();
- const handleEdit = ({ target: { name, value } }: ChangeEvent) => {
- setProject((prev: Project) => (new Project({ ...prev, [name]: value })));
+ const handleEdit = ({
+ target: { name, value },
+ }: ChangeEvent) => {
+ setProject((prev: Project) => new Project({ ...prev, [name]: value }));
};
const onSubmit = (e: FormEvent) => {
@@ -32,17 +38,19 @@ function ProjectForm(props: Props) {
projectsStore
.updateProject(project.id, project)
.then((response: any) => {
- toast.success('Project updated successfully');
+ toast.success(t('Project updated successfully'));
onClose?.(null);
})
.catch((error: Error) => {
- toast.error(error.message || 'An error occurred while updating the project');
+ toast.error(
+ error.message || t('An error occurred while updating the project'),
+ );
});
} else {
projectsStore
.save(project!)
.then((resp: Project) => {
- toast.success('Project created successfully');
+ toast.success(t('Project created successfully'));
onClose?.(resp);
// mstore.searchStore.clearSearch();
@@ -52,24 +60,34 @@ function ProjectForm(props: Props) {
projectsStore.setConfigProject(parseInt(resp.id!));
})
.catch((error: Error) => {
- toast.error(error.message || 'An error occurred while creating the project');
+ toast.error(
+ error.message || t('An error occurred while creating the project'),
+ );
});
}
};
const handleRemove = async () => {
modal.confirm({
- title: 'Project Deletion Alert',
- content: 'Are you sure you want to delete this project? Deleting it will permanently remove the project, along with all associated sessions and data.',
+ title: t('Project Deletion Alert'),
+ content: t(
+ 'Are you sure you want to delete this project? Deleting it will permanently remove the project, along with all associated sessions and data.',
+ ),
onOk: () => {
- projectsStore.removeProject(project.id!).then(() => {
- if (onClose) {
- onClose(null);
- }
- }).catch((error: Error) => {
- toast.error(error.message || 'An error occurred while deleting the project');
- });
- }
+ projectsStore
+ .removeProject(project.id!)
+ .then(() => {
+ if (onClose) {
+ onClose(null);
+ }
+ })
+ .catch((error: Error) => {
+ toast.error(
+ error.message ||
+ t('An error occurred while deleting the project'),
+ );
+ });
+ },
});
};
@@ -89,13 +107,13 @@ function ProjectForm(props: Props) {
initialValues={{ ...project }}
>
-
+
{
// projectsStore.editInstance({ platform: value });
- setProject((prev: Project) => (new Project({ ...prev, platform: value })));
+ setProject(
+ (prev: Project) => new Project({ ...prev, platform: value }),
+ );
}}
/>
}
];
@@ -33,7 +47,7 @@ function ProjectTabs() {
renderTabBar={customTabBar}
items={tabItems.map((tab) => ({
key: tab.key,
- label: tab.label
+ label: tab.label,
}))}
/>
);
diff --git a/frontend/app/components/Client/Projects/ProjectTags.tsx b/frontend/app/components/Client/Projects/ProjectTags.tsx
index 92caa6485..d45c5fcf9 100644
--- a/frontend/app/components/Client/Projects/ProjectTags.tsx
+++ b/frontend/app/components/Client/Projects/ProjectTags.tsx
@@ -3,12 +3,14 @@ import { useStore } from '@/mstore';
import { List, Button, Typography, Space, Empty } from 'antd';
import { observer } from 'mobx-react-lite';
import { ScanSearch } from 'lucide-react';
-import {EditOutlined} from '@ant-design/icons'
+import { EditOutlined } from '@ant-design/icons';
import { useModal } from 'Components/ModalContext';
import TagForm from 'Components/Client/Projects/TagForm';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
+import { useTranslation } from 'react-i18next';
function ProjectTags() {
+ const { t } = useTranslation();
const { tagWatchStore, projectsStore } = useStore();
const list = tagWatchStore.tags;
const { openModal } = useModal();
@@ -20,7 +22,7 @@ function ProjectTags() {
const handleInit = (tag?: any) => {
openModal(, {
- title: tag ? 'Edit Tag' : 'Add Tag'
+ title: tag ? t('Edit Tag') : t('Add Tag'),
});
};
@@ -28,18 +30,31 @@ function ProjectTags() {
- Manage Tag Elements here. Rename tags for easy identification or delete those you no longer need.
+ {t(
+ 'Manage Tag Elements here. Rename tags for easy identification or delete those you no longer need.',
+ )}
-
To create new tags, navigate to the Tags tab while playing a session.
+
+
+ {t('To create new tags, navigate to the Tags tab while playing a session')}
+
-
Use tags in OmniSearch to quickly find relevant sessions.
+
+
+ {t('Use tags in OmniSearch to quickly find relevant sessions.')}
+
- SMTP is not configured (see{' '}
+ {t('SMTP is not configured (see')}
- here
+ {t('here')}
{' '}
- how to set it up). You can still add new users, but you’d have to
- manually copy then send them the invitation link.
+ {t(
+ 'how to set it up). You can still add new users, but you’d have to manually copy then send them the invitation link.',
+ )}
)}
@@ -108,9 +113,9 @@ function UserForm() {
className="mt-1"
/>
- Admin Privileges
+ {t('Admin Privileges')}
- {'Can manage Projects and team members.'}
+ {t('Can manage Projects and team members.')}
- {alertsSearch !== '' ? 'No matching results' : 'No alerts have been configured yet'}
+
+ {alertsSearch !== ''
+ ? t('No matching results')
+ : t('No alerts have been configured yet')}
}
- subtext='Configure alerts to stay informed about app activity with threshold or change-based notifications.'
+ subtext={t(
+ 'Configure alerts to stay informed about app activity with threshold or change-based notifications.',
+ )}
>
-