Skip to content

Commit d9630af

Browse files
authored
Merge pull request #1445 from AppQuality/develop
Release 20251006
2 parents bec9087 + b109482 commit d9630af

File tree

98 files changed

+3360
-1012
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+3360
-1012
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
"dependencies": {
66
"@analytics/google-tag-manager": "^0.6.0",
77
"@appquality/languages": "1.4.3",
8-
"@appquality/unguess-design-system": "4.0.49",
8+
"@appquality/unguess-design-system": "4.0.50--canary.549.d20012e.0",
99
"@atlaskit/pragmatic-drag-and-drop": "^1.7.4",
1010
"@atlaskit/pragmatic-drag-and-drop-flourish": "^2.0.3",
1111
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
12+
"@emotion/is-prop-valid": "^1.4.0",
1213
"@headwayapp/react-widget": "^0.0.4",
1314
"@reduxjs/toolkit": "^1.8.0",
1415
"@sentry/react": "^8.32.0",

src/analytics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const analytics = Analytics({
1515
}),
1616
}),
1717
userpilot({
18-
token: isDev() ? 'STG-NX-54e88e10' : 'NX-54e88e10',
18+
token: 'NX-54e88e10',
1919
}),
2020
],
2121
}),

src/app/App.tsx

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,49 +3,63 @@ import {
33
ThemeProvider,
44
ToastProvider,
55
} from '@appquality/unguess-design-system';
6+
import isPropValid from '@emotion/is-prop-valid';
67
import Helmet from 'react-helmet';
78
import { useTranslation } from 'react-i18next';
89
import { Provider } from 'react-redux';
10+
import analytics from 'src/analytics';
911
import { appTheme } from 'src/app/theme';
10-
import { AnalyticsProvider } from 'use-analytics';
1112
import Pages from 'src/common/Pages';
12-
import analytics from 'src/analytics';
13+
import { StyleSheetManager } from 'styled-components';
14+
import { AnalyticsProvider } from 'use-analytics';
1315
import '../i18n';
1416
import { store } from './store';
1517

18+
// This implements the default behavior from styled-components v5
19+
function shouldForwardProp(propName: string, target: any) {
20+
if (typeof target === 'string') {
21+
// For HTML elements, forward the prop if it is a valid HTML attribute
22+
return isPropValid(propName);
23+
}
24+
// For other elements, forward all props
25+
return true;
26+
}
27+
1628
const App = () => {
1729
const { t } = useTranslation();
1830
return (
19-
<Provider store={store}>
20-
<AnalyticsProvider instance={analytics}>
21-
<ThemeProvider theme={appTheme}>
22-
<GlobalStyle />
23-
<Helmet>
24-
<meta
25-
property="og:title"
26-
content={`UNGUESS - ${t('__APP_META_PAYOFF')}`}
27-
/>
28-
<title>UNGUESS - {t('__APP_META_PAYOFF')}</title>
29-
<meta name="description" content={t('__APP_META_DESCRIPTION')} />
30-
</Helmet>
31-
<ToastProvider
32-
limit={5}
33-
zIndex={500}
34-
placementProps={{
35-
top: {
36-
style: {
37-
top:
38-
parseInt(appTheme.components.chrome.header.height, 10) +
39-
appTheme.space.base * 4,
31+
<StyleSheetManager shouldForwardProp={shouldForwardProp}>
32+
<Provider store={store}>
33+
<AnalyticsProvider instance={analytics}>
34+
<ThemeProvider theme={appTheme}>
35+
<GlobalStyle />
36+
<Helmet>
37+
<meta
38+
property="og:title"
39+
content={`UNGUESS - ${t('__APP_META_PAYOFF')}`}
40+
/>
41+
<title>UNGUESS - {t('__APP_META_PAYOFF')}</title>
42+
<meta name="description" content={t('__APP_META_DESCRIPTION')} />
43+
</Helmet>
44+
<ToastProvider
45+
limit={5}
46+
zIndex={500}
47+
placementProps={{
48+
top: {
49+
style: {
50+
top:
51+
parseInt(appTheme.components.chrome.header.height, 10) +
52+
appTheme.space.base * 4,
53+
},
4054
},
41-
},
42-
}}
43-
>
44-
<Pages />
45-
</ToastProvider>
46-
</ThemeProvider>
47-
</AnalyticsProvider>
48-
</Provider>
55+
}}
56+
>
57+
<Pages />
58+
</ToastProvider>
59+
</ThemeProvider>
60+
</AnalyticsProvider>
61+
</Provider>
62+
</StyleSheetManager>
4963
);
5064
};
5165

Lines changed: 6 additions & 0 deletions
Loading

src/common/Track.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const Track = ({
1919
const { data: userData, isLoading, isSuccess } = useGetUsersMeQuery();
2020
const { activeWorkspace } = useActiveWorkspace();
2121
const { track, identify, page } = useAnalytics();
22+
const utmSource = sessionStorage.getItem('utmSource');
2223
const location = useLocation();
2324

2425
const defaultMeta = [
@@ -63,6 +64,7 @@ export const Track = ({
6364
email: userData.email,
6465
company: activeWorkspace.company,
6566
workspace: activeWorkspace,
67+
...((utmSource && { utm_source: utmSource }) || {}),
6668
});
6769

6870
track(

src/common/analytics-plugins/userpilot.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { User } from 'src/features/api';
22
import { Userpilot } from 'userpilot';
3+
import { isDev } from '../isDevEnvironment';
34

45
declare global {
56
interface Window {
@@ -28,7 +29,14 @@ export default function userpilotPlugin(pluginSettings: UserpilotConfig) {
2829
name: 'userpilot',
2930
config: { ...pluginSettings },
3031
initialize: ({ config }: { config: UserpilotConfig }) => {
31-
Userpilot.initialize(config.token);
32+
if (isDev()) {
33+
const previewEnabled = localStorage.getItem('userpilot_ug_preview');
34+
if (previewEnabled !== null) {
35+
Userpilot.initialize(config.token);
36+
}
37+
} else {
38+
Userpilot.initialize(config.token);
39+
}
3240
},
3341
identify: ({ payload }: { payload: IIdentifyPayload }) => {
3442
const { userId, traits } = payload;
@@ -56,6 +64,6 @@ export default function userpilotPlugin(pluginSettings: UserpilotConfig) {
5664
Userpilot.track(event, { ...properties, userId });
5765
},
5866

59-
loaded: () => !!window.userpilot,
67+
loaded: () => true,
6068
};
6169
}

src/common/schema.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,15 @@ export interface paths {
377377
};
378378
};
379379
};
380+
"/plans/{pid}/rules-evaluation": {
381+
/** Usefull endpoint when a purchasable plan have some failed rules */
382+
get: operations["get-plans-pid-rules-evaluation"];
383+
parameters: {
384+
path: {
385+
pid: string;
386+
};
387+
};
388+
};
380389
"/plans/{pid}/status": {
381390
/** */
382391
patch: operations["patch-workspaces-wid-plans-pid-status"];
@@ -1424,6 +1433,16 @@ export interface components {
14241433
name: string;
14251434
workspaceId: number;
14261435
};
1436+
/**
1437+
* PurchasablePlanRules
1438+
* @enum {string}
1439+
*/
1440+
PurchasablePlanRules:
1441+
| "number_of_modules"
1442+
| "module_type"
1443+
| "number_of_testers"
1444+
| "number_of_tasks"
1445+
| "task_type";
14271446
/** Report */
14281447
Report: {
14291448
creation_date?: string;
@@ -3344,8 +3363,12 @@ export interface operations {
33443363
config: {
33453364
modules: components["schemas"]["Module"][];
33463365
};
3366+
from_template?: {
3367+
id: number;
3368+
title: string;
3369+
};
33473370
id: number;
3348-
is_frozen?: number;
3371+
price?: string;
33493372
project: {
33503373
id: number;
33513374
name: string;
@@ -3421,6 +3444,24 @@ export interface operations {
34213444
500: components["responses"]["Error"];
34223445
};
34233446
};
3447+
/** Usefull endpoint when a purchasable plan have some failed rules */
3448+
"get-plans-pid-rules-evaluation": {
3449+
parameters: {
3450+
path: {
3451+
pid: string;
3452+
};
3453+
};
3454+
responses: {
3455+
/** OK */
3456+
200: {
3457+
content: {
3458+
"application/json": {
3459+
failed: components["schemas"]["PurchasablePlanRules"][];
3460+
};
3461+
};
3462+
};
3463+
};
3464+
};
34243465
/** */
34253466
"patch-workspaces-wid-plans-pid-status": {
34263467
parameters: {

src/features/api/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export const apiSlice = createApi({
3636
'Archive',
3737
'Plans',
3838
'Users',
39+
'EvaluationRules',
40+
'CheckoutItem',
3941
],
4042
endpoints: () => ({}),
4143
});

src/features/api/apiTags.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,16 @@ unguessApi.enhanceEndpoints({
307307
},
308308
},
309309
patchPlansByPid: {
310-
invalidatesTags: ['Plans'],
310+
invalidatesTags: ['Plans', 'EvaluationRules'],
311311
},
312312
postWorkspacesByWidPlans: {
313313
invalidatesTags: ['Plans'],
314314
},
315315
patchPlansByPidStatus: {
316-
invalidatesTags: ['Plans', 'Projects'],
316+
invalidatesTags: ['Plans', 'Projects', 'CheckoutItem'],
317+
},
318+
getPlansByPidCheckoutItem: {
319+
providesTags: ['CheckoutItem'],
317320
},
318321
deleteProjectsByPid: {
319322
invalidatesTags: ['Projects'],
@@ -324,6 +327,9 @@ unguessApi.enhanceEndpoints({
324327
getWorkspacesByWidTemplates: {
325328
providesTags: ['Templates'],
326329
},
330+
getPlansByPidRulesEvaluation: {
331+
providesTags: ['EvaluationRules'],
332+
},
327333
},
328334
});
329335

src/features/api/index.ts

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,12 @@ const injectedRtkApi = api.injectEndpoints({
459459
>({
460460
query: (queryArg) => ({ url: `/plans/${queryArg.pid}/checkoutItem` }),
461461
}),
462+
getPlansByPidRulesEvaluation: build.query<
463+
GetPlansByPidRulesEvaluationApiResponse,
464+
GetPlansByPidRulesEvaluationApiArg
465+
>({
466+
query: (queryArg) => ({ url: `/plans/${queryArg.pid}/rules-evaluation` }),
467+
}),
462468
patchPlansByPidStatus: build.mutation<
463469
PatchPlansByPidStatusApiResponse,
464470
PatchPlansByPidStatusApiArg
@@ -1553,8 +1559,12 @@ export type GetPlansByPidApiResponse = /** status 200 OK */ {
15531559
config: {
15541560
modules: Module[];
15551561
};
1562+
from_template?: {
1563+
id: number;
1564+
title: string;
1565+
};
15561566
id: number;
1557-
is_frozen?: number;
1567+
price?: string;
15581568
project: {
15591569
id: number;
15601570
name: string;
@@ -1587,6 +1597,12 @@ export type GetPlansByPidCheckoutItemApiResponse = /** status 200 OK */ {
15871597
export type GetPlansByPidCheckoutItemApiArg = {
15881598
pid: string;
15891599
};
1600+
export type GetPlansByPidRulesEvaluationApiResponse = /** status 200 OK */ {
1601+
failed: PurchasablePlanRules[];
1602+
};
1603+
export type GetPlansByPidRulesEvaluationApiArg = {
1604+
pid: string;
1605+
};
15901606
export type PatchPlansByPidStatusApiResponse = /** status 200 OK */ {};
15911607
export type PatchPlansByPidStatusApiArg = {
15921608
pid: string;
@@ -2670,8 +2686,7 @@ export type OutputModuleTouchpointsAppTablet = {
26702686
kind: 'app';
26712687
os: {
26722688
ios?: string;
2673-
linux?: string;
2674-
windows?: string;
2689+
android?: string;
26752690
};
26762691
};
26772692
export type OutputModuleTouchpointsAppSmartphone = {
@@ -2811,6 +2826,13 @@ export type Module =
28112826
| ModuleGasSupply
28122827
| ModuleAnnualIncomeRange;
28132828
export type PlanStatus = 'pending_review' | 'draft' | 'approved' | 'paying';
2829+
export type PurchasablePlanRules =
2830+
| 'number_of_modules'
2831+
| 'module_type'
2832+
| 'number_of_testers'
2833+
| 'number_of_tasks'
2834+
| 'task_type'
2835+
| 'duplicate_touchpoint_form_factors';
28142836
export type Project = {
28152837
campaigns_count: number;
28162838
description?: string;
@@ -2991,6 +3013,7 @@ export const {
29913013
useGetPlansByPidQuery,
29923014
usePatchPlansByPidMutation,
29933015
useGetPlansByPidCheckoutItemQuery,
3016+
useGetPlansByPidRulesEvaluationQuery,
29943017
usePatchPlansByPidStatusMutation,
29953018
usePostProjectsMutation,
29963019
useDeleteProjectsByPidMutation,

0 commit comments

Comments
 (0)