diff --git a/index.html b/index.html
index 5bad140fe..bdfca044a 100644
--- a/index.html
+++ b/index.html
@@ -48,7 +48,7 @@
-

+
diff --git a/package.json b/package.json
index bd382f344..d6a122f25 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"i18n-iso-countries": "^7.3.0",
"i18next": "^23.15.1",
"i18next-browser-languagedetector": "^8.0.0",
+ "motion": "^12.15.0",
"qs": "^6.10.3",
"query-string": "^7.1.1",
"react": "^18.3.1",
diff --git a/src/assets/icons/password-check-v.svg b/src/assets/icons/password-check-v.svg
new file mode 100644
index 000000000..4438467b7
--- /dev/null
+++ b/src/assets/icons/password-check-v.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/assets/icons/password-check-x.svg b/src/assets/icons/password-check-x.svg
new file mode 100644
index 000000000..7fc25b025
--- /dev/null
+++ b/src/assets/icons/password-check-x.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/src/assets/join-bg-1.png b/src/assets/join-bg-1.png
new file mode 100644
index 000000000..b2a8b7c45
Binary files /dev/null and b/src/assets/join-bg-1.png differ
diff --git a/src/assets/join-bg-1.webp b/src/assets/join-bg-1.webp
new file mode 100644
index 000000000..b1e72f235
Binary files /dev/null and b/src/assets/join-bg-1.webp differ
diff --git a/src/assets/join-bg-2.png b/src/assets/join-bg-2.png
new file mode 100644
index 000000000..1e66db7e9
Binary files /dev/null and b/src/assets/join-bg-2.png differ
diff --git a/src/assets/join-bg-2.webp b/src/assets/join-bg-2.webp
new file mode 100644
index 000000000..67d4964cb
Binary files /dev/null and b/src/assets/join-bg-2.webp differ
diff --git a/src/assets/join-bg-3.png b/src/assets/join-bg-3.png
new file mode 100644
index 000000000..9aac47a70
Binary files /dev/null and b/src/assets/join-bg-3.png differ
diff --git a/src/assets/join-bg-3.webp b/src/assets/join-bg-3.webp
new file mode 100644
index 000000000..4a695fcfe
Binary files /dev/null and b/src/assets/join-bg-3.webp differ
diff --git a/src/assets/join-loghi.png b/src/assets/join-loghi.png
new file mode 100644
index 000000000..77eb16ddf
Binary files /dev/null and b/src/assets/join-loghi.png differ
diff --git a/src/assets/join-loghi.webp b/src/assets/join-loghi.webp
new file mode 100644
index 000000000..95b364565
Binary files /dev/null and b/src/assets/join-loghi.webp differ
diff --git a/src/assets/join-step-1.svg b/src/assets/join-step-1.svg
new file mode 100644
index 000000000..69f3ef230
--- /dev/null
+++ b/src/assets/join-step-1.svg
@@ -0,0 +1,344 @@
+
diff --git a/src/assets/join-step-1.webp b/src/assets/join-step-1.webp
new file mode 100644
index 000000000..84e6575fa
Binary files /dev/null and b/src/assets/join-step-1.webp differ
diff --git a/src/assets/join-step-2.png b/src/assets/join-step-2.png
new file mode 100644
index 000000000..4ce18d7fd
Binary files /dev/null and b/src/assets/join-step-2.png differ
diff --git a/src/assets/join-step-2.webp b/src/assets/join-step-2.webp
new file mode 100644
index 000000000..a4b9b2b78
Binary files /dev/null and b/src/assets/join-step-2.webp differ
diff --git a/src/assets/join-step-3.png b/src/assets/join-step-3.png
new file mode 100644
index 000000000..f37baa8ff
Binary files /dev/null and b/src/assets/join-step-3.png differ
diff --git a/src/assets/join-step-3.webp b/src/assets/join-step-3.webp
new file mode 100644
index 000000000..97a00ad33
Binary files /dev/null and b/src/assets/join-step-3.webp differ
diff --git a/src/common/Pages.tsx b/src/common/Pages.tsx
index dbf64772b..c1411416c 100644
--- a/src/common/Pages.tsx
+++ b/src/common/Pages.tsx
@@ -17,6 +17,7 @@ import CampaignPreview from 'src/pages/Campaign/preview';
import Dashboard from 'src/pages/Dashboard';
import Project from 'src/pages/Dashboard/Project';
import InsightsPage from 'src/pages/Insights';
+import JoinPage from 'src/pages/JoinPage';
import LoginPage from 'src/pages/LoginPage';
import Manual from 'src/pages/Manual';
import MediaNotFound from 'src/pages/NotFound/MediaNotFound';
@@ -66,6 +67,12 @@ const Pages = () => {
path={`/${langPrefix}/login`}
element={}
/>
+ } />
+ }
+ />
+
}
@@ -146,6 +153,21 @@ const Pages = () => {
}
errorElement={}
/>
+
+ {
+ if (!searchParams || !searchParams.get('redirect'))
+ return '/oops';
+ return `/campaigns/${searchParams.get('cid')}/bugform`;
+ }}
+ />
+ }
+ errorElement={}
+ />
+
} />
>
)
diff --git a/src/common/schema.ts b/src/common/schema.ts
index 75eee33f2..7cadc5d89 100644
--- a/src/common/schema.ts
+++ b/src/common/schema.ts
@@ -9,10 +9,6 @@ export interface paths {
get: operations['get-root'];
parameters: {};
};
- '/authenticate': {
- /** A request to login with your username and password */
- post: operations['post-authenticate'];
- };
'/analytics/views/campaigns/{cid}': {
post: operations['post-analytics-views-campaigns-cid'];
parameters: {
@@ -22,9 +18,9 @@ export interface paths {
};
};
};
- '/campaigns': {
- post: operations['post-campaigns'];
- parameters: {};
+ '/authenticate': {
+ /** A request to login with your username and password */
+ post: operations['post-authenticate'];
};
'/campaigns/{cid}': {
get: operations['get-campaign'];
@@ -78,25 +74,25 @@ export interface paths {
};
};
};
- '/campaigns/{cid}/bugs/{bid}/media': {
- post: operations['post-campaigns-cid-bugs-bid-media'];
+ '/campaigns/{cid}/bugs/{bid}/comments/{cmid}': {
+ post: operations['post-campaigns-cid-bugs-bid-comments-cmid-media'];
+ delete: operations['delete-campaigns-cid-bugs-bid-comments-cmid'];
parameters: {
path: {
- /** Campaign id */
cid: string;
- /** Defines an identifier for the bug object (BUG ID) */
bid: string;
+ cmid: string;
};
};
};
- '/campaigns/{cid}/bugs/{bid}/comments/{cmid}': {
- post: operations['post-campaigns-cid-bugs-bid-comments-cmid-media'];
- delete: operations['delete-campaigns-cid-bugs-bid-comments-cmid'];
+ '/campaigns/{cid}/bugs/{bid}/media': {
+ post: operations['post-campaigns-cid-bugs-bid-media'];
parameters: {
path: {
+ /** Campaign id */
cid: string;
+ /** Defines an identifier for the bug object (BUG ID) */
bid: string;
- cmid: string;
};
};
};
@@ -320,11 +316,12 @@ export interface paths {
};
};
};
- '/media/{id}': {
- get: operations['get-media-id'];
+ '/invites/{profile}/{token}': {
+ get: operations['get-invites-profile-token'];
parameters: {
path: {
- id: string;
+ profile: string;
+ token: string;
};
};
};
@@ -337,6 +334,33 @@ export interface paths {
};
};
};
+ '/media/{id}': {
+ get: operations['get-media-id'];
+ parameters: {
+ path: {
+ id: string;
+ };
+ };
+ };
+ '/plans/{pid}': {
+ get: operations['get-workspaces-wid-plans-pid'];
+ delete: operations['delete-workspaces-wid-plans-pid'];
+ patch: operations['patch-workspaces-wid-plans-pid'];
+ parameters: {
+ path: {
+ pid: string;
+ };
+ };
+ };
+ '/plans/{pid}/status': {
+ /** */
+ patch: operations['patch-workspaces-wid-plans-pid-status'];
+ parameters: {
+ path: {
+ pid: string;
+ };
+ };
+ };
'/projects': {
post: operations['post-projects'];
};
@@ -376,9 +400,17 @@ export interface paths {
};
};
};
- '/templates': {
- /** Retrieve all available use case templates */
- get: operations['get-templates'];
+ '/users': {
+ post: operations['post-users'];
+ parameters: {};
+ };
+ '/users/by-email/{email}': {
+ head: operations['head-users-by-email-email'];
+ parameters: {
+ path: {
+ email: string;
+ };
+ };
};
'/users/me': {
get: operations['get-users-me'];
@@ -394,6 +426,10 @@ export interface paths {
};
};
};
+ '/users/roles': {
+ get: operations['get-users-roles'];
+ parameters: {};
+ };
'/videos/{vid}': {
/** Retrive single video data */
get: operations['get-videos-vid'];
@@ -506,31 +542,34 @@ export interface paths {
};
};
};
- '/plans/{pid}': {
- get: operations['get-workspaces-wid-plans-pid'];
- delete: operations['delete-workspaces-wid-plans-pid'];
- patch: operations['patch-workspaces-wid-plans-pid'];
+ '/workspaces/{wid}/projects': {
+ get: operations['get-workspace-projects'];
parameters: {
path: {
- pid: string;
+ /** Workspace (company, customer) id */
+ wid: components['parameters']['wid'];
};
};
};
- '/plans/{pid}/status': {
- /** */
- patch: operations['patch-workspaces-wid-plans-pid-status'];
+ '/workspaces/{wid}/projects/{pid}': {
+ get: operations['get-workspace-project'];
parameters: {
path: {
- pid: string;
+ /** Workspace (company, customer) id */
+ wid: components['parameters']['wid'];
+ /** Project id */
+ pid: components['parameters']['pid'];
};
};
};
- '/workspaces/{wid}/projects': {
- get: operations['get-workspace-projects'];
+ '/workspaces/{wid}/projects/{pid}/campaigns': {
+ get: operations['get-workspace-project-campaigns'];
parameters: {
path: {
/** Workspace (company, customer) id */
wid: components['parameters']['wid'];
+ /** Project id */
+ pid: components['parameters']['pid'];
};
};
};
@@ -553,28 +592,6 @@ export interface paths {
};
};
};
- '/workspaces/{wid}/projects/{pid}': {
- get: operations['get-workspace-project'];
- parameters: {
- path: {
- /** Workspace (company, customer) id */
- wid: components['parameters']['wid'];
- /** Project id */
- pid: components['parameters']['pid'];
- };
- };
- };
- '/workspaces/{wid}/projects/{pid}/campaigns': {
- get: operations['get-workspace-project-campaigns'];
- parameters: {
- path: {
- /** Workspace (company, customer) id */
- wid: components['parameters']['wid'];
- /** Project id */
- pid: components['parameters']['pid'];
- };
- };
- };
'/workspaces/{wid}/users': {
/** Return a list of users from a specific workspace */
get: operations['get-workspaces-users'];
@@ -595,48 +612,56 @@ export interface components {
schemas: {
/** Authentication */
Authentication: {
- id: number;
/** Format: email */
email: string;
- role: string;
+ exp?: number;
+ iat?: number;
+ id: number;
name: string;
picture?: string;
+ role: string;
token: string;
- iat?: number;
- exp?: number;
};
+ /**
+ * BannerType
+ * @enum {string}
+ */
+ BannerType:
+ | 'banner_testing_automation'
+ | 'banner_user_experience'
+ | 'banner_cyber_security';
/** Bug */
Bug: {
- id: number;
- internal_id: string;
+ application_section: {
+ id?: number;
+ prefix_title?: string;
+ simple_title?: string;
+ title?: string;
+ };
campaign_id: number;
- title: components['schemas']['BugTitle'];
- step_by_step: string;
- expected_result: string;
+ created: string;
current_result: string;
- status: components['schemas']['BugStatus'];
- severity: components['schemas']['BugSeverity'];
- type: components['schemas']['BugType'];
- replicability: components['schemas']['BugReplicability'];
- priority: components['schemas']['BugPriority'];
custom_status: components['schemas']['BugCustomStatus'];
- created: string;
- occurred_date: string;
- updated?: string;
- note?: string;
device:
| components['schemas']['Smartphone']
| components['schemas']['Tablet']
| components['schemas']['Desktop'];
- application_section: {
- id?: number;
- prefix_title?: string;
- title?: string;
- simple_title?: string;
- };
duplicated_of_id?: number;
+ expected_result: string;
+ id: number;
+ internal_id: string;
is_favorite?: number;
+ note?: string;
+ occurred_date: string;
+ priority: components['schemas']['BugPriority'];
read?: boolean;
+ replicability: components['schemas']['BugReplicability'];
+ severity: components['schemas']['BugSeverity'];
+ status: components['schemas']['BugStatus'];
+ step_by_step: string;
+ title: components['schemas']['BugTitle'];
+ type: components['schemas']['BugType'];
+ updated?: string;
};
/**
* BugAdditionalField
@@ -652,39 +677,39 @@ export interface components {
);
/** BugAdditionalFieldRegex */
BugAdditionalFieldRegex: {
- validation: string;
/** @enum {string} */
kind: 'regex';
+ validation: string;
};
/** BugAdditionalFieldSelect */
BugAdditionalFieldSelect: {
- options: string[];
/** @enum {string} */
kind: 'select';
+ options: string[];
};
/** BugComment */
BugComment: {
- id: number;
- text: string;
creation_date: string;
creator: {
id: number;
- name: string;
isInternal: boolean;
+ name: string;
};
+ id: number;
media?: {
- url: string;
id: number;
type: string;
+ url: string;
}[];
+ text: string;
};
/** BugCustomStatus */
BugCustomStatus: {
+ color: string;
id: number;
+ is_default: number;
name: string;
- color: string;
phase: components['schemas']['BugCustomStatusPhase'];
- is_default: number;
};
/** BugCustomStatusPhase */
BugCustomStatusPhase: {
@@ -693,14 +718,14 @@ export interface components {
};
/** BugMedia */
BugMedia: {
+ creation_date: string;
mime_type: {
+ extension: string;
/** @enum {string} */
type: 'video' | 'image' | 'other';
- extension: string;
};
/** Format: uri */
url: string;
- creation_date: string;
};
/** BugPriority */
BugPriority: {
@@ -724,23 +749,23 @@ export interface components {
};
/** BugTag */
BugTag: {
- id: number;
- tag_id: number;
- name: string;
- slug: string;
+ author_tid?: number;
+ author_wp_id?: number;
bug_id: number;
campaign_id: number;
- author_wp_id?: number;
- author_tid?: number;
creation_date: string;
+ id: number;
is_visible_to_customer?: number;
+ name: string;
+ slug: string;
+ tag_id: number;
};
/** BugTitle */
BugTitle: {
- full: string;
/** @description Bug title without context. */
compact: string;
context?: string[];
+ full: string;
};
/** BugType */
BugType: {
@@ -749,32 +774,34 @@ export interface components {
};
/** Campaign */
Campaign: {
- id: number;
- start_date: string;
- end_date: string;
- close_date: string;
- title: string;
- customer_title: string;
- is_public: number;
+ base_bug_internal_id?: string;
/**
* @description -1: no bug form;
* 0: only bug form;
* 1: bug form with bug parade;
*/
bug_form?: number;
- type: {
+ close_date: string;
+ customer_title: string;
+ description?: string;
+ end_date: string;
+ family: {
id: number;
name: string;
};
- family: {
+ id: number;
+ is_public: number;
+ project: {
id: number;
name: string;
};
+ start_date: string;
status: {
id: number;
name: string;
};
- project: {
+ title: string;
+ type: {
id: number;
name: string;
};
@@ -782,8 +809,6 @@ export interface components {
id: number;
name: string;
};
- description?: string;
- base_bug_internal_id?: string;
};
/** CampaignWithOutput */
CampaignWithOutput: components['schemas']['Campaign'] & {
@@ -800,21 +825,31 @@ export interface components {
* The coin only valid currency in order to run an express campaign (no matter what type of express)
*/
Coin: {
- id: number;
- customer_id: number;
+ agreement_id?: number;
/** @description Number of available coin */
amount: number;
- agreement_id?: number;
+ created_on?: string;
+ customer_id: number;
+ id: number;
/**
* Format: float
* @description This is the single coin price
* @default 0
*/
price?: number;
- created_on?: string;
/** @description On each coin use, the related package will be updated */
updated_on?: string;
};
+ /** CpReqTemplate */
+ CpReqTemplate: {
+ config: string;
+ description?: string;
+ id: number;
+ name: string;
+ price?: string;
+ strapi?: components['schemas']['StrapiTemplate'];
+ workspace_id?: number;
+ };
/** Desktop */
Desktop: {
desktop_type: string;
@@ -825,17 +860,17 @@ export interface components {
};
/** Error */
Error: {
- message: string;
code: number;
error: boolean;
+ message: string;
};
/**
* Feature
* @description Flags used to enable functionality to some users
*/
Feature: {
- slug?: string;
name?: string;
+ slug?: string;
};
/** Generic Device */
GenericDevice: {
@@ -845,46 +880,46 @@ export interface components {
};
/** Grape */
Grapes: {
- title: string;
- severity: string;
- usersNumber: number;
observations: (components['schemas']['Observation'] & {
- uploaderId: number;
- mediaId: number;
deviceType: string;
+ mediaId: number;
+ uploaderId: number;
usecaseTitle: string;
})[];
+ severity: string;
+ title: string;
+ usersNumber: number;
};
/** Insight */
Insight: {
- id: number;
- title: string;
+ comment?: string;
description: string;
+ id: number;
+ observations: (components['schemas']['Observation'] & {
+ uploaderId: number;
+ usecaseTitle: string;
+ video: {
+ deviceType: string;
+ id: number;
+ };
+ })[];
severity: {
id: number;
name: string;
style: string;
};
+ title: string;
visible?: number;
- comment?: string;
- observations: (components['schemas']['Observation'] & {
- video: {
- id: number;
- deviceType: string;
- };
- uploaderId: number;
- usecaseTitle: string;
- })[];
};
MediaSentiment: {
- value: number;
- reason: string;
paragraphs: {
- start: number;
end: number;
- value: number;
reason: string;
+ start: number;
+ value: number;
}[];
+ reason: string;
+ value: number;
};
Module:
| components['schemas']['ModuleTitle']
@@ -903,128 +938,128 @@ export interface components {
| components['schemas']['ModuleSetupNote']
| components['schemas']['ModuleTouchpoints']
| components['schemas']['ModuleAdditionalTarget'];
- ModuleDate: {
+ /** ModuleAdditionalTarget */
+ ModuleAdditionalTarget: {
+ output: string;
/** @enum {string} */
- type: 'dates';
+ type: 'additional_target';
variant: string;
- output: {
- start: string;
- };
};
- ModuleGoal: {
+ /** ModuleAge */
+ ModuleAge: {
+ output: components['schemas']['OutputModuleAge'];
/** @enum {string} */
- type: 'goal';
+ type: 'age';
variant: string;
- output: string;
};
- ModuleOutOfScope: {
+ /** ModuleBrowser */
+ ModuleBrowser: {
+ output: components['schemas']['OutputModuleBrowser'];
/** @enum {string} */
- type: 'out_of_scope';
+ type: 'browser';
variant: string;
- output: string;
};
- ModuleTitle: {
+ ModuleDate: {
+ output: {
+ start: string;
+ };
/** @enum {string} */
- type: 'title';
+ type: 'dates';
variant: string;
- output: string;
};
- /** ModuleTask */
- ModuleTask: {
+ /** ModuleGender */
+ ModuleGender: {
+ output: components['schemas']['OutputModuleGender'];
/** @enum {string} */
- type: 'tasks';
+ type: 'gender';
variant: string;
- output: components['schemas']['OutputModuleTask'][];
};
- /** ModuleTouchpoints */
- ModuleTouchpoints: {
+ ModuleGoal: {
+ output: string;
/** @enum {string} */
- type: 'touchpoints';
+ type: 'goal';
variant: string;
- output: components['schemas']['OutputModuleTouchpoints'][];
};
- /** ModuleAge */
- ModuleAge: {
+ /** ModuleInstructionNote */
+ ModuleInstructionNote: {
+ output: string;
/** @enum {string} */
- type: 'age';
+ type: 'instruction_note';
variant: string;
- output: components['schemas']['OutputModuleAge'];
};
- /** ModuleGender */
- ModuleGender: {
+ /** ModuleLanguage */
+ ModuleLanguage: {
+ output: string;
/** @enum {string} */
- type: 'gender';
+ type: 'language';
variant: string;
- output: components['schemas']['OutputModuleGender'];
};
/** ModuleLiteracy */
ModuleLiteracy: {
+ output: components['schemas']['OutputModuleLiteracy'];
/** @enum {string} */
type: 'literacy';
variant: string;
- output: components['schemas']['OutputModuleLiteracy'];
};
- /** ModuleLanguage */
- ModuleLanguage: {
+ ModuleOutOfScope: {
+ output: string;
/** @enum {string} */
- type: 'language';
+ type: 'out_of_scope';
variant: string;
+ };
+ /** ModuleSetupNote */
+ ModuleSetupNote: {
output: string;
+ /** @enum {string} */
+ type: 'setup_note';
+ variant: string;
};
/** ModuleTarget */
ModuleTarget: {
+ output: number;
/** @enum {string} */
type: 'target';
variant: string;
- output: number;
};
/** ModuleTargetNote */
ModuleTargetNote: {
+ output: string;
/** @enum {string} */
type: 'target_note';
variant: string;
- output: string;
};
- /** ModuleSetupNote */
- ModuleSetupNote: {
+ /** ModuleTask */
+ ModuleTask: {
+ output: components['schemas']['OutputModuleTask'][];
/** @enum {string} */
- type: 'setup_note';
+ type: 'tasks';
variant: string;
- output: string;
};
- /** ModuleInstructionNote */
- ModuleInstructionNote: {
- /** @enum {string} */
- type: 'instruction_note';
- variant: string;
+ ModuleTitle: {
output: string;
- };
- /** ModuleBrowser */
- ModuleBrowser: {
/** @enum {string} */
- type: 'browser';
+ type: 'title';
variant: string;
- output: components['schemas']['OutputModuleBrowser'];
};
- /** ModuleAdditionalTarget */
- ModuleAdditionalTarget: {
+ /** ModuleTouchpoints */
+ ModuleTouchpoints: {
+ output: components['schemas']['OutputModuleTouchpoints'][];
/** @enum {string} */
- type: 'additional_target';
+ type: 'touchpoints';
variant: string;
- output: string;
};
/** Observation */
Observation: {
- id: number;
- title: string;
description: string;
/** Format: float */
- start: number;
- /** Format: float */
end: number;
+ id: number;
quotes: string;
- uxNote?: string;
+ /** Format: float */
+ start: number;
tags: components['schemas']['VideoTag'][];
+ title: string;
+ uxNote?: string;
};
/**
* Output
@@ -1032,59 +1067,241 @@ export interface components {
* @enum {string}
*/
Output: 'bugs' | 'media' | 'insights';
- /** PaginationData */
- PaginationData: {
- start?: number;
- size?: number;
- limit?: number;
- total?: number;
+ /** OutputModuleAge */
+ OutputModuleAge: {
+ max: number;
+ min: number;
+ percentage: number;
+ }[];
+ /** OutputModuleBrowser */
+ OutputModuleBrowser: {
+ /** @enum {string} */
+ name: 'firefox' | 'edge' | 'chrome' | 'safari';
+ percentage: number;
+ }[];
+ /** OutputModuleGender */
+ OutputModuleGender: {
+ /** @enum {string} */
+ gender: 'male' | 'female';
+ percentage: number;
+ }[];
+ /** OutputModuleLiteracy */
+ OutputModuleLiteracy: {
+ /** @enum {string} */
+ level: 'beginner' | 'intermediate' | 'expert';
+ percentage: number;
+ }[];
+ /** SubcomponentTask */
+ OutputModuleTask:
+ | components['schemas']['OutputModuleTaskVideo']
+ | components['schemas']['OutputModuleTaskBug']
+ | components['schemas']['OutputModuleTaskSurvey']
+ | components['schemas']['OutputModuleTaskModerateVideo']
+ | components['schemas']['OutputModuleTaskExplorativeBug']
+ | components['schemas']['OutputModuleTaskAccessibility'];
+ /** OutputModuleTaskAccessibility */
+ OutputModuleTaskAccessibility: {
+ description?: string;
+ /** @enum {string} */
+ kind: 'accessibility';
+ title: string;
+ /** Format: uri */
+ url?: string;
};
- Paragraph: {
- text: string;
- start: number;
- end: number;
- /** @description Id Of speaker */
- speaker?: number;
- words: components['schemas']['Word'][];
+ /** SubcomponentTaskBug */
+ OutputModuleTaskBug: {
+ description?: string;
+ /** @enum {string} */
+ kind: 'bug';
+ title: string;
+ /** Format: uri */
+ url?: string;
};
- /** Platform Object */
- Platform: {
- /** @description os */
- id: number;
- /**
- * @description form_factor
- *
- * 0 => smartphone,
- * 1 => tablet
- * 2 => pc
- * 3 => smartwatch
- * 4 => console
- * 5 => tv
- */
- deviceType: number;
+ /** OutputModuleTaskExplorativeBug */
+ OutputModuleTaskExplorativeBug: {
+ description?: string;
+ /** @enum {string} */
+ kind: 'explorative-bug';
+ title: string;
+ /** Format: uri */
+ url?: string;
};
- /** Project */
- Project: {
- id: number;
- name: string;
- campaigns_count: number;
- workspaceId: number;
+ /** OutputModuleTaskModerateVideo */
+ OutputModuleTaskModerateVideo: {
description?: string;
- is_archive?: number;
+ /** @enum {string} */
+ kind: 'moderate-video';
+ title: string;
+ /** Format: uri */
+ url?: string;
};
- /** Report */
- Report: {
- id?: number;
- title?: string;
+ /** SubcomponentTaskSurvey */
+ OutputModuleTaskSurvey: {
description?: string;
- url: string;
- file_type?: {
- extension?: components['schemas']['ReportExtensions'];
- type: string;
- domain_name?: string;
+ /** @enum {string} */
+ kind: 'survey';
+ title: string;
+ /** Format: uri */
+ url?: string;
+ };
+ /** SubcomponentTaskVideo */
+ OutputModuleTaskVideo: {
+ description?: string;
+ /** @enum {string} */
+ kind: 'video';
+ title: string;
+ /** Format: uri */
+ url?: string;
+ };
+ /** SubcomponentTouchpoints */
+ OutputModuleTouchpoints:
+ | components['schemas']['OutputModuleTouchpointsAppDesktop']
+ | components['schemas']['OutputModuleTouchpointsAppTablet']
+ | components['schemas']['OutputModuleTouchpointsAppSmartphone']
+ | components['schemas']['OutputModuleTouchpointsWebDesktop']
+ | components['schemas']['OutputModuleTouchpointsWebTablet']
+ | components['schemas']['OutputModuleTouchpointsWebSmartphone'];
+ /** OutputModuleTouchpointsAppDesktop */
+ OutputModuleTouchpointsAppDesktop: {
+ /** @enum {undefined} */
+ form_factor: 'desktop';
+ /** @enum {undefined} */
+ kind: 'app';
+ os: {
+ linux?: string;
+ macos?: string;
+ windows?: string;
+ };
+ };
+ /** OutputModuleTouchpointsAppSmartphone */
+ OutputModuleTouchpointsAppSmartphone: {
+ /** @enum {undefined} */
+ form_factor: 'smartphone';
+ /** @enum {undefined} */
+ kind: 'app';
+ os: {
+ android?: string;
+ ios?: string;
+ };
+ };
+ /** OutputModuleTouchpointsAppTablet */
+ OutputModuleTouchpointsAppTablet: {
+ /** @enum {undefined} */
+ form_factor: 'tablet';
+ /** @enum {undefined} */
+ kind: 'app';
+ os: {
+ ios?: string;
+ linux?: string;
+ windows?: string;
+ };
+ };
+ /** OutputModuleTouchpointsWebDesktop */
+ OutputModuleTouchpointsWebDesktop: {
+ /** @enum {undefined} */
+ form_factor: 'desktop';
+ /** @enum {undefined} */
+ kind: 'web';
+ os: {
+ linux?: string;
+ macos?: string;
+ windows?: string;
+ };
+ };
+ /** OutputModuleTouchpointsWebSmartphone */
+ OutputModuleTouchpointsWebSmartphone: {
+ /** @enum {undefined} */
+ form_factor: 'smartphone';
+ /** @enum {undefined} */
+ kind: 'web';
+ os: {
+ android?: string;
+ ios?: string;
};
+ };
+ /** OutputModuleTouchpointsWebTablet */
+ OutputModuleTouchpointsWebTablet: {
+ /** @enum {undefined} */
+ form_factor: 'tablet';
+ /** @enum {undefined} */
+ kind: 'web';
+ os: {
+ android?: string;
+ ios?: string;
+ };
+ };
+ /** PaginationData */
+ PaginationData: {
+ limit?: number;
+ size?: number;
+ start?: number;
+ total?: number;
+ };
+ Paragraph: {
+ end: number;
+ /** @description Id Of speaker */
+ speaker?: number;
+ start: number;
+ text: string;
+ words: components['schemas']['Word'][];
+ };
+ /**
+ * PlanStatus
+ * @enum {string}
+ */
+ PlanStatus: 'pending_review' | 'draft' | 'approved';
+ /** Platform Object */
+ Platform: {
+ /**
+ * @description form_factor
+ *
+ * 0 => smartphone,
+ * 1 => tablet
+ * 2 => pc
+ * 3 => smartwatch
+ * 4 => console
+ * 5 => tv
+ */
+ deviceType: number;
+ /** @description os */
+ id: number;
+ };
+ /** Data for post-users request for invited user */
+ PostUserInviteData: {
+ profileId: number;
+ token: string;
+ /** @enum {string} */
+ type: 'invite';
+ };
+ /** Data for post-users request for new user */
+ PostUserNewData: {
+ email: string;
+ /** @enum {string} */
+ type: 'new';
+ workspace: string;
+ };
+ /** Project */
+ Project: {
+ campaigns_count: number;
+ description?: string;
+ id: number;
+ is_archive?: number;
+ name: string;
+ workspaceId: number;
+ };
+ /** Report */
+ Report: {
creation_date?: string;
+ description?: string;
+ file_type?: {
+ domain_name?: string;
+ extension?: components['schemas']['ReportExtensions'];
+ type: string;
+ };
+ id?: number;
+ title?: string;
update_date?: string;
+ url: string;
};
/**
* ReportExtensions
@@ -1114,6 +1331,50 @@ export interface components {
/** @enum {string} */
type: 'smartphone';
};
+ StrapiTemplate: {
+ background?: string;
+ description: string;
+ how?: {
+ description: string;
+ /** Format: uri */
+ icon: string;
+ title: string;
+ }[];
+ /** Format: uri */
+ image?: string;
+ /** Format: uri */
+ output_image?: string;
+ pre_title: string;
+ price?: {
+ /** @default 0 */
+ is_strikethrough?: number;
+ previous_price?: string;
+ price: string;
+ };
+ requirements?: {
+ description: string;
+ list: string[];
+ };
+ tags: {
+ /** Format: uri */
+ icon: string;
+ text: string;
+ }[];
+ title: string;
+ what?: {
+ description: string;
+ goal: string;
+ };
+ why?: {
+ advantages: string[];
+ reasons: {
+ description: string;
+ /** Format: uri */
+ icon: string;
+ title: string;
+ }[];
+ };
+ };
/** Tablet */
Tablet: {
manufacturer: string;
@@ -1123,111 +1384,74 @@ export interface components {
/** @enum {string} */
type: 'tablet';
};
- /**
- * Template
- * @description Template of a usecase object
- */
- Template: {
- title: string;
- /** @description Short description used as preview of template or in templates dropdown */
- description?: string;
- /** @description HTML content used to pre-fill the use case editor */
- content?: string;
- category?: components['schemas']['TemplateCategory'];
- /** @enum {string} */
- device_type?: 'webapp' | 'mobileapp';
- /**
- * @default en
- * @enum {string}
- */
- locale?: 'en' | 'it';
- /** Format: uri */
- image?: string;
- /**
- * @description The use case created by this template needs a login or not?
- * @default false
- */
- requiresLogin?: boolean;
- };
- /**
- * TemplateCategory
- * @description Group different templates
- */
- TemplateCategory: {
- id?: number;
- name: string;
- };
/** Tenant */
Tenant: {
+ email: string;
/** @description tryber wp_user_id */
id: number;
- profile_id: number;
- name: string;
- email: string;
invitationPending: boolean;
+ name: string;
permissionFrom?: {
+ id?: number;
/** @enum {string} */
type?: 'workspace' | 'project';
- id?: number;
};
+ profile_id: number;
};
Transcript: {
+ paragraphs: components['schemas']['Paragraph'][];
/** @description Number of spekers */
speakers: number;
- paragraphs: components['schemas']['Paragraph'][];
};
/** UseCase */
UseCase: {
- title: string;
description: string;
- /** @description Optional in experiential campaigns */
- functionality?: {
- id?: number;
- } & components['schemas']['Template'];
- logged?: boolean;
link?: string;
+ logged?: boolean;
+ title: string;
};
/** User */
User: {
- /** @description This is the main id of the user. Currently is equal to tryber_wp_user_id */
- id: number;
+ customer_role: string;
/** Format: email */
email: string;
- role: string;
+ features?: components['schemas']['Feature'][];
+ /** @description This is the main id of the user. Currently is equal to tryber_wp_user_id */
+ id: number;
name: string;
+ picture?: string;
profile_id: number;
+ role: string;
tryber_wp_user_id: number;
unguess_wp_user_id: number;
- picture?: string;
- features?: components['schemas']['Feature'][];
};
/** UserPreference */
UserPreference: {
+ name: string;
preference_id: number;
value: string;
- name: string;
};
/**
* Video
* @description Video uploaded from a user
*/
Video: {
+ duration?: number;
id: number;
- url: string;
- streamUrl?: string;
poster?: string;
- duration?: number;
+ sentiment?: components['schemas']['MediaSentiment'];
+ streamUrl?: string;
tester: {
- id: number;
- name: string;
- surname: string;
device: {
/** @enum {string} */
type: 'smartphone' | 'tablet' | 'desktop' | 'other';
};
+ id: number;
+ name: string;
+ surname: string;
};
transcript?: components['schemas']['Transcript'];
- sentiment?: components['schemas']['MediaSentiment'];
+ url: string;
};
/** VideoTag */
VideoTag: {
@@ -1252,9 +1476,9 @@ export interface components {
| components['schemas']['Desktop']
| components['schemas']['Tablet']
) & {
- unique_bugs: number;
/** @description Unique bugs */
bugs: number;
+ unique_bugs: number;
})[];
/**
* @default bugsByDevice
@@ -1280,15 +1504,15 @@ export interface components {
*/
WidgetBugsByUseCase: {
data: {
+ bugs: number;
+ description: string;
title: {
full: string;
- simple?: string;
- prefix?: string;
info?: string;
+ prefix?: string;
+ simple?: string;
};
- description: string;
uniqueBugs?: number;
- bugs: number;
usecase_completion?: number;
usecase_id: number;
}[];
@@ -1305,18 +1529,18 @@ export interface components {
*/
WidgetCampaignProgress: {
data: {
- start_date: string;
end_date: string;
+ /** @description Expected amount of hours required to complete the campaign */
+ expected_duration: number;
+ start_date: string;
+ /** @description Number of hours from start_date */
+ time_elapsed: number;
/**
* Format: float
* @description Percentage fixed rate of completion
* @enum {number}
*/
usecase_completion: 12.5 | 37.5 | 62.5 | 87.5 | 100;
- /** @description Number of hours from start_date */
- time_elapsed: number;
- /** @description Expected amount of hours required to complete the campaign */
- expected_duration: number;
};
/**
* @default campaignProgress
@@ -1331,9 +1555,9 @@ export interface components {
*/
WidgetCampaignUniqueBugs: {
data: {
- unique: number;
total: number;
trend: number;
+ unique: number;
};
/**
* @default campaignUniqueBugs
@@ -1342,29 +1566,41 @@ export interface components {
*/
kind: 'campaignUniqueBugs';
};
+ /** WidgetCampaignUxMostUsedTitles */
+ WidgetCampaignUxMostUsedTitles: {
+ data: {
+ mostUsedTitles: {
+ mainSeverityAssignment: string;
+ title: string;
+ usage: number;
+ }[];
+ };
+ /** @enum {undefined} */
+ kind: 'uxMostUsedTitles';
+ };
/**
* WidgetCampaignUxProgress
* @description Used to show an overview of Ux progress
*/
WidgetCampaignUxProgress: {
data: {
- countMediaWithObservation?: number;
countMedia?: number;
- countTitleTag?: number;
+ countMediaWithObservation?: number;
countObservation?: number;
countObservationNoTitle?: number;
countRecurrentTitles?: number;
- severitiesDistribution?: {
- countPositiveFindings: number;
- countMinorIssue: number;
- countMajorIssue: number;
- countObservations: number;
- };
+ countTitleTag?: number;
mostUsedTitles?: {
+ mainSeverityAssignment: string;
title: string;
usage: number;
- mainSeverityAssignment: string;
}[];
+ severitiesDistribution?: {
+ countMajorIssue: number;
+ countMinorIssue: number;
+ countObservations: number;
+ countPositiveFindings: number;
+ };
};
/**
* @default uxTaggingVideoCompletion
@@ -1377,312 +1613,70 @@ export interface components {
| 'uxSeveritiesDistribution'
| 'uxMostUsedTitles';
};
- Word: {
- start: number;
- end: number;
- /** @description Id of Speaker */
- speaker?: number;
- word: string;
- };
- /**
- * Workspace
- * @description A workspace is the company area with projects and campaigns
- */
- Workspace: {
- id: number;
- company: string;
- tokens: number;
- logo?: string;
- csm: {
- id: number;
- email: string;
- name: string;
- profile_id: number;
- tryber_wp_user_id: number;
- picture?: string;
- url?: string;
- };
- /** @description express coins */
- coins?: number;
- /** @description Do this workspace have shared items? */
- isShared?: boolean;
- /** @description Number of shared items */
- sharedItems?: number;
- };
- /** WidgetCampaignUxTaggingVideoCompletionData */
- WidgetCampaignUxTaggingVideoCompletionData: {
- data: {
- countMediaWithObservation: number;
- countMedia: number;
- };
- /** @enum {undefined} */
- kind: 'uxTaggingVideoCompletion';
- };
- /** WidgetCampaignUxTotalTitlesVsRecurrentTitles */
- WidgetCampaignUxTotalTitlesVsRecurrentTitles: {
- data: {
- countTitleTag: number;
- countObservationNoTitle: number;
- countRecurrentTitles: number;
- };
- /** @enum {undefined} */
- kind: 'uxTotalTitlesVsRecurrentTitles';
- };
/** WidgetCampaignUxSeveritiesDistribution */
WidgetCampaignUxSeveritiesDistribution: {
data: {
countObservations: number;
severitiesDistribution: {
- countPositiveFindings: number;
- countMinorIssue: number;
countMajorIssue: number;
+ countMinorIssue: number;
countObservationSeverity: number;
+ countPositiveFindings: number;
};
};
/** @enum {undefined} */
kind: 'uxSeveritiesDistribution';
};
- /** WidgetCampaignUxMostUsedTitles */
- WidgetCampaignUxMostUsedTitles: {
+ /** WidgetCampaignUxTaggingVideoCompletionData */
+ WidgetCampaignUxTaggingVideoCompletionData: {
data: {
- mostUsedTitles: {
- title: string;
- usage: number;
- mainSeverityAssignment: string;
- }[];
- };
- /** @enum {undefined} */
- kind: 'uxMostUsedTitles';
- };
- /**
- * BannerType
- * @enum {string}
- */
- BannerType:
- | 'banner_testing_automation'
- | 'banner_user_experience'
- | 'banner_cyber_security';
- /** CpReqTemplate */
- CpReqTemplate: {
- id: number;
- name: string;
- description?: string;
- config: string;
- workspace_id?: number;
- price?: string;
- strapi?: components['schemas']['StrapiTemplate'];
- };
- /** SubcomponentTaskBug */
- OutputModuleTaskBug: {
- /** @enum {string} */
- kind: 'bug';
- title: string;
- description?: string;
- /** Format: uri */
- url?: string;
- };
- /** OutputModuleAge */
- OutputModuleAge: {
- min: number;
- max: number;
- percentage: number;
- }[];
- /** SubcomponentTaskVideo */
- OutputModuleTaskVideo: {
- /** @enum {string} */
- kind: 'video';
- title: string;
- description?: string;
- /** Format: uri */
- url?: string;
- };
- /** SubcomponentTaskSurvey */
- OutputModuleTaskSurvey: {
- /** @enum {string} */
- kind: 'survey';
- title: string;
- description?: string;
- /** Format: uri */
- url?: string;
- };
- /** OutputModuleTaskModerateVideo */
- OutputModuleTaskModerateVideo: {
- /** @enum {string} */
- kind: 'moderate-video';
- title: string;
- description?: string;
- /** Format: uri */
- url?: string;
- };
- /** OutputModuleTaskExplorativeBug */
- OutputModuleTaskExplorativeBug: {
- /** @enum {string} */
- kind: 'explorative-bug';
- title: string;
- description?: string;
- /** Format: uri */
- url?: string;
- };
- /** OutputModuleTaskAccessibility */
- OutputModuleTaskAccessibility: {
- /** @enum {string} */
- kind: 'accessibility';
- title: string;
- description?: string;
- /** Format: uri */
- url?: string;
- };
- /** SubcomponentTask */
- OutputModuleTask:
- | components['schemas']['OutputModuleTaskVideo']
- | components['schemas']['OutputModuleTaskBug']
- | components['schemas']['OutputModuleTaskSurvey']
- | components['schemas']['OutputModuleTaskModerateVideo']
- | components['schemas']['OutputModuleTaskExplorativeBug']
- | components['schemas']['OutputModuleTaskAccessibility'];
- /** SubcomponentTouchpoints */
- OutputModuleTouchpoints:
- | components['schemas']['OutputModuleTouchpointsAppDesktop']
- | components['schemas']['OutputModuleTouchpointsAppTablet']
- | components['schemas']['OutputModuleTouchpointsAppSmartphone']
- | components['schemas']['OutputModuleTouchpointsWebDesktop']
- | components['schemas']['OutputModuleTouchpointsWebTablet']
- | components['schemas']['OutputModuleTouchpointsWebSmartphone'];
- /** OutputModuleTouchpointsAppDesktop */
- OutputModuleTouchpointsAppDesktop: {
- /** @enum {undefined} */
- kind: 'app';
- /** @enum {undefined} */
- form_factor: 'desktop';
- os: {
- linux?: string;
- macos?: string;
- windows?: string;
- };
- };
- /** OutputModuleTouchpointsAppTablet */
- OutputModuleTouchpointsAppTablet: {
- /** @enum {undefined} */
- kind: 'app';
- /** @enum {undefined} */
- form_factor: 'tablet';
- os: {
- linux?: string;
- ios?: string;
- windows?: string;
+ countMedia: number;
+ countMediaWithObservation: number;
};
- };
- /** OutputModuleTouchpointsAppSmartphone */
- OutputModuleTouchpointsAppSmartphone: {
- /** @enum {undefined} */
- kind: 'app';
/** @enum {undefined} */
- form_factor: 'smartphone';
- os: {
- android?: string;
- ios?: string;
- };
+ kind: 'uxTaggingVideoCompletion';
};
- /** OutputModuleTouchpointsWebDesktop */
- OutputModuleTouchpointsWebDesktop: {
- /** @enum {undefined} */
- kind: 'web';
- /** @enum {undefined} */
- form_factor: 'desktop';
- os: {
- linux?: string;
- macos?: string;
- windows?: string;
+ /** WidgetCampaignUxTotalTitlesVsRecurrentTitles */
+ WidgetCampaignUxTotalTitlesVsRecurrentTitles: {
+ data: {
+ countObservationNoTitle: number;
+ countRecurrentTitles: number;
+ countTitleTag: number;
};
- };
- /** OutputModuleTouchpointsWebTablet */
- OutputModuleTouchpointsWebTablet: {
- /** @enum {undefined} */
- kind: 'web';
/** @enum {undefined} */
- form_factor: 'tablet';
- os: {
- android?: string;
- ios?: string;
- };
+ kind: 'uxTotalTitlesVsRecurrentTitles';
};
- /** OutputModuleTouchpointsWebSmartphone */
- OutputModuleTouchpointsWebSmartphone: {
- /** @enum {undefined} */
- kind: 'web';
- /** @enum {undefined} */
- form_factor: 'smartphone';
- os: {
- android?: string;
- ios?: string;
- };
+ Word: {
+ end: number;
+ /** @description Id of Speaker */
+ speaker?: number;
+ start: number;
+ word: string;
};
- /** OutputModuleLiteracy */
- OutputModuleLiteracy: {
- /** @enum {string} */
- level: 'beginner' | 'intermediate' | 'expert';
- percentage: number;
- }[];
- /** OutputModuleGender */
- OutputModuleGender: {
- /** @enum {string} */
- gender: 'male' | 'female';
- percentage: number;
- }[];
- /** OutputModuleBrowser */
- OutputModuleBrowser: {
- /** @enum {string} */
- name: 'firefox' | 'edge' | 'chrome' | 'safari';
- percentage: number;
- }[];
/**
- * PlanStatus
- * @enum {string}
+ * Workspace
+ * @description A workspace is the company area with projects and campaigns
*/
- PlanStatus: 'pending_review' | 'draft' | 'approved';
- StrapiTemplate: {
- title: string;
- description: string;
- pre_title: string;
- /** Format: uri */
- image?: string;
- /** Format: uri */
- output_image?: string;
- requirements?: {
- description: string;
- list: string[];
- };
- tags: {
- /** Format: uri */
- icon: string;
- text: string;
- }[];
- why?: {
- reasons: {
- /** Format: uri */
- icon: string;
- title: string;
- description: string;
- }[];
- advantages: string[];
- };
- what?: {
- description: string;
- goal: string;
- };
- how?: {
- /** Format: uri */
- icon: string;
- title: string;
- description: string;
- }[];
- price?: {
- price: string;
- previous_price?: string;
- /** @default 0 */
- is_strikethrough?: number;
+ Workspace: {
+ /** @description express coins */
+ coins?: number;
+ company: string;
+ csm: {
+ email: string;
+ id: number;
+ name: string;
+ picture?: string;
+ profile_id: number;
+ tryber_wp_user_id: number;
+ url?: string;
};
- background?: string;
+ id: number;
+ /** @description Do this workspace have shared items? */
+ isShared?: boolean;
+ logo?: string;
+ /** @description Number of shared items */
+ sharedItems?: number;
+ tokens: number;
};
};
responses: {
@@ -1691,27 +1685,33 @@ export interface components {
content: {
'application/json': components['schemas']['Error'];
};
- };
- };
- parameters: {
- /** @description Workspace (company, customer) id */
- wid: string;
- /** @description Project id */
- pid: string;
+ };
+ };
+ parameters: {
+ /** @description Defines an identifier for the bug object (BUG ID) */
+ bid: string;
+ /** @description Campaign id */
+ cid: string;
+ /** @description Custom Status id */
+ csid: string;
+ /** @description filterBy[]= */
+ filterBy: unknown;
+ /** @description Insight id */
+ iid: string;
/** @description Limit pagination parameter */
limit: number;
- /** @description Start pagination parameter */
- start: number;
/** @description Order value (ASC, DESC) */
order: string;
/** @description Order by accepted field */
orderBy: string;
- /** @description filterBy[]= */
- filterBy: unknown;
- /** @description Campaign id */
- cid: string;
- /** @description Defines an identifier for the bug object (BUG ID) */
- bid: string;
+ /** @description Project id */
+ pid: string;
+ /** @description keywords to search */
+ search: string;
+ /** @description Start pagination parameter */
+ start: number;
+ /** @description Workspace (company, customer) id */
+ wid: string;
/** @description Campaign widget slug */
wslug:
| 'bugs-by-usecase'
@@ -1723,67 +1723,51 @@ export interface components {
| 'ux-total-titles-vs-recurrent-titles'
| 'ux-severities-distribution'
| 'ux-most-used-titles';
- /** @description keywords to search */
- search: string;
- /** @description Custom Status id */
- csid: string;
- /** @description Insight id */
- iid: string;
};
requestBodies: {
- Credentials: {
- content: {
- 'application/json': {
- username: string;
- password: string;
- };
- };
- };
Campaign: {
content: {
'application/json': {
- title: string;
- start_date: string;
- end_date: string;
- close_date: string;
- customer_title?: string;
- status_id?: number;
- is_public?: number;
+ base_bug_internal_id?: string;
+ browsers?: number[];
campaign_type_id: number;
- project_id: number;
- pm_id: number;
- platforms: components['schemas']['Platform'][];
- /** @description Da togliere */
- page_preview_id?: number;
- /** @description Da togliere */
- page_manual_id?: number;
+ close_date: string;
/** @description Used to check available coins */
customer_id: number;
+ customer_title?: string;
+ description?: string;
+ end_date: string;
+ goal?: string;
has_bug_form?: number;
/** @description if has_bug_form is 0 this has to be 0 */
has_bug_parade?: number;
- description?: string;
- base_bug_internal_id?: string;
- express_slug: string;
- use_cases?: components['schemas']['UseCase'][];
- productType?: number;
- productLink?: string;
- browsers?: number[];
+ is_public?: number;
languages?: string[];
outOfScope?: string;
- testerRequirements?: string;
+ /** @description Da togliere */
+ page_manual_id?: number;
+ /** @description Da togliere */
+ page_preview_id?: number;
+ platforms: components['schemas']['Platform'][];
+ pm_id: number;
+ productLink?: string;
+ productType?: number;
+ project_id: number;
+ start_date: string;
+ status_id?: number;
targetSize?: number;
- goal?: string;
testDescription?: string;
+ testerRequirements?: string;
+ title: string;
+ use_cases?: components['schemas']['UseCase'][];
};
};
};
- Project: {
+ Credentials: {
content: {
'application/json': {
- name: string;
- customer_id: number;
- description?: string;
+ password: string;
+ username: string;
};
};
};
@@ -1791,12 +1775,21 @@ export interface components {
content: {
'application/json': {
email: string;
- name?: string;
- surname?: string;
- locale?: string;
event_name?: string;
- redirect_url?: string;
+ locale?: string;
message?: string;
+ name?: string;
+ redirect_url?: string;
+ surname?: string;
+ };
+ };
+ };
+ Project: {
+ content: {
+ 'application/json': {
+ customer_id: number;
+ description?: string;
+ name: string;
};
};
};
@@ -1817,20 +1810,6 @@ export interface operations {
500: components['responses']['Error'];
};
};
- /** A request to login with your username and password */
- 'post-authenticate': {
- parameters: {};
- responses: {
- /** OK */
- 200: {
- content: {
- 'application/json': components['schemas']['Authentication'];
- };
- };
- 500: components['responses']['Error'];
- };
- requestBody: components['requestBodies']['Credentials'];
- };
'post-analytics-views-campaigns-cid': {
parameters: {
path: {
@@ -1850,21 +1829,19 @@ export interface operations {
500: components['responses']['Error'];
};
};
- 'post-campaigns': {
+ /** A request to login with your username and password */
+ 'post-authenticate': {
parameters: {};
responses: {
/** OK */
200: {
content: {
- 'application/json': components['schemas']['Campaign'];
+ 'application/json': components['schemas']['Authentication'];
};
};
- 400: components['responses']['Error'];
- 403: components['responses']['Error'];
- 404: components['responses']['Error'];
500: components['responses']['Error'];
};
- requestBody: components['requestBodies']['Campaign'];
+ requestBody: components['requestBodies']['Credentials'];
};
'get-campaign': {
parameters: {
@@ -1955,21 +1932,21 @@ export interface operations {
content: {
'application/json': {
items?: (components['schemas']['Bug'] & {
- tags?: {
- tag_id: number;
- tag_name: string;
- }[];
- siblings: number;
- comments: number;
additional_fields?: {
+ name: string;
slug: string;
value: string;
- name: string;
+ }[];
+ comments: number;
+ siblings: number;
+ tags?: {
+ tag_id: number;
+ tag_name: string;
}[];
})[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -1994,13 +1971,13 @@ export interface operations {
200: {
content: {
'application/json': components['schemas']['Bug'] & {
- media: components['schemas']['BugMedia'][];
- tags: components['schemas']['BugTag'][];
additional_fields: components['schemas']['BugAdditionalField'][];
+ media: components['schemas']['BugMedia'][];
reporter: {
- tester_id: number;
name: string;
+ tester_id: number;
};
+ tags: components['schemas']['BugTag'][];
};
};
};
@@ -2024,12 +2001,12 @@ export interface operations {
200: {
content: {
'application/json': {
+ custom_status?: components['schemas']['BugCustomStatus'];
+ priority?: components['schemas']['BugPriority'];
tags?: {
tag_id: number;
tag_name: string;
}[];
- priority?: components['schemas']['BugPriority'];
- custom_status?: components['schemas']['BugCustomStatus'];
};
};
};
@@ -2037,6 +2014,8 @@ export interface operations {
requestBody: {
content: {
'application/json': {
+ custom_status_id?: number;
+ priority_id?: number;
tags?: (
| {
tag_id: number;
@@ -2045,8 +2024,6 @@ export interface operations {
tag_name: string;
}
)[];
- priority_id?: number;
- custom_status_id?: number;
};
};
};
@@ -2097,24 +2074,23 @@ export interface operations {
requestBody: {
content: {
'application/json': {
- text: string;
- mentioned?: {
+ media_id?: {
id: number;
}[];
- media_id?: {
+ mentioned?: {
id: number;
}[];
+ text: string;
};
};
};
};
- 'post-campaigns-cid-bugs-bid-media': {
+ 'post-campaigns-cid-bugs-bid-comments-cmid-media': {
parameters: {
path: {
- /** Campaign id */
cid: string;
- /** Defines an identifier for the bug object (BUG ID) */
bid: string;
+ cmid: string;
};
};
responses: {
@@ -2123,12 +2099,16 @@ export interface operations {
content: {
'application/json': {
failed?: {
- name: string;
/** @enum {string} */
errorCode:
| 'FILE_TOO_BIG'
| 'INVALID_FILE_EXTENSION'
| 'GENERIC_ERROR';
+ name: string;
+ }[];
+ files?: {
+ name: string;
+ path: string;
}[];
uploaded_ids?: {
id: number;
@@ -2145,7 +2125,7 @@ export interface operations {
};
};
};
- 'post-campaigns-cid-bugs-bid-comments-cmid-media': {
+ 'delete-campaigns-cid-bugs-bid-comments-cmid': {
parameters: {
path: {
cid: string;
@@ -2153,22 +2133,40 @@ export interface operations {
cmid: string;
};
};
+ responses: {
+ /** OK */
+ 200: unknown;
+ 400: components['responses']['Error'];
+ 403: components['responses']['Error'];
+ 500: components['responses']['Error'];
+ };
+ requestBody: {
+ content: {
+ 'application/json': { [key: string]: unknown };
+ };
+ };
+ };
+ 'post-campaigns-cid-bugs-bid-media': {
+ parameters: {
+ path: {
+ /** Campaign id */
+ cid: string;
+ /** Defines an identifier for the bug object (BUG ID) */
+ bid: string;
+ };
+ };
responses: {
/** OK */
200: {
content: {
'application/json': {
- files?: {
- name: string;
- path: string;
- }[];
failed?: {
- name: string;
/** @enum {string} */
errorCode:
| 'FILE_TOO_BIG'
| 'INVALID_FILE_EXTENSION'
| 'GENERIC_ERROR';
+ name: string;
}[];
uploaded_ids?: {
id: number;
@@ -2185,27 +2183,6 @@ export interface operations {
};
};
};
- 'delete-campaigns-cid-bugs-bid-comments-cmid': {
- parameters: {
- path: {
- cid: string;
- bid: string;
- cmid: string;
- };
- };
- responses: {
- /** OK */
- 200: unknown;
- 400: components['responses']['Error'];
- 403: components['responses']['Error'];
- 500: components['responses']['Error'];
- };
- requestBody: {
- content: {
- 'application/json': { [key: string]: unknown };
- };
- };
- };
'get-campaigns-bug-siblings': {
parameters: {
path: {
@@ -2221,32 +2198,32 @@ export interface operations {
content: {
'application/json': {
father?: {
- id: number;
- title: {
- full: string;
- compact: string;
- context?: string[];
- };
context?: string;
device: string;
+ id: number;
os: {
name: string;
version: string;
};
- };
- siblings: {
- id: number;
title: {
- full: string;
compact: string;
context?: string[];
+ full: string;
};
+ };
+ siblings: {
context?: string;
device: string;
+ id: number;
os: {
name: string;
version: string;
};
+ title: {
+ compact: string;
+ context?: string[];
+ full: string;
+ };
}[];
};
};
@@ -2340,10 +2317,10 @@ export interface operations {
requestBody: {
content: {
'application/json': {
+ color: string;
/** @description se esiste già questo parametro viene passato nel request body\r\nse invece non esiste ed il custom status deve essere creato, non viene passato */
custom_status_id?: number;
name: string;
- color: string;
}[];
};
};
@@ -2435,11 +2412,11 @@ export interface operations {
requestBody: {
content: {
'application/json': {
- title: string;
+ comment?: string;
description?: string;
- severity_id: number;
observations_ids: number[];
- comment?: string;
+ severity_id: number;
+ title: string;
visible?: number;
};
};
@@ -2458,9 +2435,9 @@ export interface operations {
200: {
content: {
'application/json': components['schemas']['Campaign'] & {
- selected_testers: number;
/** @description Array of form factors */
allowed_devices: string[];
+ selected_testers: number;
};
};
};
@@ -2489,37 +2466,37 @@ export interface operations {
content: {
'application/json':
| {
+ /**
+ * @default usecase-grapes
+ * @example usecase-grapes
+ * @enum {string}
+ */
+ kind: 'usecase-grapes';
results: {
- usecaseId: number;
- usecaseTitle: string;
grapes: components['schemas']['Grapes'][];
ungrouped: (components['schemas']['Observation'] & {
- uploaderId: number;
- mediaId: number;
deviceType: string;
+ mediaId: number;
+ uploaderId: number;
usecaseTitle: string;
})[];
+ usecaseId: number;
+ usecaseTitle: string;
}[];
- /**
- * @default usecase-grapes
- * @example usecase-grapes
- * @enum {string}
- */
- kind: 'usecase-grapes';
}
| {
- results: (components['schemas']['Observation'] & {
- uploaderId: number;
- mediaId: number;
- deviceType: string;
- usecaseTitle: string;
- })[];
/**
* @default ungrouped
* @example ungrouped
* @enum {string}
*/
kind: 'ungrouped';
+ results: (components['schemas']['Observation'] & {
+ deviceType: string;
+ mediaId: number;
+ uploaderId: number;
+ usecaseTitle: string;
+ })[];
};
};
};
@@ -2635,9 +2612,9 @@ export interface operations {
content: {
'application/json': {
suggestion?: {
- slug: components['schemas']['BannerType'];
/** @description ServiceId from strapi */
serviceId?: number;
+ slug: components['schemas']['BannerType'];
};
};
};
@@ -2682,10 +2659,10 @@ export interface operations {
200: {
content: {
'application/json': {
- tag_id: number;
display_name: string;
- slug: string;
is_public?: number;
+ slug: string;
+ tag_id: number;
}[];
};
};
@@ -2710,14 +2687,15 @@ export interface operations {
200: {
content: {
'application/json': {
+ completion: number;
+ content?: string;
id: number;
title: {
full: string;
- simple?: string;
- prefix?: string;
info?: string;
+ prefix?: string;
+ simple?: string;
};
- completion: number;
}[];
};
};
@@ -2750,9 +2728,9 @@ export interface operations {
content: {
'application/json': {
items: components['schemas']['Tenant'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -2775,9 +2753,9 @@ export interface operations {
200: {
content: {
'application/json': {
+ email: string;
profile_id: number;
tryber_wp_user_id: number;
- email: string;
};
};
};
@@ -2834,49 +2812,49 @@ export interface operations {
200: {
content: {
'application/json': {
- goal?: string;
- users?: number;
findings?: {
+ cluster:
+ | {
+ id: number;
+ name: string;
+ }[]
+ | 'all';
+ comment?: string;
+ description: string;
/** @description this field is the Finding ID */
id: number;
- title: string;
- description: string;
- comment?: string;
severity: {
id: number;
name: string;
style: string;
};
- cluster:
- | {
- id: number;
- name: string;
- }[]
- | 'all';
+ title: string;
video?: {
- url: string;
- streamUrl: string;
+ description?: string;
+ end: number;
poster?: string;
start: number;
- end: number;
- description?: string;
+ streamUrl: string;
+ url: string;
}[];
}[];
+ goal?: string;
+ methodology?: {
+ description: string;
+ type: string;
+ };
+ questions?: {
+ text: string;
+ }[];
sentiment?: {
cluster: {
id: number;
name: string;
};
- value: number;
comment: string;
+ value: number;
}[];
- methodology?: {
- type: string;
- description: string;
- };
- questions?: {
- text: string;
- }[];
+ users?: number;
};
};
};
@@ -3065,25 +3043,37 @@ export interface operations {
requestBody: {
content: {
'application/json': {
- title?: string;
+ comment?: string;
description?: string;
- severity_id?: number;
observations_ids?: number[];
- comment?: string;
+ severity_id?: number;
+ title?: string;
visible?: number;
};
};
};
};
- 'get-media-id': {
+ 'get-invites-profile-token': {
parameters: {
path: {
- id: string;
+ profile: string;
+ token: string;
};
};
responses: {
- /** Found */
- 302: never;
+ /** OK */
+ 200: {
+ content: {
+ 'application/json': {
+ email: string;
+ name: string;
+ surname: string;
+ workspace: string;
+ };
+ };
+ };
+ /** Bad Request */
+ 400: unknown;
};
};
/** Delete a media-comment */
@@ -3106,6 +3096,113 @@ export interface operations {
404: unknown;
};
};
+ 'get-media-id': {
+ parameters: {
+ path: {
+ id: string;
+ };
+ };
+ responses: {
+ /** Found */
+ 302: never;
+ };
+ };
+ 'get-workspaces-wid-plans-pid': {
+ parameters: {
+ path: {
+ pid: string;
+ };
+ };
+ responses: {
+ /** OK */
+ 200: {
+ content: {
+ 'application/json': {
+ campaign?: {
+ id: number;
+ startDate: string;
+ /** @description CustomerTitle ?? Title */
+ title: string;
+ };
+ config: {
+ modules: components['schemas']['Module'][];
+ };
+ id: number;
+ project: {
+ id: number;
+ name: string;
+ };
+ quote?: {
+ id: number;
+ /** @enum {string} */
+ status: 'pending' | 'proposed' | 'approved' | 'rejected';
+ value: string;
+ };
+ status: components['schemas']['PlanStatus'];
+ workspace_id: number;
+ };
+ };
+ };
+ };
+ };
+ 'delete-workspaces-wid-plans-pid': {
+ parameters: {
+ path: {
+ pid: string;
+ };
+ };
+ responses: {
+ /** OK */
+ 200: unknown;
+ };
+ };
+ 'patch-workspaces-wid-plans-pid': {
+ parameters: {
+ path: {
+ pid: string;
+ };
+ };
+ responses: {
+ /** OK */
+ 200: unknown;
+ /** Forbidden */
+ 403: unknown;
+ /** Not Found */
+ 404: unknown;
+ };
+ requestBody: {
+ content: {
+ 'application/json': {
+ config: {
+ modules: components['schemas']['Module'][];
+ };
+ };
+ };
+ };
+ };
+ /** */
+ 'patch-workspaces-wid-plans-pid-status': {
+ parameters: {
+ path: {
+ pid: string;
+ };
+ };
+ responses: {
+ /** OK */
+ 200: {
+ content: {
+ 'application/json': { [key: string]: unknown };
+ };
+ };
+ };
+ requestBody: {
+ content: {
+ 'application/json': {
+ status: components['schemas']['PlanStatus'];
+ };
+ };
+ };
+ };
'post-projects': {
responses: {
/** OK */
@@ -3214,9 +3311,9 @@ export interface operations {
content: {
'application/json': {
items?: components['schemas']['CampaignWithOutput'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -3252,9 +3349,9 @@ export interface operations {
content: {
'application/json': {
items: components['schemas']['Tenant'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -3277,9 +3374,9 @@ export interface operations {
200: {
content: {
'application/json': {
+ email: string;
profile_id: number;
tryber_wp_user_id: number;
- email: string;
};
};
};
@@ -3298,52 +3395,69 @@ export interface operations {
};
};
responses: {
- /** OK */
- 200: {
+ /** OK */
+ 200: {
+ content: {
+ 'application/json': {
+ items: components['schemas']['Tenant'][];
+ };
+ };
+ };
+ 400: components['responses']['Error'];
+ 403: components['responses']['Error'];
+ 500: components['responses']['Error'];
+ };
+ requestBody: {
+ content: {
+ 'application/json': {
+ include_shared?: boolean;
+ /** @description Tryber WP USER ID */
+ user_id: number;
+ };
+ };
+ };
+ };
+ 'post-users': {
+ parameters: {};
+ responses: {
+ /** Created */
+ 201: {
content: {
'application/json': {
- items: components['schemas']['Tenant'][];
+ projectId?: number;
+ workspaceId: number;
};
};
};
400: components['responses']['Error'];
- 403: components['responses']['Error'];
- 500: components['responses']['Error'];
};
requestBody: {
content: {
'application/json': {
- /** @description Tryber WP USER ID */
- user_id: number;
- include_shared?: boolean;
- };
+ name: string;
+ password: string;
+ roleId: number;
+ surname: string;
+ } & (
+ | components['schemas']['PostUserInviteData']
+ | components['schemas']['PostUserNewData']
+ );
};
};
};
- /** Retrieve all available use case templates */
- 'get-templates': {
+ 'head-users-by-email-email': {
parameters: {
- query: {
- /** filterBy[]= */
- filterBy?: components['parameters']['filterBy'];
- /** Order value (ASC, DESC) */
- order?: components['parameters']['order'];
- /** Order by accepted field */
- orderBy?: components['parameters']['orderBy'];
+ path: {
+ email: string;
};
};
responses: {
/** OK */
- 200: {
- content: {
- 'application/json': ({
- id?: number;
- } & components['schemas']['Template'])[];
- };
- };
- 400: components['responses']['Error'];
- 403: components['responses']['Error'];
- 500: components['responses']['Error'];
+ 200: unknown;
+ /** Bad Request */
+ 400: unknown;
+ /** Not Found */
+ 404: unknown;
};
};
'get-users-me': {
@@ -3397,6 +3511,20 @@ export interface operations {
};
};
};
+ 'get-users-roles': {
+ parameters: {};
+ responses: {
+ /** OK */
+ 200: {
+ content: {
+ 'application/json': {
+ id: number;
+ name: string;
+ }[];
+ };
+ };
+ };
+ };
/** Retrive single video data */
'get-videos-vid': {
parameters: {
@@ -3453,10 +3581,10 @@ export interface operations {
requestBody: {
content: {
'application/json': {
- /** Format: float */
- start: number;
/** Format: float */
end: number;
+ /** Format: float */
+ start: number;
};
};
};
@@ -3493,14 +3621,14 @@ export interface operations {
requestBody: {
content: {
'application/json': {
- title?: string;
description?: string;
/** Format: float */
- start?: number;
- /** Format: float */
end?: number;
quotes?: string;
+ /** Format: float */
+ start?: number;
tags?: number[];
+ title?: string;
};
};
};
@@ -3525,9 +3653,9 @@ export interface operations {
/** @default 0 */
processing: number;
sentences: {
- text: string;
- start: number;
end: number;
+ start: number;
+ text: string;
}[];
};
};
@@ -3593,9 +3721,9 @@ export interface operations {
content: {
'application/json': {
items?: components['schemas']['Workspace'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -3613,8 +3741,8 @@ export interface operations {
200: {
content: {
'application/json': {
- id: number;
company: string;
+ id: number;
};
};
};
@@ -3664,10 +3792,10 @@ export interface operations {
200: {
content: {
'application/json': {
+ campaignsCounter: number;
+ description: string;
id: number;
name: string;
- description: string;
- campaignsCounter: number;
};
};
};
@@ -3701,9 +3829,9 @@ export interface operations {
content: {
'application/json': {
items?: components['schemas']['CampaignWithOutput'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -3737,9 +3865,9 @@ export interface operations {
content: {
'application/json': {
items?: components['schemas']['Coin'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -3779,9 +3907,6 @@ export interface operations {
content: {
'application/json': {
id: number;
- title: string;
- /** @enum {string} */
- status: 'draft' | 'pending_review' | 'approved';
project: {
id: number;
title: string;
@@ -3791,6 +3916,9 @@ export interface operations {
/** @enum {string} */
status: 'pending' | 'proposed' | 'approved' | 'rejected';
};
+ /** @enum {string} */
+ status: 'draft' | 'pending_review' | 'approved';
+ title: string;
}[];
};
};
@@ -3819,16 +3947,23 @@ export interface operations {
requestBody: {
content: {
'application/json': {
- template_id: number;
project_id: number;
+ template_id: number;
};
};
};
};
- 'get-workspaces-wid-plans-pid': {
+ 'get-workspace-projects': {
parameters: {
path: {
- pid: string;
+ /** Workspace (company, customer) id */
+ wid: components['parameters']['wid'];
+ };
+ query: {
+ /** Limit pagination parameter */
+ limit?: components['parameters']['limit'];
+ /** Start pagination parameter */
+ start?: components['parameters']['start'];
};
};
responses: {
@@ -3836,96 +3971,49 @@ export interface operations {
200: {
content: {
'application/json': {
- id: number;
- config: {
- modules: components['schemas']['Module'][];
- };
- status: components['schemas']['PlanStatus'];
- project: {
- id: number;
- name: string;
- };
- quote?: {
- id: number;
- /** @enum {string} */
- status: 'pending' | 'proposed' | 'approved' | 'rejected';
- value: string;
- };
- campaign?: {
- id: number;
- /** @description CustomerTitle ?? Title */
- title: string;
- startDate: string;
- };
- workspace_id: number;
- };
- };
- };
- };
- };
- 'delete-workspaces-wid-plans-pid': {
- parameters: {
- path: {
- pid: string;
- };
- };
- responses: {
- /** OK */
- 200: unknown;
- };
- };
- 'patch-workspaces-wid-plans-pid': {
- parameters: {
- path: {
- pid: string;
- };
- };
- responses: {
- /** OK */
- 200: unknown;
- /** Forbidden */
- 403: unknown;
- /** Not Found */
- 404: unknown;
- };
- requestBody: {
- content: {
- 'application/json': {
- config: {
- modules: components['schemas']['Module'][];
+ items?: components['schemas']['Project'][];
+ limit?: number;
+ size?: number;
+ start?: number;
+ total?: number;
};
};
};
+ 400: components['responses']['Error'];
+ 403: components['responses']['Error'];
+ 404: components['responses']['Error'];
+ 500: components['responses']['Error'];
};
};
- /** */
- 'patch-workspaces-wid-plans-pid-status': {
+ 'get-workspace-project': {
parameters: {
path: {
- pid: string;
+ /** Workspace (company, customer) id */
+ wid: components['parameters']['wid'];
+ /** Project id */
+ pid: components['parameters']['pid'];
};
};
responses: {
/** OK */
200: {
content: {
- 'application/json': { [key: string]: unknown };
- };
- };
- };
- requestBody: {
- content: {
- 'application/json': {
- status: components['schemas']['PlanStatus'];
+ 'application/json': components['schemas']['Project'];
};
};
+ 400: components['responses']['Error'];
+ 403: components['responses']['Error'];
+ 404: components['responses']['Error'];
+ 500: components['responses']['Error'];
};
};
- 'get-workspace-projects': {
+ 'get-workspace-project-campaigns': {
parameters: {
path: {
/** Workspace (company, customer) id */
wid: components['parameters']['wid'];
+ /** Project id */
+ pid: components['parameters']['pid'];
};
query: {
/** Limit pagination parameter */
@@ -3939,10 +4027,10 @@ export interface operations {
200: {
content: {
'application/json': {
- items?: components['schemas']['Project'][];
- start?: number;
+ items?: components['schemas']['CampaignWithOutput'][];
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -3999,13 +4087,13 @@ export interface operations {
200: {
content: {
'application/json': {
+ config: string;
+ description?: string;
id: number;
name: string;
- description?: string;
- config: string;
- workspace_id?: number;
price?: string;
strapi?: components['schemas']['StrapiTemplate'];
+ workspace_id?: number;
};
};
};
@@ -4033,62 +4121,6 @@ export interface operations {
404: unknown;
};
};
- 'get-workspace-project': {
- parameters: {
- path: {
- /** Workspace (company, customer) id */
- wid: components['parameters']['wid'];
- /** Project id */
- pid: components['parameters']['pid'];
- };
- };
- responses: {
- /** OK */
- 200: {
- content: {
- 'application/json': components['schemas']['Project'];
- };
- };
- 400: components['responses']['Error'];
- 403: components['responses']['Error'];
- 404: components['responses']['Error'];
- 500: components['responses']['Error'];
- };
- };
- 'get-workspace-project-campaigns': {
- parameters: {
- path: {
- /** Workspace (company, customer) id */
- wid: components['parameters']['wid'];
- /** Project id */
- pid: components['parameters']['pid'];
- };
- query: {
- /** Limit pagination parameter */
- limit?: components['parameters']['limit'];
- /** Start pagination parameter */
- start?: components['parameters']['start'];
- };
- };
- responses: {
- /** OK */
- 200: {
- content: {
- 'application/json': {
- items?: components['schemas']['CampaignWithOutput'][];
- start?: number;
- limit?: number;
- size?: number;
- total?: number;
- };
- };
- };
- 400: components['responses']['Error'];
- 403: components['responses']['Error'];
- 404: components['responses']['Error'];
- 500: components['responses']['Error'];
- };
- };
/** Return a list of users from a specific workspace */
'get-workspaces-users': {
parameters: {
@@ -4113,9 +4145,9 @@ export interface operations {
content: {
'application/json': {
items: components['schemas']['Tenant'][];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
};
@@ -4138,9 +4170,9 @@ export interface operations {
200: {
content: {
'application/json': {
+ email: string;
profile_id: number;
tryber_wp_user_id: number;
- email: string;
};
};
};
@@ -4174,9 +4206,9 @@ export interface operations {
requestBody: {
content: {
'application/json': {
+ include_shared?: boolean;
/** @description Tryber WP USER ID */
user_id: number;
- include_shared?: boolean;
};
};
};
diff --git a/src/features/api/api.ts b/src/features/api/api.ts
index a8050af93..0f2071819 100644
--- a/src/features/api/api.ts
+++ b/src/features/api/api.ts
@@ -1,6 +1,5 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { stringify } from 'qs';
-import { Template } from '.';
export const apiSlice = createApi({
reducerPath: 'api',
@@ -39,7 +38,3 @@ export const apiSlice = createApi({
],
endpoints: () => ({}),
});
-
-export interface UseCaseTemplate extends Template {
- id?: number;
-}
diff --git a/src/features/api/apiTags.ts b/src/features/api/apiTags.ts
index 578b553c5..fc7e2e19c 100644
--- a/src/features/api/apiTags.ts
+++ b/src/features/api/apiTags.ts
@@ -29,9 +29,6 @@ unguessApi.enhanceEndpoints({
patchProjectsByPid: {
invalidatesTags: ['Projects'],
},
- postCampaigns: {
- invalidatesTags: ['Campaigns'],
- },
patchCampaignsByCid: {
invalidatesTags: ['Campaigns', 'Projects', 'Archive', 'Users'],
},
@@ -53,9 +50,6 @@ unguessApi.enhanceEndpoints({
getWorkspacesByWidCoins: {
providesTags: ['Workspaces'],
},
- getTemplates: {
- providesTags: ['Templates'],
- },
getCampaignsByCidReports: {
providesTags: ['Reports'],
},
diff --git a/src/features/api/index.ts b/src/features/api/index.ts
index a95c87b53..e38021afb 100644
--- a/src/features/api/index.ts
+++ b/src/features/api/index.ts
@@ -4,16 +4,6 @@ const injectedRtkApi = api.injectEndpoints({
$get: build.query<$getApiResponse, $getApiArg>({
query: () => ({ url: `/` }),
}),
- postAuthenticate: build.mutation<
- PostAuthenticateApiResponse,
- PostAuthenticateApiArg
- >({
- query: (queryArg) => ({
- url: `/authenticate`,
- method: 'POST',
- body: queryArg.body,
- }),
- }),
postAnalyticsViewsCampaignsByCid: build.mutation<
PostAnalyticsViewsCampaignsByCidApiResponse,
PostAnalyticsViewsCampaignsByCidApiArg
@@ -23,16 +13,22 @@ const injectedRtkApi = api.injectEndpoints({
method: 'POST',
}),
}),
- postCampaigns: build.mutation<
- PostCampaignsApiResponse,
- PostCampaignsApiArg
+ postAuthenticate: build.mutation<
+ PostAuthenticateApiResponse,
+ PostAuthenticateApiArg
>({
query: (queryArg) => ({
- url: `/campaigns`,
+ url: `/authenticate`,
method: 'POST',
body: queryArg.body,
}),
}),
+ getCampaignsByCid: build.query<
+ GetCampaignsByCidApiResponse,
+ GetCampaignsByCidApiArg
+ >({
+ query: (queryArg) => ({ url: `/campaigns/${queryArg.cid}` }),
+ }),
patchCampaignsByCid: build.mutation<
PatchCampaignsByCidApiResponse,
PatchCampaignsByCidApiArg
@@ -43,12 +39,6 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- getCampaignsByCid: build.query<
- GetCampaignsByCidApiResponse,
- GetCampaignsByCidApiArg
- >({
- query: (queryArg) => ({ url: `/campaigns/${queryArg.cid}` }),
- }),
getCampaignsByCidBugTypes: build.query<
GetCampaignsByCidBugTypesApiResponse,
GetCampaignsByCidBugTypesApiArg
@@ -107,13 +97,13 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- postCampaignsByCidBugsAndBidMedia: build.mutation<
- PostCampaignsByCidBugsAndBidMediaApiResponse,
- PostCampaignsByCidBugsAndBidMediaApiArg
+ deleteCampaignsByCidBugsAndBidCommentsCmid: build.mutation<
+ DeleteCampaignsByCidBugsAndBidCommentsCmidApiResponse,
+ DeleteCampaignsByCidBugsAndBidCommentsCmidApiArg
>({
query: (queryArg) => ({
- url: `/campaigns/${queryArg.cid}/bugs/${queryArg.bid}/media`,
- method: 'POST',
+ url: `/campaigns/${queryArg.cid}/bugs/${queryArg.bid}/comments/${queryArg.cmid}`,
+ method: 'DELETE',
body: queryArg.body,
}),
}),
@@ -127,13 +117,13 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- deleteCampaignsByCidBugsAndBidCommentsCmid: build.mutation<
- DeleteCampaignsByCidBugsAndBidCommentsCmidApiResponse,
- DeleteCampaignsByCidBugsAndBidCommentsCmidApiArg
+ postCampaignsByCidBugsAndBidMedia: build.mutation<
+ PostCampaignsByCidBugsAndBidMediaApiResponse,
+ PostCampaignsByCidBugsAndBidMediaApiArg
>({
query: (queryArg) => ({
- url: `/campaigns/${queryArg.cid}/bugs/${queryArg.bid}/comments/${queryArg.cmid}`,
- method: 'DELETE',
+ url: `/campaigns/${queryArg.cid}/bugs/${queryArg.bid}/media`,
+ method: 'POST',
body: queryArg.body,
}),
}),
@@ -151,6 +141,16 @@ const injectedRtkApi = api.injectEndpoints({
>({
query: (queryArg) => ({ url: `/campaigns/${queryArg.cid}/clusters` }),
}),
+ deleteCampaignsByCidCustomStatuses: build.mutation<
+ DeleteCampaignsByCidCustomStatusesApiResponse,
+ DeleteCampaignsByCidCustomStatusesApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/campaigns/${queryArg.cid}/custom_statuses`,
+ method: 'DELETE',
+ body: queryArg.body,
+ }),
+ }),
getCampaignsByCidCustomStatuses: build.query<
GetCampaignsByCidCustomStatusesApiResponse,
GetCampaignsByCidCustomStatusesApiArg
@@ -169,16 +169,6 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- deleteCampaignsByCidCustomStatuses: build.mutation<
- DeleteCampaignsByCidCustomStatusesApiResponse,
- DeleteCampaignsByCidCustomStatusesApiArg
- >({
- query: (queryArg) => ({
- url: `/campaigns/${queryArg.cid}/custom_statuses`,
- method: 'DELETE',
- body: queryArg.body,
- }),
- }),
getCampaignsByCidDevices: build.query<
GetCampaignsByCidDevicesApiResponse,
GetCampaignsByCidDevicesApiArg
@@ -195,6 +185,12 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
+ getCampaignsByCidInsights: build.query<
+ GetCampaignsByCidInsightsApiResponse,
+ GetCampaignsByCidInsightsApiArg
+ >({
+ query: (queryArg) => ({ url: `/campaigns/${queryArg.cid}/insights` }),
+ }),
postCampaignsByCidInsights: build.mutation<
PostCampaignsByCidInsightsApiResponse,
PostCampaignsByCidInsightsApiArg
@@ -205,12 +201,6 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- getCampaignsByCidInsights: build.query<
- GetCampaignsByCidInsightsApiResponse,
- GetCampaignsByCidInsightsApiArg
- >({
- query: (queryArg) => ({ url: `/campaigns/${queryArg.cid}/insights` }),
- }),
getCampaignsByCidMeta: build.query<
GetCampaignsByCidMetaApiResponse,
GetCampaignsByCidMetaApiArg
@@ -289,6 +279,16 @@ const injectedRtkApi = api.injectEndpoints({
params: { filterBy: queryArg.filterBy },
}),
}),
+ deleteCampaignsByCidUsers: build.mutation<
+ DeleteCampaignsByCidUsersApiResponse,
+ DeleteCampaignsByCidUsersApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/campaigns/${queryArg.cid}/users`,
+ method: 'DELETE',
+ body: queryArg.body,
+ }),
+ }),
getCampaignsByCidUsers: build.query<
GetCampaignsByCidUsersApiResponse,
GetCampaignsByCidUsersApiArg
@@ -313,16 +313,6 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- deleteCampaignsByCidUsers: build.mutation<
- DeleteCampaignsByCidUsersApiResponse,
- DeleteCampaignsByCidUsersApiArg
- >({
- query: (queryArg) => ({
- url: `/campaigns/${queryArg.cid}/users`,
- method: 'DELETE',
- body: queryArg.body,
- }),
- }),
getCampaignsByCidUx: build.query<
GetCampaignsByCidUxApiResponse,
GetCampaignsByCidUxApiArg
@@ -375,12 +365,6 @@ const injectedRtkApi = api.injectEndpoints({
params: { s: queryArg.s, updateTrend: queryArg.updateTrend },
}),
}),
- getInsightsByIid: build.query<
- GetInsightsByIidApiResponse,
- GetInsightsByIidApiArg
- >({
- query: (queryArg) => ({ url: `/insights/${queryArg.iid}` }),
- }),
deleteInsightsByIid: build.mutation<
DeleteInsightsByIidApiResponse,
DeleteInsightsByIidApiArg
@@ -390,6 +374,12 @@ const injectedRtkApi = api.injectEndpoints({
method: 'DELETE',
}),
}),
+ getInsightsByIid: build.query<
+ GetInsightsByIidApiResponse,
+ GetInsightsByIidApiArg
+ >({
+ query: (queryArg) => ({ url: `/insights/${queryArg.iid}` }),
+ }),
patchInsightsByIid: build.mutation<
PatchInsightsByIidApiResponse,
PatchInsightsByIidApiArg
@@ -400,8 +390,13 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- getMediaById: build.query({
- query: (queryArg) => ({ url: `/media/${queryArg.id}` }),
+ getInvitesByProfileAndToken: build.query<
+ GetInvitesByProfileAndTokenApiResponse,
+ GetInvitesByProfileAndTokenApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/invites/${queryArg.profile}/${queryArg.token}`,
+ }),
}),
deleteMediaCommentByMcid: build.mutation<
DeleteMediaCommentByMcidApiResponse,
@@ -412,6 +407,41 @@ const injectedRtkApi = api.injectEndpoints({
method: 'DELETE',
}),
}),
+ getMediaById: build.query({
+ query: (queryArg) => ({ url: `/media/${queryArg.id}` }),
+ }),
+ deletePlansByPid: build.mutation<
+ DeletePlansByPidApiResponse,
+ DeletePlansByPidApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/plans/${queryArg.pid}`,
+ method: 'DELETE',
+ }),
+ }),
+ getPlansByPid: build.query({
+ query: (queryArg) => ({ url: `/plans/${queryArg.pid}` }),
+ }),
+ patchPlansByPid: build.mutation<
+ PatchPlansByPidApiResponse,
+ PatchPlansByPidApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/plans/${queryArg.pid}`,
+ method: 'PATCH',
+ body: queryArg.body,
+ }),
+ }),
+ patchPlansByPidStatus: build.mutation<
+ PatchPlansByPidStatusApiResponse,
+ PatchPlansByPidStatusApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/plans/${queryArg.pid}/status`,
+ method: 'PATCH',
+ body: queryArg.body,
+ }),
+ }),
postProjects: build.mutation({
query: (queryArg) => ({
url: `/projects`,
@@ -419,6 +449,15 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
+ deleteProjectsByPid: build.mutation<
+ DeleteProjectsByPidApiResponse,
+ DeleteProjectsByPidApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/projects/${queryArg.pid}`,
+ method: 'DELETE',
+ }),
+ }),
getProjectsByPid: build.query<
GetProjectsByPidApiResponse,
GetProjectsByPidApiArg
@@ -435,15 +474,6 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- deleteProjectsByPid: build.mutation<
- DeleteProjectsByPidApiResponse,
- DeleteProjectsByPidApiArg
- >({
- query: (queryArg) => ({
- url: `/projects/${queryArg.pid}`,
- method: 'DELETE',
- }),
- }),
getProjectsByPidCampaigns: build.query<
GetProjectsByPidCampaignsApiResponse,
GetProjectsByPidCampaignsApiArg
@@ -458,6 +488,16 @@ const injectedRtkApi = api.injectEndpoints({
},
}),
}),
+ deleteProjectsByPidUsers: build.mutation<
+ DeleteProjectsByPidUsersApiResponse,
+ DeleteProjectsByPidUsersApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/projects/${queryArg.pid}/users`,
+ method: 'DELETE',
+ body: queryArg.body,
+ }),
+ }),
getProjectsByPidUsers: build.query<
GetProjectsByPidUsersApiResponse,
GetProjectsByPidUsersApiArg
@@ -482,24 +522,20 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- deleteProjectsByPidUsers: build.mutation<
- DeleteProjectsByPidUsersApiResponse,
- DeleteProjectsByPidUsersApiArg
- >({
+ postUsers: build.mutation({
query: (queryArg) => ({
- url: `/projects/${queryArg.pid}/users`,
- method: 'DELETE',
+ url: `/users`,
+ method: 'POST',
body: queryArg.body,
}),
}),
- getTemplates: build.query({
+ headUsersByEmailByEmail: build.mutation<
+ HeadUsersByEmailByEmailApiResponse,
+ HeadUsersByEmailByEmailApiArg
+ >({
query: (queryArg) => ({
- url: `/templates`,
- params: {
- filterBy: queryArg.filterBy,
- order: queryArg.order,
- orderBy: queryArg.orderBy,
- },
+ url: `/users/by-email/${queryArg.email}`,
+ method: 'HEAD',
}),
}),
getUsersMe: build.query({
@@ -521,6 +557,9 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
+ getUsersRoles: build.query({
+ query: () => ({ url: `/users/roles` }),
+ }),
getVideosByVid: build.query<
GetVideosByVidApiResponse,
GetVideosByVidApiArg
@@ -543,23 +582,23 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- patchVideosByVidObservationsAndOid: build.mutation<
- PatchVideosByVidObservationsAndOidApiResponse,
- PatchVideosByVidObservationsAndOidApiArg
+ deleteVideosByVidObservationsAndOid: build.mutation<
+ DeleteVideosByVidObservationsAndOidApiResponse,
+ DeleteVideosByVidObservationsAndOidApiArg
>({
query: (queryArg) => ({
url: `/videos/${queryArg.vid}/observations/${queryArg.oid}`,
- method: 'PATCH',
- body: queryArg.body,
+ method: 'DELETE',
}),
}),
- deleteVideosByVidObservationsAndOid: build.mutation<
- DeleteVideosByVidObservationsAndOidApiResponse,
- DeleteVideosByVidObservationsAndOidApiArg
+ patchVideosByVidObservationsAndOid: build.mutation<
+ PatchVideosByVidObservationsAndOidApiResponse,
+ PatchVideosByVidObservationsAndOidApiArg
>({
query: (queryArg) => ({
url: `/videos/${queryArg.vid}/observations/${queryArg.oid}`,
- method: 'DELETE',
+ method: 'PATCH',
+ body: queryArg.body,
}),
}),
getVideosByVidTranslation: build.query<
@@ -643,16 +682,6 @@ const injectedRtkApi = api.injectEndpoints({
},
}),
}),
- postWorkspacesByWidPlans: build.mutation<
- PostWorkspacesByWidPlansApiResponse,
- PostWorkspacesByWidPlansApiArg
- >({
- query: (queryArg) => ({
- url: `/workspaces/${queryArg.wid}/plans`,
- method: 'POST',
- body: queryArg.body,
- }),
- }),
getWorkspacesByWidPlans: build.query<
GetWorkspacesByWidPlansApiResponse,
GetWorkspacesByWidPlansApiArg
@@ -667,35 +696,13 @@ const injectedRtkApi = api.injectEndpoints({
},
}),
}),
- deletePlansByPid: build.mutation<
- DeletePlansByPidApiResponse,
- DeletePlansByPidApiArg
- >({
- query: (queryArg) => ({
- url: `/plans/${queryArg.pid}`,
- method: 'DELETE',
- }),
- }),
- getPlansByPid: build.query({
- query: (queryArg) => ({ url: `/plans/${queryArg.pid}` }),
- }),
- patchPlansByPid: build.mutation<
- PatchPlansByPidApiResponse,
- PatchPlansByPidApiArg
- >({
- query: (queryArg) => ({
- url: `/plans/${queryArg.pid}`,
- method: 'PATCH',
- body: queryArg.body,
- }),
- }),
- patchPlansByPidStatus: build.mutation<
- PatchPlansByPidStatusApiResponse,
- PatchPlansByPidStatusApiArg
+ postWorkspacesByWidPlans: build.mutation<
+ PostWorkspacesByWidPlansApiResponse,
+ PostWorkspacesByWidPlansApiArg
>({
query: (queryArg) => ({
- url: `/plans/${queryArg.pid}/status`,
- method: 'PATCH',
+ url: `/workspaces/${queryArg.wid}/plans`,
+ method: 'POST',
body: queryArg.body,
}),
}),
@@ -708,10 +715,27 @@ const injectedRtkApi = api.injectEndpoints({
params: { limit: queryArg.limit, start: queryArg.start },
}),
}),
- getWorkspacesByWidTemplates: build.query<
- GetWorkspacesByWidTemplatesApiResponse,
- GetWorkspacesByWidTemplatesApiArg
- >({
+ getWorkspacesByWidProjectsAndPid: build.query<
+ GetWorkspacesByWidProjectsAndPidApiResponse,
+ GetWorkspacesByWidProjectsAndPidApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/workspaces/${queryArg.wid}/projects/${queryArg.pid}`,
+ }),
+ }),
+ getWorkspacesByWidProjectsAndPidCampaigns: build.query<
+ GetWorkspacesByWidProjectsAndPidCampaignsApiResponse,
+ GetWorkspacesByWidProjectsAndPidCampaignsApiArg
+ >({
+ query: (queryArg) => ({
+ url: `/workspaces/${queryArg.wid}/projects/${queryArg.pid}/campaigns`,
+ params: { limit: queryArg.limit, start: queryArg.start },
+ }),
+ }),
+ getWorkspacesByWidTemplates: build.query<
+ GetWorkspacesByWidTemplatesApiResponse,
+ GetWorkspacesByWidTemplatesApiArg
+ >({
query: (queryArg) => ({
url: `/workspaces/${queryArg.wid}/templates`,
params: {
@@ -740,21 +764,14 @@ const injectedRtkApi = api.injectEndpoints({
url: `/workspaces/${queryArg.wid}/templates/${queryArg.tid}`,
}),
}),
- getWorkspacesByWidProjectsAndPid: build.query<
- GetWorkspacesByWidProjectsAndPidApiResponse,
- GetWorkspacesByWidProjectsAndPidApiArg
- >({
- query: (queryArg) => ({
- url: `/workspaces/${queryArg.wid}/projects/${queryArg.pid}`,
- }),
- }),
- getWorkspacesByWidProjectsAndPidCampaigns: build.query<
- GetWorkspacesByWidProjectsAndPidCampaignsApiResponse,
- GetWorkspacesByWidProjectsAndPidCampaignsApiArg
+ deleteWorkspacesByWidUsers: build.mutation<
+ DeleteWorkspacesByWidUsersApiResponse,
+ DeleteWorkspacesByWidUsersApiArg
>({
query: (queryArg) => ({
- url: `/workspaces/${queryArg.wid}/projects/${queryArg.pid}/campaigns`,
- params: { limit: queryArg.limit, start: queryArg.start },
+ url: `/workspaces/${queryArg.wid}/users`,
+ method: 'DELETE',
+ body: queryArg.body,
}),
}),
getWorkspacesByWidUsers: build.query<
@@ -781,29 +798,12 @@ const injectedRtkApi = api.injectEndpoints({
body: queryArg.body,
}),
}),
- deleteWorkspacesByWidUsers: build.mutation<
- DeleteWorkspacesByWidUsersApiResponse,
- DeleteWorkspacesByWidUsersApiArg
- >({
- query: (queryArg) => ({
- url: `/workspaces/${queryArg.wid}/users`,
- method: 'DELETE',
- body: queryArg.body,
- }),
- }),
}),
overrideExisting: false,
});
export { injectedRtkApi as unguessApi };
export type $getApiResponse = /** status 200 OK */ {};
export type $getApiArg = void;
-export type PostAuthenticateApiResponse = /** status 200 OK */ Authentication;
-export type PostAuthenticateApiArg = {
- body: {
- username: string;
- password: string;
- };
-};
export type PostAnalyticsViewsCampaignsByCidApiResponse = /** status 200 OK */ {
success?: boolean;
};
@@ -811,51 +811,11 @@ export type PostAnalyticsViewsCampaignsByCidApiArg = {
/** Campaign id */
cid: string;
};
-export type PostCampaignsApiResponse = /** status 200 OK */ Campaign;
-export type PostCampaignsApiArg = {
- body: {
- title: string;
- start_date: string;
- end_date: string;
- close_date: string;
- customer_title?: string;
- status_id?: number;
- is_public?: number;
- campaign_type_id: number;
- project_id: number;
- pm_id: number;
- platforms: PlatformObject[];
- /** Da togliere */
- page_preview_id?: number;
- /** Da togliere */
- page_manual_id?: number;
- /** Used to check available coins */
- customer_id: number;
- has_bug_form?: number;
- /** if has_bug_form is 0 this has to be 0 */
- has_bug_parade?: number;
- description?: string;
- base_bug_internal_id?: string;
- express_slug: string;
- use_cases?: UseCase[];
- productType?: number;
- productLink?: string;
- browsers?: number[];
- languages?: string[];
- outOfScope?: string;
- testerRequirements?: string;
- targetSize?: number;
- goal?: string;
- testDescription?: string;
- };
-};
-export type PatchCampaignsByCidApiResponse = /** status 200 OK */ Campaign;
-export type PatchCampaignsByCidApiArg = {
- /** Campaign id */
- cid: string;
+export type PostAuthenticateApiResponse = /** status 200 OK */ Authentication;
+export type PostAuthenticateApiArg = {
body: {
- customer_title?: string;
- project_id?: number;
+ password: string;
+ username: string;
};
};
export type GetCampaignsByCidApiResponse =
@@ -867,6 +827,15 @@ export type GetCampaignsByCidApiArg = {
/** Campaign id */
cid: string;
};
+export type PatchCampaignsByCidApiResponse = /** status 200 OK */ Campaign;
+export type PatchCampaignsByCidApiArg = {
+ /** Campaign id */
+ cid: string;
+ body: {
+ customer_title?: string;
+ project_id?: number;
+ };
+};
export type GetCampaignsByCidBugTypesApiResponse =
/** status 200 OK */ BugType[];
export type GetCampaignsByCidBugTypesApiArg = {
@@ -875,21 +844,21 @@ export type GetCampaignsByCidBugTypesApiArg = {
};
export type GetCampaignsByCidBugsApiResponse = /** status 200 OK */ {
items?: (Bug & {
- tags?: {
- tag_id: number;
- tag_name: string;
- }[];
- siblings: number;
- comments: number;
additional_fields?: {
+ name: string;
slug: string;
value: string;
- name: string;
+ }[];
+ comments: number;
+ siblings: number;
+ tags?: {
+ tag_id: number;
+ tag_name: string;
}[];
})[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetCampaignsByCidBugsApiArg = {
@@ -910,13 +879,13 @@ export type GetCampaignsByCidBugsApiArg = {
};
export type GetCampaignsByCidBugsAndBidApiResponse =
/** status 200 OK */ Bug & {
- media: BugMedia[];
- tags: BugTag[];
additional_fields: BugAdditionalField[];
+ media: BugMedia[];
reporter: {
- tester_id: number;
name: string;
+ tester_id: number;
};
+ tags: BugTag[];
};
export type GetCampaignsByCidBugsAndBidApiArg = {
/** Campaign id */
@@ -925,12 +894,12 @@ export type GetCampaignsByCidBugsAndBidApiArg = {
bid: string;
};
export type PatchCampaignsByCidBugsAndBidApiResponse = /** status 200 OK */ {
+ custom_status?: BugCustomStatus;
+ priority?: BugPriority;
tags?: {
tag_id: number;
tag_name: string;
}[];
- priority?: BugPriority;
- custom_status?: BugCustomStatus;
};
export type PatchCampaignsByCidBugsAndBidApiArg = {
/** Campaign id */
@@ -938,6 +907,8 @@ export type PatchCampaignsByCidBugsAndBidApiArg = {
/** Defines an identifier for the bug object (BUG ID) */
bid: string;
body: {
+ custom_status_id?: number;
+ priority_id?: number;
tags?: (
| {
tag_id: number;
@@ -946,8 +917,6 @@ export type PatchCampaignsByCidBugsAndBidApiArg = {
tag_name: string;
}
)[];
- priority_id?: number;
- custom_status_id?: number;
};
};
export type GetCampaignsByCidBugsAndBidCommentsApiResponse =
@@ -968,93 +937,93 @@ export type PostCampaignsByCidBugsAndBidCommentsApiArg = {
/** Defines an identifier for the bug object (BUG ID) */
bid: string;
body: {
- text: string;
- mentioned?: {
+ media_id?: {
id: number;
}[];
- media_id?: {
+ mentioned?: {
id: number;
}[];
+ text: string;
};
};
-export type PostCampaignsByCidBugsAndBidMediaApiResponse =
+export type DeleteCampaignsByCidBugsAndBidCommentsCmidApiResponse =
+ /** status 200 OK */ string;
+export type DeleteCampaignsByCidBugsAndBidCommentsCmidApiArg = {
+ cid: string;
+ bid: string;
+ cmid: string;
+ body: {};
+};
+export type PostCampaignsByCidBugsAndBidCommentsCmidApiResponse =
/** status 200 OK */ {
failed?: {
- name: string;
errorCode: 'FILE_TOO_BIG' | 'INVALID_FILE_EXTENSION' | 'GENERIC_ERROR';
+ name: string;
+ }[];
+ files?: {
+ name: string;
+ path: string;
}[];
uploaded_ids?: {
id: number;
}[];
};
-export type PostCampaignsByCidBugsAndBidMediaApiArg = {
- /** Campaign id */
+export type PostCampaignsByCidBugsAndBidCommentsCmidApiArg = {
cid: string;
- /** Defines an identifier for the bug object (BUG ID) */
bid: string;
+ cmid: string;
body: {
media: string | string[];
};
};
-export type PostCampaignsByCidBugsAndBidCommentsCmidApiResponse =
+export type PostCampaignsByCidBugsAndBidMediaApiResponse =
/** status 200 OK */ {
- files?: {
- name: string;
- path: string;
- }[];
failed?: {
- name: string;
errorCode: 'FILE_TOO_BIG' | 'INVALID_FILE_EXTENSION' | 'GENERIC_ERROR';
+ name: string;
}[];
uploaded_ids?: {
id: number;
}[];
};
-export type PostCampaignsByCidBugsAndBidCommentsCmidApiArg = {
+export type PostCampaignsByCidBugsAndBidMediaApiArg = {
+ /** Campaign id */
cid: string;
+ /** Defines an identifier for the bug object (BUG ID) */
bid: string;
- cmid: string;
body: {
media: string | string[];
};
};
-export type DeleteCampaignsByCidBugsAndBidCommentsCmidApiResponse =
- /** status 200 OK */ string;
-export type DeleteCampaignsByCidBugsAndBidCommentsCmidApiArg = {
- cid: string;
- bid: string;
- cmid: string;
- body: {};
-};
export type GetCampaignsByCidBugsAndBidSiblingsApiResponse =
/** status 200 OK */ {
father?: {
- id: number;
- title: {
- full: string;
- compact: string;
- context?: string[];
- };
context?: string;
device: string;
+ id: number;
os: {
name: string;
version: string;
};
- };
- siblings: {
- id: number;
title: {
- full: string;
compact: string;
context?: string[];
+ full: string;
};
+ };
+ siblings: {
context?: string;
device: string;
+ id: number;
os: {
name: string;
version: string;
};
+ title: {
+ compact: string;
+ context?: string[];
+ full: string;
+ };
}[];
};
export type GetCampaignsByCidBugsAndBidSiblingsApiArg = {
@@ -1069,6 +1038,18 @@ export type GetCampaignsByCidClustersApiResponse = /** status 200 OK */ {
export type GetCampaignsByCidClustersApiArg = {
cid: string;
};
+export type DeleteCampaignsByCidCustomStatusesApiResponse =
+ /** status 200 OK */ {
+ status?: boolean;
+ };
+export type DeleteCampaignsByCidCustomStatusesApiArg = {
+ /** Campaign id */
+ cid: string;
+ body: {
+ custom_status_id: number;
+ to_custom_status_id?: number;
+ }[];
+};
export type GetCampaignsByCidCustomStatusesApiResponse =
/** status 200 OK */ BugCustomStatus[];
export type GetCampaignsByCidCustomStatusesApiArg = {
@@ -1081,22 +1062,10 @@ export type PatchCampaignsByCidCustomStatusesApiArg = {
/** Campaign id */
cid: string;
body: {
+ color: string;
/** se esiste già questo parametro viene passato nel request body\r\nse invece non esiste ed il custom status deve essere creato, non viene passato */
custom_status_id?: number;
name: string;
- color: string;
- }[];
-};
-export type DeleteCampaignsByCidCustomStatusesApiResponse =
- /** status 200 OK */ {
- status?: boolean;
- };
-export type DeleteCampaignsByCidCustomStatusesApiArg = {
- /** Campaign id */
- cid: string;
- body: {
- custom_status_id: number;
- to_custom_status_id?: number;
}[];
};
export type GetCampaignsByCidDevicesApiResponse = /** status 200 OK */ {
@@ -1116,20 +1085,6 @@ export type PutCampaignsByCidFindingsAndFidApiArg = {
comment: string;
};
};
-export type PostCampaignsByCidInsightsApiResponse =
- /** status 200 OK */ Insight;
-export type PostCampaignsByCidInsightsApiArg = {
- /** Campaign id */
- cid: string;
- body: {
- title: string;
- description?: string;
- severity_id: number;
- observations_ids: number[];
- comment?: string;
- visible?: number;
- };
-};
export type GetCampaignsByCidInsightsApiResponse =
/** status 200 OK */ (Insight & {
usecases: {
@@ -1141,10 +1096,24 @@ export type GetCampaignsByCidInsightsApiArg = {
/** Campaign id */
cid: string;
};
+export type PostCampaignsByCidInsightsApiResponse =
+ /** status 200 OK */ Insight;
+export type PostCampaignsByCidInsightsApiArg = {
+ /** Campaign id */
+ cid: string;
+ body: {
+ comment?: string;
+ description?: string;
+ observations_ids: number[];
+ severity_id: number;
+ title: string;
+ visible?: number;
+ };
+};
export type GetCampaignsByCidMetaApiResponse = /** status 200 OK */ Campaign & {
- selected_testers: number;
/** Array of form factors */
allowed_devices: string[];
+ selected_testers: number;
};
export type GetCampaignsByCidMetaApiArg = {
/** Campaign id */
@@ -1153,27 +1122,27 @@ export type GetCampaignsByCidMetaApiArg = {
export type GetCampaignsByCidObservationsApiResponse =
/** status 200 OK */
| {
+ kind: 'usecase-grapes';
results: {
- usecaseId: number;
- usecaseTitle: string;
grapes: Grape[];
ungrouped: (Observation & {
- uploaderId: number;
- mediaId: number;
deviceType: string;
+ mediaId: number;
+ uploaderId: number;
usecaseTitle: string;
})[];
+ usecaseId: number;
+ usecaseTitle: string;
}[];
- kind: 'usecase-grapes';
}
| {
+ kind: 'ungrouped';
results: (Observation & {
- uploaderId: number;
- mediaId: number;
deviceType: string;
+ mediaId: number;
+ uploaderId: number;
usecaseTitle: string;
})[];
- kind: 'ungrouped';
};
export type GetCampaignsByCidObservationsApiArg = {
cid: string;
@@ -1211,9 +1180,9 @@ export type GetCampaignsByCidSeveritiesApiArg = {
};
export type GetCampaignsByCidSuggestionsApiResponse = /** status 200 OK */ {
suggestion?: {
- slug: BannerType;
/** ServiceId from strapi */
serviceId?: number;
+ slug: BannerType;
};
};
export type GetCampaignsByCidSuggestionsApiArg = {
@@ -1229,24 +1198,25 @@ export type PostCampaignsByCidSuggestionsApiArg = {
};
};
export type GetCampaignsByCidTagsApiResponse = /** status 200 OK */ {
- tag_id: number;
display_name: string;
- slug: string;
is_public?: number;
+ slug: string;
+ tag_id: number;
}[];
export type GetCampaignsByCidTagsApiArg = {
/** Campaign id */
cid: string;
};
export type GetCampaignsByCidUsecasesApiResponse = /** status 200 OK */ {
+ completion: number;
+ content?: string;
id: number;
title: {
full: string;
- simple?: string;
- prefix?: string;
info?: string;
+ prefix?: string;
+ simple?: string;
};
- completion: number;
}[];
export type GetCampaignsByCidUsecasesApiArg = {
/** Campaign id */
@@ -1254,11 +1224,22 @@ export type GetCampaignsByCidUsecasesApiArg = {
/** bugs, videos */
filterBy?: string;
};
+export type DeleteCampaignsByCidUsersApiResponse = /** status 200 OK */ {
+ items: Tenant[];
+};
+export type DeleteCampaignsByCidUsersApiArg = {
+ /** Campaign id */
+ cid: string;
+ body: {
+ /** Tryber WP USER ID */
+ user_id: number;
+ };
+};
export type GetCampaignsByCidUsersApiResponse = /** status 200 OK */ {
items: Tenant[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetCampaignsByCidUsersApiArg = {
@@ -1274,78 +1255,67 @@ export type GetCampaignsByCidUsersApiArg = {
orderBy?: string;
};
export type PostCampaignsByCidUsersApiResponse = /** status 200 OK */ {
+ email: string;
profile_id: number;
tryber_wp_user_id: number;
- email: string;
};
export type PostCampaignsByCidUsersApiArg = {
/** Campaign id */
cid: string;
body: {
email: string;
- name?: string;
- surname?: string;
- locale?: string;
event_name?: string;
- redirect_url?: string;
+ locale?: string;
message?: string;
- };
-};
-export type DeleteCampaignsByCidUsersApiResponse = /** status 200 OK */ {
- items: Tenant[];
-};
-export type DeleteCampaignsByCidUsersApiArg = {
- /** Campaign id */
- cid: string;
- body: {
- /** Tryber WP USER ID */
- user_id: number;
+ name?: string;
+ redirect_url?: string;
+ surname?: string;
};
};
export type GetCampaignsByCidUxApiResponse = /** status 200 OK */ {
- goal?: string;
- users?: number;
findings?: {
+ cluster:
+ | {
+ id: number;
+ name: string;
+ }[]
+ | 'all';
+ comment?: string;
+ description: string;
/** this field is the Finding ID */
id: number;
- title: string;
- description: string;
- comment?: string;
severity: {
id: number;
name: string;
style: string;
};
- cluster:
- | {
- id: number;
- name: string;
- }[]
- | 'all';
+ title: string;
video?: {
- url: string;
- streamUrl: string;
+ description?: string;
+ end: number;
poster?: string;
start: number;
- end: number;
- description?: string;
+ streamUrl: string;
+ url: string;
}[];
}[];
+ goal?: string;
+ methodology?: {
+ description: string;
+ type: string;
+ };
+ questions?: {
+ text: string;
+ }[];
sentiment?: {
cluster: {
id: number;
name: string;
};
- value: number;
comment: string;
+ value: number;
}[];
- methodology?: {
- type: string;
- description: string;
- };
- questions?: {
- text: string;
- }[];
+ users?: number;
};
export type GetCampaignsByCidUxApiArg = {
/** Campaign id */
@@ -1430,13 +1400,13 @@ export type GetCampaignsByCidWidgetsApiArg = {
/** should update bug trend after request resolves? */
updateTrend?: boolean;
};
-export type GetInsightsByIidApiResponse = /** status 200 OK */ Insight;
-export type GetInsightsByIidApiArg = {
+export type DeleteInsightsByIidApiResponse = /** status 200 OK */ void;
+export type DeleteInsightsByIidApiArg = {
/** Insight id */
iid: string;
};
-export type DeleteInsightsByIidApiResponse = /** status 200 OK */ void;
-export type DeleteInsightsByIidApiArg = {
+export type GetInsightsByIidApiResponse = /** status 200 OK */ Insight;
+export type GetInsightsByIidApiArg = {
/** Insight id */
iid: string;
};
@@ -1445,30 +1415,91 @@ export type PatchInsightsByIidApiArg = {
/** Insight id */
iid: string;
body: {
- title?: string;
+ comment?: string;
description?: string;
- severity_id?: number;
observations_ids?: number[];
- comment?: string;
+ severity_id?: number;
+ title?: string;
visible?: number;
};
};
-export type GetMediaByIdApiResponse = unknown;
-export type GetMediaByIdApiArg = {
- id: string;
+export type GetInvitesByProfileAndTokenApiResponse = /** status 200 OK */ {
+ email: string;
+ name: string;
+ surname: string;
+ workspace: string;
+};
+export type GetInvitesByProfileAndTokenApiArg = {
+ profile: string;
+ token: string;
};
export type DeleteMediaCommentByMcidApiResponse = /** status 200 OK */ object;
export type DeleteMediaCommentByMcidApiArg = {
mcid: string;
};
+export type GetMediaByIdApiResponse = unknown;
+export type GetMediaByIdApiArg = {
+ id: string;
+};
+export type DeletePlansByPidApiResponse = unknown;
+export type DeletePlansByPidApiArg = {
+ pid: string;
+};
+export type GetPlansByPidApiResponse = /** status 200 OK */ {
+ campaign?: {
+ id: number;
+ startDate: string;
+ /** CustomerTitle ?? Title */
+ title: string;
+ };
+ config: {
+ modules: Module[];
+ };
+ id: number;
+ project: {
+ id: number;
+ name: string;
+ };
+ quote?: {
+ id: number;
+ status: 'pending' | 'proposed' | 'approved' | 'rejected';
+ value: string;
+ };
+ status: PlanStatus;
+ workspace_id: number;
+};
+export type GetPlansByPidApiArg = {
+ pid: string;
+};
+export type PatchPlansByPidApiResponse = unknown;
+export type PatchPlansByPidApiArg = {
+ pid: string;
+ body: {
+ config: {
+ modules: Module[];
+ };
+ };
+};
+export type PatchPlansByPidStatusApiResponse = /** status 200 OK */ {};
+export type PatchPlansByPidStatusApiArg = {
+ pid: string;
+ body: {
+ status: PlanStatus;
+ };
+};
export type PostProjectsApiResponse = /** status 200 OK */ Project;
export type PostProjectsApiArg = {
body: {
- name: string;
customer_id: number;
description?: string;
+ name: string;
};
};
+export type DeleteProjectsByPidApiResponse = /** status 200 OK */ void;
+export type DeleteProjectsByPidApiArg = {
+ /** Project id */
+ pid: string;
+};
export type GetProjectsByPidApiResponse = /** status 200 OK */ Project;
export type GetProjectsByPidApiArg = {
/** Project id */
@@ -1486,16 +1517,11 @@ export type PatchProjectsByPidApiArg = {
description: string;
};
};
-export type DeleteProjectsByPidApiResponse = /** status 200 OK */ void;
-export type DeleteProjectsByPidApiArg = {
- /** Project id */
- pid: string;
-};
export type GetProjectsByPidCampaignsApiResponse = /** status 200 OK */ {
items?: CampaignWithOutput[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetProjectsByPidCampaignsApiArg = {
@@ -1510,11 +1536,23 @@ export type GetProjectsByPidCampaignsApiArg = {
/** Order by accepted field */
orderBy?: string;
};
+export type DeleteProjectsByPidUsersApiResponse = /** status 200 OK */ {
+ items: Tenant[];
+};
+export type DeleteProjectsByPidUsersApiArg = {
+ /** Project id */
+ pid: string;
+ body: {
+ include_shared?: boolean;
+ /** Tryber WP USER ID */
+ user_id: number;
+ };
+};
export type GetProjectsByPidUsersApiResponse = /** status 200 OK */ {
items: Tenant[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetProjectsByPidUsersApiArg = {
@@ -1530,45 +1568,41 @@ export type GetProjectsByPidUsersApiArg = {
orderBy?: string;
};
export type PostProjectsByPidUsersApiResponse = /** status 200 OK */ {
+ email: string;
profile_id: number;
tryber_wp_user_id: number;
- email: string;
};
export type PostProjectsByPidUsersApiArg = {
/** Project id */
pid: string;
body: {
email: string;
- name?: string;
- surname?: string;
- locale?: string;
event_name?: string;
- redirect_url?: string;
+ locale?: string;
message?: string;
+ name?: string;
+ redirect_url?: string;
+ surname?: string;
};
};
-export type DeleteProjectsByPidUsersApiResponse = /** status 200 OK */ {
- items: Tenant[];
+export type PostUsersApiResponse = /** status 201 Created */ {
+ projectId?: number;
+ workspaceId: number;
};
-export type DeleteProjectsByPidUsersApiArg = {
- /** Project id */
- pid: string;
+export type PostUsersApiArg = {
body: {
- /** Tryber WP USER ID */
- user_id: number;
- include_shared?: boolean;
- };
+ name: string;
+ password: string;
+ roleId: number;
+ surname: string;
+ } & (
+ | DataForPostUsersRequestForInvitedUser
+ | DataForPostUsersRequestForNewUser
+ );
};
-export type GetTemplatesApiResponse = /** status 200 OK */ ({
- id?: number;
-} & Template)[];
-export type GetTemplatesApiArg = {
- /** filterBy[]= */
- filterBy?: any;
- /** Order value (ASC, DESC) */
- order?: string;
- /** Order by accepted field */
- orderBy?: string;
+export type HeadUsersByEmailByEmailApiResponse = unknown;
+export type HeadUsersByEmailByEmailApiArg = {
+ email: string;
};
export type GetUsersMeApiResponse = /** status 200 */ User;
export type GetUsersMeApiArg = void;
@@ -1584,6 +1618,11 @@ export type PutUsersMePreferencesBySlugApiArg = {
value: string;
};
};
+export type GetUsersRolesApiResponse = /** status 200 OK */ {
+ id: number;
+ name: string;
+}[];
+export type GetUsersRolesApiArg = void;
export type GetVideosByVidApiResponse = /** status 200 OK */ Video & {
usecase: {
id: number;
@@ -1605,36 +1644,36 @@ export type PostVideosByVidObservationsApiResponse =
export type PostVideosByVidObservationsApiArg = {
vid: string;
body: {
- start: number;
end: number;
+ start: number;
};
};
+export type DeleteVideosByVidObservationsAndOidApiResponse = unknown;
+export type DeleteVideosByVidObservationsAndOidApiArg = {
+ vid: string;
+ oid: string;
+};
export type PatchVideosByVidObservationsAndOidApiResponse =
/** status 200 OK */ Observation;
export type PatchVideosByVidObservationsAndOidApiArg = {
vid: string;
oid: string;
body: {
- title?: string;
description?: string;
- start?: number;
end?: number;
quotes?: string;
+ start?: number;
tags?: number[];
+ title?: string;
};
};
-export type DeleteVideosByVidObservationsAndOidApiResponse = unknown;
-export type DeleteVideosByVidObservationsAndOidApiArg = {
- vid: string;
- oid: string;
-};
export type GetVideosByVidTranslationApiResponse = /** status 200 OK */ {
language: string;
processing: number;
sentences: {
- text: string;
- start: number;
end: number;
+ start: number;
+ text: string;
}[];
};
export type GetVideosByVidTranslationApiArg = {
@@ -1651,9 +1690,9 @@ export type PostVideosByVidTranslationApiArg = {
};
export type GetWorkspacesApiResponse = /** status 200 OK */ {
items?: Workspace[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetWorkspacesApiArg = {
@@ -1667,8 +1706,8 @@ export type GetWorkspacesApiArg = {
orderBy?: string;
};
export type PostWorkspacesApiResponse = /** status 200 OK */ {
- id: number;
company: string;
+ id: number;
};
export type PostWorkspacesApiArg = {
body: {
@@ -1682,10 +1721,10 @@ export type GetWorkspacesByWidApiArg = {
wid: string;
};
export type GetWorkspacesByWidArchiveApiResponse = /** status 200 OK */ {
+ campaignsCounter: number;
+ description: string;
id: number;
name: string;
- description: string;
- campaignsCounter: number;
};
export type GetWorkspacesByWidArchiveApiArg = {
/** Workspace (company, customer) id */
@@ -1693,9 +1732,9 @@ export type GetWorkspacesByWidArchiveApiArg = {
};
export type GetWorkspacesByWidCampaignsApiResponse = /** status 200 OK */ {
items?: CampaignWithOutput[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetWorkspacesByWidCampaignsApiArg = {
@@ -1714,9 +1753,9 @@ export type GetWorkspacesByWidCampaignsApiArg = {
};
export type GetWorkspacesByWidCoinsApiResponse = /** status 200 OK */ {
items?: Coin[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetWorkspacesByWidCoinsApiArg = {
@@ -1731,20 +1770,8 @@ export type GetWorkspacesByWidCoinsApiArg = {
/** Order by accepted field */
orderBy?: string;
};
-export type PostWorkspacesByWidPlansApiResponse = /** status 201 Created */ {
- id: number;
-};
-export type PostWorkspacesByWidPlansApiArg = {
- wid: string;
- body: {
- template_id: number;
- project_id: number;
- };
-};
export type GetWorkspacesByWidPlansApiResponse = /** status 200 OK */ {
id: number;
- title: string;
- status: 'draft' | 'pending_review' | 'approved';
project: {
id: number;
title: string;
@@ -1753,6 +1780,8 @@ export type GetWorkspacesByWidPlansApiResponse = /** status 200 OK */ {
id: number;
status: 'pending' | 'proposed' | 'approved' | 'rejected';
};
+ status: 'draft' | 'pending_review' | 'approved';
+ title: string;
}[];
export type GetWorkspacesByWidPlansApiArg = {
wid: string;
@@ -1765,57 +1794,21 @@ export type GetWorkspacesByWidPlansApiArg = {
/** Limit pagination parameter */
limit?: number;
};
-export type DeletePlansByPidApiResponse = unknown;
-export type DeletePlansByPidApiArg = {
- pid: string;
-};
-export type GetPlansByPidApiResponse = /** status 200 OK */ {
+export type PostWorkspacesByWidPlansApiResponse = /** status 201 Created */ {
id: number;
- config: {
- modules: Module[];
- };
- status: PlanStatus;
- project: {
- id: number;
- name: string;
- };
- quote?: {
- id: number;
- status: 'pending' | 'proposed' | 'approved' | 'rejected';
- value: string;
- };
- campaign?: {
- id: number;
- /** CustomerTitle ?? Title */
- title: string;
- startDate: string;
- };
- workspace_id: number;
-};
-export type GetPlansByPidApiArg = {
- pid: string;
-};
-export type PatchPlansByPidApiResponse = unknown;
-export type PatchPlansByPidApiArg = {
- pid: string;
- body: {
- config: {
- modules: Module[];
- };
- };
};
-export type PatchPlansByPidStatusApiResponse = /** status 200 OK */ {};
-export type PatchPlansByPidStatusApiArg = {
- pid: string;
+export type PostWorkspacesByWidPlansApiArg = {
+ wid: string;
body: {
- status: PlanStatus;
+ project_id: number;
+ template_id: number;
};
};
export type GetWorkspacesByWidProjectsApiResponse = /** status 200 OK */ {
items?: Project[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetWorkspacesByWidProjectsApiArg = {
@@ -1826,6 +1819,32 @@ export type GetWorkspacesByWidProjectsApiArg = {
/** Start pagination parameter */
start?: number;
};
+export type GetWorkspacesByWidProjectsAndPidApiResponse =
+ /** status 200 OK */ Project;
+export type GetWorkspacesByWidProjectsAndPidApiArg = {
+ /** Workspace (company, customer) id */
+ wid: string;
+ /** Project id */
+ pid: string;
+};
+export type GetWorkspacesByWidProjectsAndPidCampaignsApiResponse =
+ /** status 200 OK */ {
+ items?: CampaignWithOutput[];
+ limit?: number;
+ size?: number;
+ start?: number;
+ total?: number;
+ };
+export type GetWorkspacesByWidProjectsAndPidCampaignsApiArg = {
+ /** Workspace (company, customer) id */
+ wid: string;
+ /** Project id */
+ pid: string;
+ /** Limit pagination parameter */
+ limit?: number;
+ /** Start pagination parameter */
+ start?: number;
+};
export type GetWorkspacesByWidTemplatesApiResponse = /** status 200 OK */ {
items: CpReqTemplate[];
} & PaginationData;
@@ -1851,49 +1870,35 @@ export type DeleteWorkspacesByWidTemplatesAndTidApiArg = {
};
export type GetWorkspacesByWidTemplatesAndTidApiResponse =
/** status 200 OK */ {
+ config: string;
+ description?: string;
id: number;
name: string;
- description?: string;
- config: string;
- workspace_id?: number;
price?: string;
strapi?: StrapiTemplate;
+ workspace_id?: number;
};
export type GetWorkspacesByWidTemplatesAndTidApiArg = {
wid: string;
tid: string;
};
-export type GetWorkspacesByWidProjectsAndPidApiResponse =
- /** status 200 OK */ Project;
-export type GetWorkspacesByWidProjectsAndPidApiArg = {
- /** Workspace (company, customer) id */
- wid: string;
- /** Project id */
- pid: string;
+export type DeleteWorkspacesByWidUsersApiResponse = /** status 200 OK */ {
+ items: Tenant[];
};
-export type GetWorkspacesByWidProjectsAndPidCampaignsApiResponse =
- /** status 200 OK */ {
- items?: CampaignWithOutput[];
- start?: number;
- limit?: number;
- size?: number;
- total?: number;
- };
-export type GetWorkspacesByWidProjectsAndPidCampaignsApiArg = {
+export type DeleteWorkspacesByWidUsersApiArg = {
/** Workspace (company, customer) id */
wid: string;
- /** Project id */
- pid: string;
- /** Limit pagination parameter */
- limit?: number;
- /** Start pagination parameter */
- start?: number;
+ body: {
+ include_shared?: boolean;
+ /** Tryber WP USER ID */
+ user_id: number;
+ };
};
export type GetWorkspacesByWidUsersApiResponse = /** status 200 OK */ {
items: Tenant[];
- start?: number;
limit?: number;
size?: number;
+ start?: number;
total?: number;
};
export type GetWorkspacesByWidUsersApiArg = {
@@ -1909,75 +1914,65 @@ export type GetWorkspacesByWidUsersApiArg = {
orderBy?: string;
};
export type PostWorkspacesByWidUsersApiResponse = /** status 200 OK */ {
+ email: string;
profile_id: number;
tryber_wp_user_id: number;
- email: string;
};
export type PostWorkspacesByWidUsersApiArg = {
/** Workspace (company, customer) id */
wid: string;
body: {
email: string;
- name?: string;
- surname?: string;
- locale?: string;
event_name?: string;
- redirect_url?: string;
+ locale?: string;
message?: string;
- };
-};
-export type DeleteWorkspacesByWidUsersApiResponse = /** status 200 OK */ {
- items: Tenant[];
-};
-export type DeleteWorkspacesByWidUsersApiArg = {
- /** Workspace (company, customer) id */
- wid: string;
- body: {
- /** Tryber WP USER ID */
- user_id: number;
- include_shared?: boolean;
+ name?: string;
+ redirect_url?: string;
+ surname?: string;
};
};
export type Error = {
- message: string;
code: number;
error: boolean;
+ message: string;
};
export type Authentication = {
- id: number;
email: string;
- role: string;
+ exp?: number;
+ iat?: number;
+ id: number;
name: string;
picture?: string;
+ role: string;
token: string;
- iat?: number;
- exp?: number;
};
export type Campaign = {
- id: number;
- start_date: string;
- end_date: string;
- close_date: string;
- title: string;
- customer_title: string;
- is_public: number;
+ base_bug_internal_id?: string;
/** -1: no bug form;
0: only bug form;
1: bug form with bug parade; */
bug_form?: number;
- type: {
+ close_date: string;
+ customer_title: string;
+ description?: string;
+ end_date: string;
+ family: {
id: number;
name: string;
};
- family: {
+ id: number;
+ is_public: number;
+ project: {
id: number;
name: string;
};
+ start_date: string;
status: {
id: number;
name: string;
};
- project: {
+ title: string;
+ type: {
id: number;
name: string;
};
@@ -1985,48 +1980,6 @@ export type Campaign = {
id: number;
name: string;
};
- description?: string;
- base_bug_internal_id?: string;
-};
-export type PlatformObject = {
- /** os */
- id: number;
- /** form_factor
-
- 0 => smartphone,
- 1 => tablet
- 2 => pc
- 3 => smartwatch
- 4 => console
- 5 => tv */
- deviceType: number;
-};
-export type TemplateCategory = {
- id?: number;
- name: string;
-};
-export type Template = {
- title: string;
- /** Short description used as preview of template or in templates dropdown */
- description?: string;
- /** HTML content used to pre-fill the use case editor */
- content?: string;
- category?: TemplateCategory;
- device_type?: 'webapp' | 'mobileapp';
- locale?: 'en' | 'it';
- image?: string;
- /** The use case created by this template needs a login or not? */
- requiresLogin?: boolean;
-};
-export type UseCase = {
- title: string;
- description: string;
- /** Optional in experiential campaigns */
- functionality?: {
- id?: number;
- } & Template;
- logged?: boolean;
- link?: string;
};
export type Output = 'bugs' | 'media' | 'insights';
export type CampaignWithOutput = Campaign & {
@@ -2036,38 +1989,16 @@ export type BugType = {
id: number;
name: string;
};
-export type BugTitle = {
- full: string;
- /** Bug title without context. */
- compact: string;
- context?: string[];
-};
-export type BugStatus = {
- id: number;
- name: string;
-};
-export type BugSeverity = {
- id: number;
- name: string;
-};
-export type BugReplicability = {
- id: number;
- name: string;
-};
-export type BugPriority = {
- id: number;
- name: string;
-};
export type BugCustomStatusPhase = {
id: number;
name: string;
};
export type BugCustomStatus = {
+ color: string;
id: number;
+ is_default: number;
name: string;
- color: string;
phase: BugCustomStatusPhase;
- is_default: number;
};
export type Smartphone = {
manufacturer: string;
@@ -2089,82 +2020,104 @@ export type Desktop = {
os_version: string;
type: 'desktop';
};
-export type Bug = {
+export type BugPriority = {
id: number;
- internal_id: string;
- campaign_id: number;
- title: BugTitle;
- step_by_step: string;
- expected_result: string;
- current_result: string;
- status: BugStatus;
- severity: BugSeverity;
- type: BugType;
- replicability: BugReplicability;
- priority: BugPriority;
- custom_status: BugCustomStatus;
- created: string;
- occurred_date: string;
- updated?: string;
- note?: string;
- device: Smartphone | Tablet | Desktop;
- application_section: {
- id?: number;
- prefix_title?: string;
- title?: string;
- simple_title?: string;
- };
- duplicated_of_id?: number;
- is_favorite?: number;
- read?: boolean;
+ name: string;
};
-export type BugMedia = {
- mime_type: {
- type: 'video' | 'image' | 'other';
- extension: string;
- };
- url: string;
- creation_date: string;
+export type BugReplicability = {
+ id: number;
+ name: string;
};
-export type BugTag = {
+export type BugSeverity = {
id: number;
- tag_id: number;
name: string;
- slug: string;
- bug_id: number;
+};
+export type BugStatus = {
+ id: number;
+ name: string;
+};
+export type BugTitle = {
+ /** Bug title without context. */
+ compact: string;
+ context?: string[];
+ full: string;
+};
+export type Bug = {
+ application_section: {
+ id?: number;
+ prefix_title?: string;
+ simple_title?: string;
+ title?: string;
+ };
campaign_id: number;
- author_wp_id?: number;
- author_tid?: number;
- creation_date: string;
- is_visible_to_customer?: number;
+ created: string;
+ current_result: string;
+ custom_status: BugCustomStatus;
+ device: Smartphone | Tablet | Desktop;
+ duplicated_of_id?: number;
+ expected_result: string;
+ id: number;
+ internal_id: string;
+ is_favorite?: number;
+ note?: string;
+ occurred_date: string;
+ priority: BugPriority;
+ read?: boolean;
+ replicability: BugReplicability;
+ severity: BugSeverity;
+ status: BugStatus;
+ step_by_step: string;
+ title: BugTitle;
+ type: BugType;
+ updated?: string;
};
export type BugAdditionalFieldRegex = {
- validation: string;
kind: 'regex';
+ validation: string;
};
export type BugAdditionalFieldSelect = {
- options: string[];
kind: 'select';
+ options: string[];
};
export type BugAdditionalField = {
id: number;
name: string;
value: string;
} & (BugAdditionalFieldRegex | BugAdditionalFieldSelect);
-export type BugComment = {
+export type BugMedia = {
+ creation_date: string;
+ mime_type: {
+ extension: string;
+ type: 'video' | 'image' | 'other';
+ };
+ url: string;
+};
+export type BugTag = {
+ author_tid?: number;
+ author_wp_id?: number;
+ bug_id: number;
+ campaign_id: number;
+ creation_date: string;
id: number;
- text: string;
+ is_visible_to_customer?: number;
+ name: string;
+ slug: string;
+ tag_id: number;
+};
+export type BugComment = {
creation_date: string;
creator: {
id: number;
- name: string;
isInternal: boolean;
+ name: string;
};
+ id: number;
media?: {
- url: string;
id: number;
type: string;
+ url: string;
}[];
+ text: string;
};
export type Cluster = {
id: number;
@@ -2183,45 +2136,45 @@ export type VideoTag = {
};
};
export type Observation = {
- id: number;
- title: string;
description: string;
- start: number;
end: number;
+ id: number;
quotes: string;
- uxNote?: string;
+ start: number;
tags: VideoTag[];
+ title: string;
+ uxNote?: string;
};
export type Insight = {
- id: number;
- title: string;
+ comment?: string;
description: string;
+ id: number;
+ observations: (Observation & {
+ uploaderId: number;
+ usecaseTitle: string;
+ video: {
+ deviceType: string;
+ id: number;
+ };
+ })[];
severity: {
id: number;
name: string;
style: string;
};
+ title: string;
visible?: number;
- comment?: string;
- observations: (Observation & {
- video: {
- id: number;
- deviceType: string;
- };
- uploaderId: number;
- usecaseTitle: string;
- })[];
};
export type Grape = {
- title: string;
- severity: string;
- usersNumber: number;
observations: (Observation & {
- uploaderId: number;
- mediaId: number;
deviceType: string;
+ mediaId: number;
+ uploaderId: number;
usecaseTitle: string;
})[];
+ severity: string;
+ title: string;
+ usersNumber: number;
};
export type ReportExtensions =
| 'pdf'
@@ -2239,98 +2192,98 @@ export type ReportExtensions =
| 'gz'
| '7z';
export type Report = {
- id?: number;
- title?: string;
+ creation_date?: string;
description?: string;
- url: string;
file_type?: {
+ domain_name?: string;
extension?: ReportExtensions;
type: string;
- domain_name?: string;
};
- creation_date?: string;
+ id?: number;
+ title?: string;
update_date?: string;
+ url: string;
};
export type BannerType =
| 'banner_testing_automation'
| 'banner_user_experience'
| 'banner_cyber_security';
export type Tenant = {
+ email: string;
/** tryber wp_user_id */
id: number;
- profile_id: number;
- name: string;
- email: string;
invitationPending: boolean;
+ name: string;
permissionFrom?: {
- type?: 'workspace' | 'project';
id?: number;
+ type?: 'workspace' | 'project';
};
+ profile_id: number;
+};
+export type MediaSentiment = {
+ paragraphs: {
+ end: number;
+ reason: string;
+ start: number;
+ value: number;
+ }[];
+ reason: string;
+ value: number;
};
export type Word = {
- start: number;
end: number;
/** Id of Speaker */
speaker?: number;
+ start: number;
word: string;
};
export type Paragraph = {
- text: string;
- start: number;
end: number;
/** Id Of speaker */
speaker?: number;
+ start: number;
+ text: string;
words: Word[];
};
export type Transcript = {
+ paragraphs: Paragraph[];
/** Number of spekers */
speakers: number;
- paragraphs: Paragraph[];
-};
-export type MediaSentiment = {
- value: number;
- reason: string;
- paragraphs: {
- start: number;
- end: number;
- value: number;
- reason: string;
- }[];
};
export type Video = {
+ duration?: number;
id: number;
- url: string;
- streamUrl?: string;
poster?: string;
- duration?: number;
+ sentiment?: MediaSentiment;
+ streamUrl?: string;
tester: {
- id: number;
- name: string;
- surname: string;
device: {
type: 'smartphone' | 'tablet' | 'desktop' | 'other';
};
+ id: number;
+ name: string;
+ surname: string;
};
transcript?: Transcript;
- sentiment?: MediaSentiment;
+ url: string;
};
export type PaginationData = {
- start?: number;
- size?: number;
limit?: number;
+ size?: number;
+ start?: number;
total?: number;
};
export type WidgetBugsByUseCase = {
data: {
+ bugs: number;
+ description: string;
title: {
full: string;
- simple?: string;
- prefix?: string;
info?: string;
+ prefix?: string;
+ simple?: string;
};
- description: string;
uniqueBugs?: number;
- bugs: number;
usecase_completion?: number;
usecase_id: number;
}[];
@@ -2338,30 +2291,30 @@ export type WidgetBugsByUseCase = {
};
export type WidgetBugsByDevice = {
data: ((Smartphone | Desktop | Tablet) & {
- unique_bugs: number;
/** Unique bugs */
bugs: number;
+ unique_bugs: number;
})[];
kind: 'bugsByDevice';
};
export type WidgetCampaignProgress = {
data: {
- start_date: string;
end_date: string;
- /** Percentage fixed rate of completion */
- usecase_completion: 12.5 | 37.5 | 62.5 | 87.5 | 100;
- /** Number of hours from start_date */
- time_elapsed: number;
/** Expected amount of hours required to complete the campaign */
expected_duration: number;
+ start_date: string;
+ /** Number of hours from start_date */
+ time_elapsed: number;
+ /** Percentage fixed rate of completion */
+ usecase_completion: 12.5 | 37.5 | 62.5 | 87.5 | 100;
};
kind: 'campaignProgress';
};
export type WidgetCampaignUniqueBugs = {
data: {
- unique: number;
total: number;
trend: number;
+ unique: number;
};
kind: 'campaignUniqueBugs';
};
@@ -2373,149 +2326,87 @@ export type WidgetBugsByDuplicates = {
};
export type WidgetCampaignUxTaggingVideoCompletionData = {
data: {
- countMediaWithObservation: number;
countMedia: number;
+ countMediaWithObservation: number;
};
kind: 'uxTaggingVideoCompletion';
};
-export type WidgetCampaignUxTotalTitlesVsRecurrentTitles = {
- data: {
- countTitleTag: number;
- countObservationNoTitle: number;
- countRecurrentTitles: number;
- };
- kind: 'uxTotalTitlesVsRecurrentTitles';
-};
-export type WidgetCampaignUxSeveritiesDistribution = {
- data: {
- countObservations: number;
- severitiesDistribution: {
- countPositiveFindings: number;
- countMinorIssue: number;
- countMajorIssue: number;
- countObservationSeverity: number;
- };
- };
- kind: 'uxSeveritiesDistribution';
-};
-export type WidgetCampaignUxMostUsedTitles = {
- data: {
- mostUsedTitles: {
- title: string;
- usage: number;
- mainSeverityAssignment: string;
- }[];
- };
- kind: 'uxMostUsedTitles';
-};
-export type Project = {
- id: number;
- name: string;
- campaigns_count: number;
- workspaceId: number;
- description?: string;
- is_archive?: number;
-};
-export type Feature = {
- slug?: string;
- name?: string;
-};
-export type User = {
- /** This is the main id of the user. Currently is equal to tryber_wp_user_id */
- id: number;
- email: string;
- role: string;
- name: string;
- profile_id: number;
- tryber_wp_user_id: number;
- unguess_wp_user_id: number;
- picture?: string;
- features?: Feature[];
-};
-export type UserPreference = {
- preference_id: number;
- value: string;
- name: string;
-};
-export type Workspace = {
- id: number;
- company: string;
- tokens: number;
- logo?: string;
- csm: {
- id: number;
- email: string;
- name: string;
- profile_id: number;
- tryber_wp_user_id: number;
- picture?: string;
- url?: string;
+export type WidgetCampaignUxTotalTitlesVsRecurrentTitles = {
+ data: {
+ countObservationNoTitle: number;
+ countRecurrentTitles: number;
+ countTitleTag: number;
};
- /** express coins */
- coins?: number;
- /** Do this workspace have shared items? */
- isShared?: boolean;
- /** Number of shared items */
- sharedItems?: number;
+ kind: 'uxTotalTitlesVsRecurrentTitles';
};
-export type Coin = {
- id: number;
- customer_id: number;
- /** Number of available coin */
- amount: number;
- agreement_id?: number;
- /** This is the single coin price */
- price?: number;
- created_on?: string;
- /** On each coin use, the related package will be updated */
- updated_on?: string;
+export type WidgetCampaignUxSeveritiesDistribution = {
+ data: {
+ countObservations: number;
+ severitiesDistribution: {
+ countMajorIssue: number;
+ countMinorIssue: number;
+ countObservationSeverity: number;
+ countPositiveFindings: number;
+ };
+ };
+ kind: 'uxSeveritiesDistribution';
+};
+export type WidgetCampaignUxMostUsedTitles = {
+ data: {
+ mostUsedTitles: {
+ mainSeverityAssignment: string;
+ title: string;
+ usage: number;
+ }[];
+ };
+ kind: 'uxMostUsedTitles';
};
export type ModuleTitle = {
+ output: string;
type: 'title';
variant: string;
- output: string;
};
export type ModuleDate = {
- type: 'dates';
- variant: string;
output: {
start: string;
};
+ type: 'dates';
+ variant: string;
};
export type SubcomponentTaskVideo = {
+ description?: string;
kind: 'video';
title: string;
- description?: string;
url?: string;
};
export type SubcomponentTaskBug = {
+ description?: string;
kind: 'bug';
title: string;
- description?: string;
url?: string;
};
export type SubcomponentTaskSurvey = {
+ description?: string;
kind: 'survey';
title: string;
- description?: string;
url?: string;
};
export type OutputModuleTaskModerateVideo = {
+ description?: string;
kind: 'moderate-video';
title: string;
- description?: string;
url?: string;
};
export type OutputModuleTaskExplorativeBug = {
+ description?: string;
kind: 'explorative-bug';
title: string;
- description?: string;
url?: string;
};
export type OutputModuleTaskAccessibility = {
+ description?: string;
kind: 'accessibility';
title: string;
- description?: string;
url?: string;
};
export type SubcomponentTask =
@@ -2526,85 +2417,85 @@ export type SubcomponentTask =
| OutputModuleTaskExplorativeBug
| OutputModuleTaskAccessibility;
export type ModuleTask = {
+ output: SubcomponentTask[];
type: 'tasks';
variant: string;
- output: SubcomponentTask[];
};
export type OutputModuleAge = {
- min: number;
max: number;
+ min: number;
percentage: number;
}[];
export type ModuleAge = {
+ output: OutputModuleAge;
type: 'age';
variant: string;
- output: OutputModuleAge;
};
export type ModuleLanguage = {
+ output: string;
type: 'language';
variant: string;
- output: string;
};
export type OutputModuleLiteracy = {
level: 'beginner' | 'intermediate' | 'expert';
percentage: number;
}[];
export type ModuleLiteracy = {
+ output: OutputModuleLiteracy;
type: 'literacy';
variant: string;
- output: OutputModuleLiteracy;
};
export type ModuleTarget = {
+ output: number;
type: 'target';
variant: string;
- output: number;
};
export type ModuleGoal = {
+ output: string;
type: 'goal';
variant: string;
- output: string;
};
export type OutputModuleGender = {
gender: 'male' | 'female';
percentage: number;
}[];
export type ModuleGender = {
+ output: OutputModuleGender;
type: 'gender';
variant: string;
- output: OutputModuleGender;
};
export type ModuleOutOfScope = {
+ output: string;
type: 'out_of_scope';
variant: string;
- output: string;
};
export type OutputModuleBrowser = {
name: 'firefox' | 'edge' | 'chrome' | 'safari';
percentage: number;
}[];
export type ModuleBrowser = {
+ output: OutputModuleBrowser;
type: 'browser';
variant: string;
- output: OutputModuleBrowser;
};
export type ModuleTargetNote = {
+ output: string;
type: 'target_note';
variant: string;
- output: string;
};
export type ModuleInstructionNote = {
+ output: string;
type: 'instruction_note';
variant: string;
- output: string;
};
export type ModuleSetupNote = {
+ output: string;
type: 'setup_note';
variant: string;
- output: string;
};
export type OutputModuleTouchpointsAppDesktop = {
- kind: 'app';
form_factor: 'desktop';
+ kind: 'app';
os: {
linux?: string;
macos?: string;
@@ -2612,25 +2503,25 @@ export type OutputModuleTouchpointsAppDesktop = {
};
};
export type OutputModuleTouchpointsAppTablet = {
- kind: 'app';
form_factor: 'tablet';
+ kind: 'app';
os: {
- linux?: string;
ios?: string;
+ linux?: string;
windows?: string;
};
};
export type OutputModuleTouchpointsAppSmartphone = {
- kind: 'app';
form_factor: 'smartphone';
+ kind: 'app';
os: {
android?: string;
ios?: string;
};
};
export type OutputModuleTouchpointsWebDesktop = {
- kind: 'web';
form_factor: 'desktop';
+ kind: 'web';
os: {
linux?: string;
macos?: string;
@@ -2638,16 +2529,16 @@ export type OutputModuleTouchpointsWebDesktop = {
};
};
export type OutputModuleTouchpointsWebTablet = {
- kind: 'web';
form_factor: 'tablet';
+ kind: 'web';
os: {
android?: string;
ios?: string;
};
};
export type OutputModuleTouchpointsWebSmartphone = {
- kind: 'web';
form_factor: 'smartphone';
+ kind: 'web';
os: {
android?: string;
ios?: string;
@@ -2661,14 +2552,14 @@ export type SubcomponentTouchpoints =
| OutputModuleTouchpointsWebTablet
| OutputModuleTouchpointsWebSmartphone;
export type ModuleTouchpoints = {
+ output: SubcomponentTouchpoints[];
type: 'touchpoints';
variant: string;
- output: SubcomponentTouchpoints[];
};
export type ModuleAdditionalTarget = {
+ output: string;
type: 'additional_target';
variant: string;
- output: string;
};
export type Module =
| ModuleTitle
@@ -2688,12 +2579,95 @@ export type Module =
| ModuleTouchpoints
| ModuleAdditionalTarget;
export type PlanStatus = 'pending_review' | 'draft' | 'approved';
+export type Project = {
+ campaigns_count: number;
+ description?: string;
+ id: number;
+ is_archive?: number;
+ name: string;
+ workspaceId: number;
+};
+export type DataForPostUsersRequestForInvitedUser = {
+ profileId: number;
+ token: string;
+ type: 'invite';
+};
+export type DataForPostUsersRequestForNewUser = {
+ email: string;
+ type: 'new';
+ workspace: string;
+};
+export type Feature = {
+ name?: string;
+ slug?: string;
+};
+export type User = {
+ customer_role: string;
+ email: string;
+ features?: Feature[];
+ /** This is the main id of the user. Currently is equal to tryber_wp_user_id */
+ id: number;
+ name: string;
+ picture?: string;
+ profile_id: number;
+ role: string;
+ tryber_wp_user_id: number;
+ unguess_wp_user_id: number;
+};
+export type UserPreference = {
+ name: string;
+ preference_id: number;
+ value: string;
+};
+export type Workspace = {
+ /** express coins */
+ coins?: number;
+ company: string;
+ csm: {
+ email: string;
+ id: number;
+ name: string;
+ picture?: string;
+ profile_id: number;
+ tryber_wp_user_id: number;
+ url?: string;
+ };
+ id: number;
+ /** Do this workspace have shared items? */
+ isShared?: boolean;
+ logo?: string;
+ /** Number of shared items */
+ sharedItems?: number;
+ tokens: number;
+};
+export type Coin = {
+ agreement_id?: number;
+ /** Number of available coin */
+ amount: number;
+ created_on?: string;
+ customer_id: number;
+ id: number;
+ /** This is the single coin price */
+ price?: number;
+ /** On each coin use, the related package will be updated */
+ updated_on?: string;
+};
export type StrapiTemplate = {
- title: string;
+ background?: string;
description: string;
- pre_title: string;
+ how?: {
+ description: string;
+ icon: string;
+ title: string;
+ }[];
image?: string;
output_image?: string;
+ pre_title: string;
+ price?: {
+ is_strikethrough?: number;
+ previous_price?: string;
+ price: string;
+ };
requirements?: {
description: string;
list: string[];
@@ -2702,64 +2676,53 @@ export type StrapiTemplate = {
icon: string;
text: string;
}[];
+ title: string;
+ what?: {
+ description: string;
+ goal: string;
+ };
why?: {
+ advantages: string[];
reasons: {
+ description: string;
icon: string;
title: string;
- description: string;
}[];
- advantages: string[];
- };
- what?: {
- description: string;
- goal: string;
- };
- how?: {
- icon: string;
- title: string;
- description: string;
- }[];
- price?: {
- price: string;
- previous_price?: string;
- is_strikethrough?: number;
};
- background?: string;
};
export type CpReqTemplate = {
+ config: string;
+ description?: string;
id: number;
name: string;
- description?: string;
- config: string;
- workspace_id?: number;
price?: string;
strapi?: StrapiTemplate;
+ workspace_id?: number;
};
export const {
use$getQuery,
- usePostAuthenticateMutation,
usePostAnalyticsViewsCampaignsByCidMutation,
- usePostCampaignsMutation,
- usePatchCampaignsByCidMutation,
+ usePostAuthenticateMutation,
useGetCampaignsByCidQuery,
+ usePatchCampaignsByCidMutation,
useGetCampaignsByCidBugTypesQuery,
useGetCampaignsByCidBugsQuery,
useGetCampaignsByCidBugsAndBidQuery,
usePatchCampaignsByCidBugsAndBidMutation,
useGetCampaignsByCidBugsAndBidCommentsQuery,
usePostCampaignsByCidBugsAndBidCommentsMutation,
- usePostCampaignsByCidBugsAndBidMediaMutation,
- usePostCampaignsByCidBugsAndBidCommentsCmidMutation,
useDeleteCampaignsByCidBugsAndBidCommentsCmidMutation,
+ usePostCampaignsByCidBugsAndBidCommentsCmidMutation,
+ usePostCampaignsByCidBugsAndBidMediaMutation,
useGetCampaignsByCidBugsAndBidSiblingsQuery,
useGetCampaignsByCidClustersQuery,
+ useDeleteCampaignsByCidCustomStatusesMutation,
useGetCampaignsByCidCustomStatusesQuery,
usePatchCampaignsByCidCustomStatusesMutation,
- useDeleteCampaignsByCidCustomStatusesMutation,
useGetCampaignsByCidDevicesQuery,
usePutCampaignsByCidFindingsAndFidMutation,
- usePostCampaignsByCidInsightsMutation,
useGetCampaignsByCidInsightsQuery,
+ usePostCampaignsByCidInsightsMutation,
useGetCampaignsByCidMetaQuery,
useGetCampaignsByCidObservationsQuery,
useGetCampaignsByCidOsQuery,
@@ -2771,36 +2734,43 @@ export const {
usePostCampaignsByCidSuggestionsMutation,
useGetCampaignsByCidTagsQuery,
useGetCampaignsByCidUsecasesQuery,
+ useDeleteCampaignsByCidUsersMutation,
useGetCampaignsByCidUsersQuery,
usePostCampaignsByCidUsersMutation,
- useDeleteCampaignsByCidUsersMutation,
useGetCampaignsByCidUxQuery,
useGetCampaignsByCidVideoTagsQuery,
usePostCampaignsByCidVideoTagsMutation,
useGetCampaignsByCidVideosQuery,
useGetCampaignsByCidWidgetsQuery,
- useGetInsightsByIidQuery,
useDeleteInsightsByIidMutation,
+ useGetInsightsByIidQuery,
usePatchInsightsByIidMutation,
- useGetMediaByIdQuery,
+ useGetInvitesByProfileAndTokenQuery,
useDeleteMediaCommentByMcidMutation,
+ useGetMediaByIdQuery,
+ useDeletePlansByPidMutation,
+ useGetPlansByPidQuery,
+ usePatchPlansByPidMutation,
+ usePatchPlansByPidStatusMutation,
usePostProjectsMutation,
+ useDeleteProjectsByPidMutation,
useGetProjectsByPidQuery,
usePatchProjectsByPidMutation,
- useDeleteProjectsByPidMutation,
useGetProjectsByPidCampaignsQuery,
+ useDeleteProjectsByPidUsersMutation,
useGetProjectsByPidUsersQuery,
usePostProjectsByPidUsersMutation,
- useDeleteProjectsByPidUsersMutation,
- useGetTemplatesQuery,
+ usePostUsersMutation,
+ useHeadUsersByEmailByEmailMutation,
useGetUsersMeQuery,
useGetUsersMePreferencesQuery,
usePutUsersMePreferencesBySlugMutation,
+ useGetUsersRolesQuery,
useGetVideosByVidQuery,
useGetVideosByVidObservationsQuery,
usePostVideosByVidObservationsMutation,
- usePatchVideosByVidObservationsAndOidMutation,
useDeleteVideosByVidObservationsAndOidMutation,
+ usePatchVideosByVidObservationsAndOidMutation,
useGetVideosByVidTranslationQuery,
usePostVideosByVidTranslationMutation,
useGetWorkspacesQuery,
@@ -2809,19 +2779,15 @@ export const {
useGetWorkspacesByWidArchiveQuery,
useGetWorkspacesByWidCampaignsQuery,
useGetWorkspacesByWidCoinsQuery,
- usePostWorkspacesByWidPlansMutation,
useGetWorkspacesByWidPlansQuery,
- useDeletePlansByPidMutation,
- useGetPlansByPidQuery,
- usePatchPlansByPidMutation,
- usePatchPlansByPidStatusMutation,
+ usePostWorkspacesByWidPlansMutation,
useGetWorkspacesByWidProjectsQuery,
+ useGetWorkspacesByWidProjectsAndPidQuery,
+ useGetWorkspacesByWidProjectsAndPidCampaignsQuery,
useGetWorkspacesByWidTemplatesQuery,
useDeleteWorkspacesByWidTemplatesAndTidMutation,
useGetWorkspacesByWidTemplatesAndTidQuery,
- useGetWorkspacesByWidProjectsAndPidQuery,
- useGetWorkspacesByWidProjectsAndPidCampaignsQuery,
+ useDeleteWorkspacesByWidUsersMutation,
useGetWorkspacesByWidUsersQuery,
usePostWorkspacesByWidUsersMutation,
- useDeleteWorkspacesByWidUsersMutation,
} = injectedRtkApi;
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 6cf4337a4..15929df48 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -704,6 +704,7 @@
"__PAGE_NOT_ACCESIBLE_DESCRIPTION": "It seems that your access is no longer active. You can log out or contact our support center. We are here to help you!",
"__PAGE_NOT_ACCESIBLE_TITLE": "You cannot access this page at the moment.",
"__PAGE_TITLE_BUGS_COLLECTION": "Bug collection",
+ "__PAGE_TITLE_JOIN": "join page",
"__PAGE_TITLE_LOGIN": "Log in",
"__PAGE_TITLE_PRIMARY_DASHBOARD": "My activities",
"__PAGE_TITLE_PRIMARY_DASHBOARD_ARCHIVE": "Archive",
@@ -1197,6 +1198,11 @@
"INSIGHT_PAGE_COLLECTION_USECASE_SUBTITTLE": "Recurring Themes",
"INSIGHTS_PAGE_COLLECTION_SUBTITLE": "Here you can find all the observations collected so far.",
"INSIGHTS_PAGE_COLLECTION_TITLE": "Themes and Observations",
+ "PASSWORD_VALIDATOR_CONTAIN_A_LOWERCASE_LETTER": "One lowercase character",
+ "PASSWORD_VALIDATOR_CONTAIN_A_NUMBER": "One numeric digit",
+ "PASSWORD_VALIDATOR_CONTAIN_AN_UPPERCASE_LETTER": "One uppercase character",
+ "PASSWORD_VALIDATOR_MINIMUM_OF_6_CHARACTERS": "Contain\u00a06 characters minimum",
+ "PASSWORD_VALIDATOR_PASSWORD_REQUIREMENTS": "Your password must:",
"PLAN_GLOBAL_ALERT_APPROVED_STATE_MESSAGE": "You will be notified when the first data is available on your dashboard",
"PLAN_GLOBAL_ALERT_APPROVED_STATE_TITLE": "The activity has been successfully launched!",
"PLAN_GLOBAL_ALERT_AWATING_STATE_MESSAGE": "Review details and confirm to launch.",
@@ -1205,6 +1211,46 @@
"PLAN_GLOBAL_ALERT_SUBMITTED_STATE_TITLE": "Activity submitted for review",
"Severity ({{count}})_one": "Severity ({{count}})",
"Severity ({{count}})_other": "Severities ({{count}})",
+ "SIGNUP_FORM_CTA_RETURN_TO_UNGUESS_LANDING": "Go to the UNGUESS website",
+ "SIGNUP_FORM_EMAIL_ALREADY_TAKEN": "Error: User with provided email already exists",
+ "SIGNUP_FORM_EMAIL_ERROR_SERVER_MAIL_CHECK": "Oops! Check your email format",
+ "SIGNUP_FORM_EMAIL_IS_REQUIRED": "This field is required",
+ "SIGNUP_FORM_EMAIL_LABEL": "Work Email",
+ "SIGNUP_FORM_EMAIL_MUST_BE_A_VALID_EMAIL": "Oops! Check your email format",
+ "SIGNUP_FORM_EMAIL_PLACEHOLDER": "Insert Email",
+ "SIGNUP_FORM_GO_TO_STEP_2": "Create my account",
+ "SIGNUP_FORM_GO_TO_STEP_3": "Next",
+ "SIGNUP_FORM_NAME_IS_REQUIRED": "This field is required",
+ "SIGNUP_FORM_NAME_LABEL": "First name",
+ "SIGNUP_FORM_NAME_PLACEHOLDER": "Insert name",
+ "SIGNUP_FORM_PASSWORD_HIDE": "hide",
+ "SIGNUP_FORM_PASSWORD_IS_A_REQUIRED_FIELD": "This field is required",
+ "SIGNUP_FORM_PASSWORD_LABEL": "Insert password",
+ "SIGNUP_FORM_PASSWORD_MUST_BE_AT_LEAST_6_CHARACTER_LONG": "The password must be at least 6 characters long",
+ "SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_LOWERCASE_LETTER": "The password must contain at least one lowercase letter",
+ "SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_NUMBER": "The password must contain at least one number",
+ "SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_AN_UPPERCASE_LETTER": "The password must contain at least one uppercase letter",
+ "SIGNUP_FORM_PASSWORD_PLACEHOLDER": "Insert password",
+ "SIGNUP_FORM_PASSWORD_SHOW": "show",
+ "SIGNUP_FORM_RETURN_TO_STEP_1": "Back",
+ "SIGNUP_FORM_RETURN_TO_STEP_2": "Back",
+ "SIGNUP_FORM_ROLE_IS_REQUIRED": "This field is required",
+ "SIGNUP_FORM_ROLE_LABEL": "Job title",
+ "SIGNUP_FORM_STEP_1_DESCRIPTION": "Start personalizing your experience, it only takes a few minutes.",
+ "SIGNUP_FORM_STEP_1_TITLE": "Welcome!
Get started with your account!",
+ "SIGNUP_FORM_STEP_2_DESCRIPTION": "So we can tailor the experience to fit your role and needs.",
+ "SIGNUP_FORM_STEP_2_TITLE": "Tell us a bit about yourself",
+ "SIGNUP_FORM_STEP_3_DESCRIPTION": "Choose a name that represents your team — it’ll shape your personalized experience.",
+ "SIGNUP_FORM_STEP_3_TITLE": "Create your workspace",
+ "SIGNUP_FORM_SUBMIT": "Let's start!",
+ "SIGNUP_FORM_SURNAME_IS_REQUIRED": "This field is required",
+ "SIGNUP_FORM_SURNAME_LABEL": "Last name",
+ "SIGNUP_FORM_SURNAME_PLACEHOLDER": "Insert last name",
+ "SIGNUP_FORM_TERMS_AND_CONDITIONS": "By signing up, you agree to our Terms and Conditions",
+ "SIGNUP_FORM_WAITING_FOR_SIGNUP": "Setting up your accountThis will take just a few seconds.",
+ "SIGNUP_FORM_WORKSPACE_IS_REQUIRED": "This field is required",
+ "SIGNUP_FORM_WORKSPACE_LABEL": "Name your Workspace",
+ "SIGNUP_FORM_WORKSPACE_PLACEHOLDER": "Insert Workspace name",
"UseCase ({{count}})_one": "Use Case ({{count}})",
"UseCase ({{count}})_other": "Use Cases ({{count}})",
"UX_SHORTCUT_ADD_OBSERVATION": "Start/Stop new observation",
diff --git a/src/locales/it/translation.json b/src/locales/it/translation.json
index 651b368a0..ee9fdac0f 100644
--- a/src/locales/it/translation.json
+++ b/src/locales/it/translation.json
@@ -734,6 +734,7 @@
"__PAGE_NOT_ACCESIBLE_DESCRIPTION": "Sembra che tu non abbia più accesso al workspace. Se hai bisogno di aiuto, contatta il nostro centro assistenza. ",
"__PAGE_NOT_ACCESIBLE_TITLE": "Al momento non è possibile accedere a questa pagina.",
"__PAGE_TITLE_BUGS_COLLECTION": "Raccolta bug",
+ "__PAGE_TITLE_JOIN": "",
"__PAGE_TITLE_LOGIN": "Accedi",
"__PAGE_TITLE_PRIMARY_DASHBOARD": "Le mie campagne",
"__PAGE_TITLE_PRIMARY_DASHBOARD_ARCHIVE": "",
@@ -1235,6 +1236,11 @@
"INSIGHT_PAGE_COLLECTION_USECASE_SUBTITTLE": "Titoli ricorrenti",
"INSIGHTS_PAGE_COLLECTION_SUBTITLE": "Qui trovi tutte le tue osservazioni che hai collezionato fin ad ora.",
"INSIGHTS_PAGE_COLLECTION_TITLE": "Temi e osservazioni",
+ "PASSWORD_VALIDATOR_CONTAIN_A_LOWERCASE_LETTER": "",
+ "PASSWORD_VALIDATOR_CONTAIN_A_NUMBER": "",
+ "PASSWORD_VALIDATOR_CONTAIN_AN_UPPERCASE_LETTER": "",
+ "PASSWORD_VALIDATOR_MINIMUM_OF_6_CHARACTERS": "",
+ "PASSWORD_VALIDATOR_PASSWORD_REQUIREMENTS": "",
"PLAN_GLOBAL_ALERT_APPROVED_STATE_MESSAGE": "",
"PLAN_GLOBAL_ALERT_APPROVED_STATE_TITLE": "",
"PLAN_GLOBAL_ALERT_AWATING_STATE_MESSAGE": "",
@@ -1244,6 +1250,46 @@
"Severity ({{count}})_one": "Gravità ({{count}})",
"Severity ({{count}})_many": "",
"Severity ({{count}})_other": "Gravità ({{count}})",
+ "SIGNUP_FORM_CTA_RETURN_TO_UNGUESS_LANDING": "",
+ "SIGNUP_FORM_EMAIL_ALREADY_TAKEN": "",
+ "SIGNUP_FORM_EMAIL_ERROR_SERVER_MAIL_CHECK": "",
+ "SIGNUP_FORM_EMAIL_IS_REQUIRED": "",
+ "SIGNUP_FORM_EMAIL_LABEL": "",
+ "SIGNUP_FORM_EMAIL_MUST_BE_A_VALID_EMAIL": "",
+ "SIGNUP_FORM_EMAIL_PLACEHOLDER": "",
+ "SIGNUP_FORM_GO_TO_STEP_2": "",
+ "SIGNUP_FORM_GO_TO_STEP_3": "",
+ "SIGNUP_FORM_NAME_IS_REQUIRED": "",
+ "SIGNUP_FORM_NAME_LABEL": "",
+ "SIGNUP_FORM_NAME_PLACEHOLDER": "",
+ "SIGNUP_FORM_PASSWORD_HIDE": "",
+ "SIGNUP_FORM_PASSWORD_IS_A_REQUIRED_FIELD": "",
+ "SIGNUP_FORM_PASSWORD_LABEL": "",
+ "SIGNUP_FORM_PASSWORD_MUST_BE_AT_LEAST_6_CHARACTER_LONG": "",
+ "SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_LOWERCASE_LETTER": "",
+ "SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_NUMBER": "",
+ "SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_AN_UPPERCASE_LETTER": "",
+ "SIGNUP_FORM_PASSWORD_PLACEHOLDER": "",
+ "SIGNUP_FORM_PASSWORD_SHOW": "",
+ "SIGNUP_FORM_RETURN_TO_STEP_1": "",
+ "SIGNUP_FORM_RETURN_TO_STEP_2": "",
+ "SIGNUP_FORM_ROLE_IS_REQUIRED": "",
+ "SIGNUP_FORM_ROLE_LABEL": "",
+ "SIGNUP_FORM_STEP_1_DESCRIPTION": "",
+ "SIGNUP_FORM_STEP_1_TITLE": "",
+ "SIGNUP_FORM_STEP_2_DESCRIPTION": "",
+ "SIGNUP_FORM_STEP_2_TITLE": "",
+ "SIGNUP_FORM_STEP_3_DESCRIPTION": "",
+ "SIGNUP_FORM_STEP_3_TITLE": "",
+ "SIGNUP_FORM_SUBMIT": "",
+ "SIGNUP_FORM_SURNAME_IS_REQUIRED": "",
+ "SIGNUP_FORM_SURNAME_LABEL": "",
+ "SIGNUP_FORM_SURNAME_PLACEHOLDER": "",
+ "SIGNUP_FORM_TERMS_AND_CONDITIONS": "",
+ "SIGNUP_FORM_WAITING_FOR_SIGNUP": "",
+ "SIGNUP_FORM_WORKSPACE_IS_REQUIRED": "",
+ "SIGNUP_FORM_WORKSPACE_LABEL": "",
+ "SIGNUP_FORM_WORKSPACE_PLACEHOLDER": "",
"UseCase ({{count}})_one": "Use Case ({{count}})",
"UseCase ({{count}})_many": "",
"UseCase ({{count}})_other": "Use Case ({{count}})",
diff --git a/src/pages/JoinPage/FormProvider.tsx b/src/pages/JoinPage/FormProvider.tsx
new file mode 100644
index 000000000..af34e65c2
--- /dev/null
+++ b/src/pages/JoinPage/FormProvider.tsx
@@ -0,0 +1,51 @@
+import { Formik, Form, FormikProps } from 'formik';
+import { useMemo } from 'react';
+import { useValidationSchema } from './validationSchema';
+import { useJoinSubmit } from './useJoinSubmit';
+import { JoinFormValues } from './valuesType';
+
+interface FormProviderProps {
+ children: (props: FormikProps) => React.ReactNode;
+ email?: string;
+ name?: string;
+ surname?: string;
+ workspace?: string;
+}
+
+export const FormProvider = ({
+ children,
+ email,
+ name,
+ surname,
+ workspace,
+}: FormProviderProps) => {
+ const initialValues: JoinFormValues = {
+ step: 1,
+ email: email || '',
+ password: '',
+ name: name || '',
+ surname: surname || '',
+ roleId: 0,
+ workspace: workspace || '',
+ };
+
+ // logic to check if the user is invited
+ // for the time being we are checking if the mail is not empty
+ const isInvited = useMemo(() => !!email, [email]);
+ const validationSchema = useValidationSchema();
+ const { onSubmit } = useJoinSubmit(isInvited);
+
+ return (
+
+ {(props) => }
+
+ );
+};
diff --git a/src/pages/JoinPage/ImagesColumn.tsx b/src/pages/JoinPage/ImagesColumn.tsx
new file mode 100644
index 000000000..fadbf548a
--- /dev/null
+++ b/src/pages/JoinPage/ImagesColumn.tsx
@@ -0,0 +1,82 @@
+import { useFormikContext } from 'formik';
+import { AnimatePresence } from 'motion/react';
+import * as motion from 'motion/react-client';
+import { useEffect, useMemo, useState } from 'react';
+import logoImgs from 'src/assets/join-loghi.png';
+import logoImgsWebp from 'src/assets/join-loghi.webp';
+import joinImg1 from 'src/assets/join-step-1.svg';
+import joinImg1webp from 'src/assets/join-step-1.webp';
+import joinImg2 from 'src/assets/join-step-2.png';
+import joinImg2webp from 'src/assets/join-step-2.webp';
+import joinImg3 from 'src/assets/join-step-3.png';
+import joinImg3webp from 'src/assets/join-step-3.webp';
+import styled from 'styled-components';
+import { JoinFormValues } from './valuesType';
+
+const ImagesWrapper = styled.div`
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ width: 100%;
+ height: calc(100vh - ${({ theme }) => theme.space.xl} * 2);
+ overflow: hidden;
+`;
+
+const LogoPicture = styled.picture`
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 100%;
+`;
+
+export const ImagesColumn = () => {
+ const { values } = useFormikContext();
+ const [step, setStep] = useState(values.step);
+ const forwardAnimation = useMemo(
+ () => values.step - step * 10,
+ [values.step, step]
+ );
+ useEffect(() => {
+ setStep(values.step);
+ }, [values.step]);
+ return (
+
+
+
+ {step === 1 && (
+
+
+
+
+ )}
+ {step === 2 && (
+
+
+
+
+ )}
+ {step === 3 && (
+
+
+
+
+ )}
+
+
+ {step === 1 && (
+
+
+
+
+ )}
+
+ );
+};
diff --git a/src/pages/JoinPage/JoinForm.tsx b/src/pages/JoinPage/JoinForm.tsx
new file mode 100644
index 000000000..5a9b0492d
--- /dev/null
+++ b/src/pages/JoinPage/JoinForm.tsx
@@ -0,0 +1,53 @@
+import { Paragraph, XL } from '@appquality/unguess-design-system';
+import { useFormikContext } from 'formik';
+import { Trans, useTranslation } from 'react-i18next';
+import { appTheme } from 'src/app/theme';
+import styled from 'styled-components';
+import { Step1 } from './Steps/Step1';
+import { Step2 } from './Steps/Step2';
+import { Step3 } from './Steps/Step3';
+import { JoinFormValues } from './valuesType';
+
+const FieldContainer = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: ${(p) => p.theme.space.md};
+`;
+
+const FormContainer = styled.div`
+ @media (min-width: ${(p) => p.theme.breakpoints.md}) {
+ padding: 0 ${(p) => p.theme.space.xxl};
+ }
+`;
+
+export const JoinForm = () => {
+ const {
+ values: { step },
+ } = useFormikContext();
+ const { t } = useTranslation();
+ return (
+
+
+
+ {step === 1 && (
+ }}
+ />
+ )}
+ {step === 2 && t('SIGNUP_FORM_STEP_2_TITLE')}
+ {step === 3 && t('SIGNUP_FORM_STEP_3_TITLE')}
+
+
+ {step === 2 && t('SIGNUP_FORM_STEP_2_DESCRIPTION')}
+ {step === 3 && t('SIGNUP_FORM_STEP_3_DESCRIPTION')}
+
+
+
+ {step === 1 && }
+ {step === 2 && }
+ {step === 3 && }
+
+
+ );
+};
diff --git a/src/pages/JoinPage/JoinPageError.tsx b/src/pages/JoinPage/JoinPageError.tsx
new file mode 100644
index 000000000..c56bbe0fe
--- /dev/null
+++ b/src/pages/JoinPage/JoinPageError.tsx
@@ -0,0 +1,91 @@
+import { Button, MD, XL } from '@appquality/unguess-design-system';
+import { useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useParams } from 'react-router-dom';
+import { appTheme } from 'src/app/theme';
+import { ReactComponent as BackgroundImage } from 'src/assets/icons/lost-in-the-space.svg';
+import { useSendGTMevent } from 'src/hooks/useGTMevent';
+import styled from 'styled-components';
+
+const Wrapper = styled.div`
+ width: 100%;
+ height: 100vh;
+ background-color: ${appTheme.palette.grey[100]};
+ display: flex;
+ align-items: center;
+`;
+
+const StyledRow = styled.div`
+ margin-left: auto;
+ margin-right: auto;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: ${appTheme.space.md};
+
+ @media (min-width: ${appTheme.breakpoints.xl}) {
+ flex-direction: row;
+ max-width: 1200px;
+ }
+`;
+const ButtonWrapper = styled.div`
+ display: flex;
+ gap: ${appTheme.space.sm};
+ margin-top: ${appTheme.space.md};
+`;
+
+export const JoinPageError = () => {
+ const { t } = useTranslation();
+ const sendGTMevent = useSendGTMevent();
+ const { profile, token } = useParams();
+ const isInvited = profile && token;
+
+ useEffect(() => {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: 'not set',
+ action: 'not set',
+ content: 'error page',
+ target: `is invited: ${isInvited}`,
+ });
+ }, []);
+
+ return (
+
+
+
+
+
+
+ {t('JOIN_PAGE_ERROR_TITLE')}
+
+ {t('JOIN_PAGE_ERROR_DESCRIPTION')}
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/pages/JoinPage/JoinPageLoading.tsx b/src/pages/JoinPage/JoinPageLoading.tsx
new file mode 100644
index 000000000..31f6a1d66
--- /dev/null
+++ b/src/pages/JoinPage/JoinPageLoading.tsx
@@ -0,0 +1,7 @@
+export const JoinPageLoading = () => (
+
+
+

+
+
+);
diff --git a/src/pages/JoinPage/Steps/ButtonContainer.tsx b/src/pages/JoinPage/Steps/ButtonContainer.tsx
new file mode 100644
index 000000000..7690d97e5
--- /dev/null
+++ b/src/pages/JoinPage/Steps/ButtonContainer.tsx
@@ -0,0 +1,9 @@
+import styled from 'styled-components';
+
+export const ButtonContainer = styled.div`
+ display: flex;
+ gap: ${(p) => p.theme.space.sm};
+ align-items: center;
+ justify-content: flex-end;
+ padding-top: ${(p) => p.theme.space.md};
+`;
diff --git a/src/pages/JoinPage/Steps/PasswordRequirements.tsx b/src/pages/JoinPage/Steps/PasswordRequirements.tsx
new file mode 100644
index 000000000..795147968
--- /dev/null
+++ b/src/pages/JoinPage/Steps/PasswordRequirements.tsx
@@ -0,0 +1,63 @@
+import { MD, theme } from '@appquality/unguess-design-system';
+import { ReactComponent as X } from 'src/assets/icons/password-check-x.svg';
+import { ReactComponent as Check } from 'src/assets/icons/password-check-v.svg';
+import { useFormikContext } from 'formik';
+import { useTranslation } from 'react-i18next';
+import { JoinFormValues } from '../valuesType';
+
+const PasswordRequirement = ({
+ check,
+ children,
+}: {
+ check: () => boolean;
+ children: React.ReactNode;
+}) => (
+
+ {check() ? (
+
+ ) : (
+
+ )}
+
+ {children}
+
+
+);
+
+const PasswordRequirements = () => {
+ const { values } = useFormikContext();
+ const { t } = useTranslation();
+
+ return (
+
+
{t('PASSWORD_VALIDATOR_PASSWORD_REQUIREMENTS')}
+
+ values.password.length >= 6}>
+ {t('PASSWORD_VALIDATOR_MINIMUM_OF_6_CHARACTERS')}
+
+ values.password.match(/[A-Z]/) !== null}
+ >
+ {t('PASSWORD_VALIDATOR_CONTAIN_AN_UPPERCASE_LETTER')}
+
+ values.password.match(/[a-z]/) !== null}
+ >
+ {t('PASSWORD_VALIDATOR_CONTAIN_A_LOWERCASE_LETTER')}
+
+ values.password.match(/[0-9]/) !== null}
+ >
+ {t('PASSWORD_VALIDATOR_CONTAIN_A_NUMBER')}
+
+
+
+ );
+};
+
+export { PasswordRequirements };
diff --git a/src/pages/JoinPage/Steps/Step1.tsx b/src/pages/JoinPage/Steps/Step1.tsx
new file mode 100644
index 000000000..7e9c83895
--- /dev/null
+++ b/src/pages/JoinPage/Steps/Step1.tsx
@@ -0,0 +1,210 @@
+import {
+ Anchor,
+ Button,
+ FormField,
+ Input,
+ Label,
+ MediaInput,
+ Message,
+ Paragraph,
+ Span,
+} from '@appquality/unguess-design-system';
+import { ReactComponent as LinkIcon } from '@zendeskgarden/svg-icons/src/16/chevron-left-stroke.svg';
+import { ReactComponent as Eye } from '@zendeskgarden/svg-icons/src/16/eye-fill.svg';
+import { ReactComponent as EyeHide } from '@zendeskgarden/svg-icons/src/16/eye-hide-fill.svg';
+import { Field, FieldProps, useFormikContext } from 'formik';
+import { useEffect, useState } from 'react';
+import { Trans, useTranslation } from 'react-i18next';
+import { appTheme } from 'src/app/theme';
+import { useSendGTMevent } from 'src/hooks/useGTMevent';
+import { JoinFormValues } from '../valuesType';
+import { ButtonContainer } from './ButtonContainer';
+import { PasswordRequirements } from './PasswordRequirements';
+
+export const Step1 = () => {
+ const { setFieldValue, validateForm, setTouched, status, values } =
+ useFormikContext();
+ const sendGTMevent = useSendGTMevent();
+ const { t } = useTranslation();
+ const [inputType, setInputType] = useState('password');
+ const handleChangeInputType = () => {
+ setInputType((prev) => (prev === 'password' ? 'text' : 'password'));
+ };
+
+ useEffect(() => {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${status?.isInvited}`,
+ content: 'step 1 rendered',
+ });
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${status?.isInvited}`,
+ action: 'start',
+ });
+ }, []);
+
+ const goToNextStep = async () => {
+ await setTouched({
+ email: true,
+ password: true,
+ });
+ const errors = await validateForm();
+ if (Object.keys(errors).length > 0) {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${status?.isInvited}`,
+ action: 'step 1 validation error',
+ content: `error count: ${Object.keys(errors).length}`,
+ });
+ return;
+ }
+ setFieldValue('step', 2);
+ };
+
+ const validateEmail = async (value: string) => {
+ let error;
+ let error_event;
+ if (status?.isInvited) return error;
+ const res = await fetch(
+ `${process.env.REACT_APP_API_URL}/users/by-email/${value}`,
+ {
+ method: 'HEAD',
+ }
+ );
+
+ if (res.status === 200) {
+ error = t('SIGNUP_FORM_EMAIL_ALREADY_TAKEN');
+ error_event = 'SIGNUP_FORM_EMAIL_ALREADY_TAKEN';
+ } else if (res.status === 404) {
+ error = undefined;
+ error_event = 'no error';
+ } else {
+ error = t('SIGNUP_FORM_EMAIL_ERROR_SERVER_MAIL_CHECK');
+ error_event = 'SIGNUP_FORM_EMAIL_ERROR_SERVER_MAIL_CHECK';
+ }
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: 'not set',
+ action: 'validate email',
+ content: `error: ${error_event}`,
+ target: `is invited: ${status?.isInvited}`,
+ });
+ return error;
+ };
+
+ return (
+ <>
+
+ {({ field, meta }: FieldProps) => {
+ const hasError = meta.touched && Boolean(meta.error);
+ return (
+
+
+
+ {hasError && (
+
+ {meta.error}
+
+ )}
+
+ );
+ }}
+
+
+
+ {({ field, meta }: FieldProps) => {
+ const hasError = meta.touched && Boolean(meta.error);
+ return (
+
+
+
+ ) : (
+
+ )
+ }
+ {...field}
+ placeholder={t('SIGNUP_FORM_PASSWORD_PLACEHOLDER')}
+ {...(hasError && { validation: 'error' })}
+ />
+ {hasError && (
+
+ {meta.error}
+
+ )}
+
+ );
+ }}
+
+
+
+
+
+
+
+ ),
+ }}
+ />
+
+
+
+
+ {t('SIGNUP_FORM_CTA_RETURN_TO_UNGUESS_LANDING')}
+
+
+ >
+ );
+};
diff --git a/src/pages/JoinPage/Steps/Step2.tsx b/src/pages/JoinPage/Steps/Step2.tsx
new file mode 100644
index 000000000..7b0d715ba
--- /dev/null
+++ b/src/pages/JoinPage/Steps/Step2.tsx
@@ -0,0 +1,170 @@
+import {
+ Button,
+ FormField,
+ Input,
+ Label,
+ Message,
+ Select,
+ Span,
+} from '@appquality/unguess-design-system';
+import { Field, FieldProps, useFormikContext } from 'formik';
+import { useEffect, useMemo, useRef } from 'react';
+import { useTranslation } from 'react-i18next';
+import { appTheme } from 'src/app/theme';
+import { useGetUsersRolesQuery } from 'src/features/api';
+import { useSendGTMevent } from 'src/hooks/useGTMevent';
+import { JoinFormValues } from '../valuesType';
+import { ButtonContainer } from './ButtonContainer';
+
+export const Step2 = () => {
+ const { setFieldValue, validateForm, setTouched, status } =
+ useFormikContext();
+ const { t } = useTranslation();
+ const sendGTMevent = useSendGTMevent();
+ const { data, isLoading } = useGetUsersRolesQuery();
+ const selectRef = useRef(null);
+
+ useEffect(() => {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${status?.isInvited}`,
+ content: 'step 2 rendered',
+ });
+ }, []);
+
+ const renderOptions = useMemo(
+ () =>
+ isLoading || !data ? (
+ loading...
+ ) : (
+ data?.map((role) => (
+
+ {role.name}
+
+ ))
+ ),
+ [data]
+ );
+ const goToNextStep = async () => {
+ await setTouched({
+ name: true,
+ surname: true,
+ roleId: true,
+ });
+ const errors = await validateForm();
+ if (Object.keys(errors).length > 0) {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${status?.isInvited}`,
+ action: 'step 2 validation error',
+ content: `error count: ${Object.keys(errors).length}`,
+ });
+ return;
+ }
+ setFieldValue('step', 3);
+ };
+ const goToPreviousStep = () => {
+ setFieldValue('step', 1);
+ };
+ return (
+ <>
+
+ {({ field, meta }: FieldProps) => {
+ const hasError = meta.touched && Boolean(meta.error);
+ return (
+
+
+
+ {hasError && (
+
+ {meta.error}
+
+ )}
+
+ );
+ }}
+
+
+ {({ field, meta }: FieldProps) => {
+ const hasError = meta.touched && Boolean(meta.error);
+ return (
+
+
+
+ {hasError && (
+
+ {meta.error}
+
+ )}
+
+ );
+ }}
+
+
+ {({ field, meta }: FieldProps) => {
+ const hasError = meta.touched && Boolean(meta.error);
+ return (
+
+
+ {hasError && (
+
+ {meta.error}
+
+ )}
+
+ );
+ }}
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/pages/JoinPage/Steps/Step3.tsx b/src/pages/JoinPage/Steps/Step3.tsx
new file mode 100644
index 000000000..abd257389
--- /dev/null
+++ b/src/pages/JoinPage/Steps/Step3.tsx
@@ -0,0 +1,68 @@
+import {
+ Button,
+ FormField,
+ Input,
+ Label,
+ Message,
+ Span,
+} from '@appquality/unguess-design-system';
+import { Field, FieldProps, useFormikContext } from 'formik';
+import { useTranslation } from 'react-i18next';
+import { appTheme } from 'src/app/theme';
+import { useSendGTMevent } from 'src/hooks/useGTMevent';
+import { JoinFormValues } from '../valuesType';
+import { ButtonContainer } from './ButtonContainer';
+import { useEffect } from 'react';
+
+export const Step3 = () => {
+ const { setFieldValue, values, status } = useFormikContext();
+ const { t } = useTranslation();
+ const sendGTMevent = useSendGTMevent();
+ useEffect(() => {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${status?.isInvited}`,
+ content: 'step 3 rendered',
+ });
+ }, []);
+ const goToPreviousStep = () => {
+ setFieldValue('step', 2);
+ };
+ return (
+ <>
+
+ {({ field, meta }: FieldProps) => {
+ const hasError = meta.touched && Boolean(meta.error);
+ return (
+
+
+
+ {hasError && (
+
+ {meta.error}
+
+ )}
+
+ );
+ }}
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/pages/JoinPage/WaitModal.tsx b/src/pages/JoinPage/WaitModal.tsx
new file mode 100644
index 000000000..7edf07625
--- /dev/null
+++ b/src/pages/JoinPage/WaitModal.tsx
@@ -0,0 +1,37 @@
+import { Modal, LG, XL, Skeleton } from '@appquality/unguess-design-system';
+import { Trans } from 'react-i18next';
+import { appTheme } from 'src/app/theme';
+
+export const WaitModal = () => (
+
+ ,
+ XL: (
+
+ ),
+ }}
+ />
+
+
+);
diff --git a/src/pages/JoinPage/index.tsx b/src/pages/JoinPage/index.tsx
new file mode 100644
index 000000000..3c72fbb83
--- /dev/null
+++ b/src/pages/JoinPage/index.tsx
@@ -0,0 +1,146 @@
+import { Col, Grid, Logo, Row } from '@appquality/unguess-design-system';
+import { useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
+import { useAppSelector } from 'src/app/hooks';
+import joinBg from 'src/assets/join-bg-1.png';
+import joingBgwebp from 'src/assets/join-bg-1.webp';
+import joinBg2 from 'src/assets/join-bg-2.png';
+import joinBg2webp from 'src/assets/join-bg-2.webp';
+import joinBg3 from 'src/assets/join-bg-3.png';
+import joinBg3webp from 'src/assets/join-bg-3.webp';
+import { GoogleTagManager } from 'src/common/GoogleTagManager';
+import { useGetInvitesByProfileAndTokenQuery } from 'src/features/api';
+import styled from 'styled-components';
+import { FormProvider } from './FormProvider';
+import { JoinForm } from './JoinForm';
+import { JoinPageError } from './JoinPageError';
+import { JoinPageLoading } from './JoinPageLoading';
+import { WaitModal } from './WaitModal';
+import { ImagesColumn } from './ImagesColumn';
+import { useSendGTMevent } from 'src/hooks/useGTMevent';
+
+const CenteredXYContainer = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ margin: 0 auto;
+ padding: 0 ${({ theme }) => theme.space.md};
+ max-width: ${({ theme }) => theme.breakpoints.md};
+ @media (min-width: ${({ theme }) => theme.breakpoints.xl}) {
+ padding: 0 ${({ theme }) => theme.space.xl};
+ max-width: ${({ theme }) => theme.breakpoints.xxl};
+ }
+`;
+
+const Background = styled.div<{ step: string }>`
+ // Default background
+ @media (min-width: ${({ theme }) => theme.breakpoints.xl}) {
+ ${({ step }) =>
+ step === '1' &&
+ `
+ background-image: url(${joinBg});
+ @supports (background-image: url(${joingBgwebp})) {
+ background-image: url(${joingBgwebp});
+ }
+ `}
+ ${({ step }) =>
+ step === '2' &&
+ `
+ background-image: url(${joinBg2});
+ @supports (background-image: url(${joinBg2webp})) {
+ background-image: url(${joinBg2webp});
+ }
+ `}
+ ${({ step }) =>
+ step === '3' &&
+ `
+ background-image: url(${joinBg3});
+ @supports (background-image: url(${joinBg3webp})) {
+ background-image: url(${joinBg3webp});
+ }
+ `}
+ background-repeat: no-repeat;
+ background-position: right top;
+ background-size: 61%;
+ }
+ position: relative;
+ width: 100%;
+ min-height: calc(100vh - ${({ theme }) => theme.space.xl} * 2);
+ padding: ${({ theme }) => theme.space.xl} 0 ${({ theme }) => theme.space.md};
+`;
+
+const StyledCol = styled(Col)`
+ margin-bottom: 0;
+`;
+
+const LogoWrapper = styled.div`
+ text-align: center;
+ margin-bottom: ${(p) => p.theme.space.lg};
+`;
+
+const JoinPage = () => {
+ const { t } = useTranslation();
+ const [searchParams] = useSearchParams();
+ const { status } = useAppSelector((state) => state.user);
+ const navigate = useNavigate();
+ const { profile, token } = useParams();
+ const sendGTMevent = useSendGTMevent();
+ const shouldSkipQuery =
+ status === 'logged' || status === 'loading' || !(profile && token);
+
+ const { isLoading, data, error } = useGetInvitesByProfileAndTokenQuery(
+ {
+ profile: profile || '',
+ token: token || '',
+ },
+ {
+ skip: shouldSkipQuery,
+ }
+ );
+
+ useEffect(() => {
+ if (status === 'logged') {
+ navigate(searchParams.get('redirectTo') || '/');
+ }
+ }, [navigate, status, searchParams]);
+
+ if (isLoading || (shouldSkipQuery && profile && token)) {
+ return ;
+ }
+
+ if (error) return ;
+
+ return (
+
+
+ {({ isSubmitting, values: { step } }) => (
+
+
+ {isSubmitting ? (
+
+ ) : (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
+ )}
+
+
+ );
+};
+
+export default JoinPage;
diff --git a/src/pages/JoinPage/useJoinSubmit.tsx b/src/pages/JoinPage/useJoinSubmit.tsx
new file mode 100644
index 000000000..2ccbd053c
--- /dev/null
+++ b/src/pages/JoinPage/useJoinSubmit.tsx
@@ -0,0 +1,122 @@
+import { Notification, useToast } from '@appquality/unguess-design-system';
+import { FormikHelpers } from 'formik';
+import { useCallback } from 'react';
+import { useParams, useSearchParams } from 'react-router-dom';
+import WPAPI from 'src/common/wpapi';
+import { usePostUsersMutation } from 'src/features/api';
+import { useSendGTMevent } from 'src/hooks/useGTMevent';
+import { JoinFormValues } from './valuesType';
+
+export function useJoinSubmit(isInvited: boolean) {
+ const [postFormValues] = usePostUsersMutation();
+ const { addToast } = useToast();
+ const [searchParams] = useSearchParams();
+ const redirectTo = searchParams.get('redirect');
+ const { token, profile } = useParams();
+ const sendGTMevent = useSendGTMevent();
+
+ const onSubmit = useCallback(
+ async (
+ values: JoinFormValues,
+ { setSubmitting }: FormikHelpers
+ ) => {
+ setSubmitting(true);
+ const basicInfo = {
+ email: values.email,
+ password: values.password,
+ name: values.name,
+ surname: values.surname,
+ roleId: values.roleId,
+ };
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${isInvited}`,
+ action: 'start submit',
+ content: `role: ${values.roleId}`,
+ });
+ try {
+ let res;
+ if (isInvited) {
+ if (!token || !profile)
+ throw new Error('Token or profile is missing');
+ res = await postFormValues({
+ body: {
+ type: 'invite',
+ ...basicInfo,
+ profileId: Number(profile),
+ token,
+ },
+ }).unwrap();
+ } else {
+ res = await postFormValues({
+ body: {
+ type: 'new',
+ ...basicInfo,
+ email: values.email,
+ workspace: values.workspace,
+ },
+ }).unwrap();
+ }
+ const nonce = await WPAPI.getNonce();
+ const login = await WPAPI.login({
+ username: values.email,
+ password: values.password,
+ security: nonce,
+ });
+
+ if (login) {
+ if (redirectTo) {
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${isInvited}`,
+ action: 'submit success',
+ content: 'redirect',
+ });
+ window.location.href = redirectTo;
+ } else if (res.projectId) {
+ document.location.href = `/projects/${res.projectId}`;
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${isInvited}`,
+ action: 'submit success',
+ content: 'project',
+ });
+ } else {
+ document.location.href = '/';
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${isInvited}`,
+ action: 'submit success',
+ content: 'home',
+ });
+ }
+ } else document.location.href = '/oops';
+ } catch (err) {
+ const message = `Error creating user: ${
+ err instanceof Error && err.message ? err.message : 'Unknown error'
+ }`;
+ sendGTMevent({
+ event: 'sign-up-flow',
+ category: `is invited: ${isInvited}`,
+ action: 'submit error',
+ content: message,
+ });
+ addToast(
+ ({ close }) => (
+
+ ),
+ { placement: 'top' }
+ );
+ }
+ setSubmitting(false);
+ },
+ [postFormValues, token, profile, isInvited]
+ );
+
+ return { onSubmit };
+}
diff --git a/src/pages/JoinPage/validationSchema.ts b/src/pages/JoinPage/validationSchema.ts
new file mode 100644
index 000000000..af4191c9e
--- /dev/null
+++ b/src/pages/JoinPage/validationSchema.ts
@@ -0,0 +1,51 @@
+import * as yup from 'yup';
+import { useTranslation } from 'react-i18next';
+
+export const useValidationSchema = () => {
+ const { t } = useTranslation();
+
+ return yup.object({
+ email: yup.string().when('step', {
+ is: 1,
+ then: yup
+ .string()
+ .required(t('SIGNUP_FORM_EMAIL_IS_REQUIRED'))
+ .email(t('SIGNUP_FORM_EMAIL_MUST_BE_A_VALID_EMAIL')),
+ }),
+ password: yup.string().when('step', {
+ is: 1,
+ then: yup
+ .string()
+ .min(6, t('SIGNUP_FORM_PASSWORD_MUST_BE_AT_LEAST_6_CHARACTER_LONG'))
+ .matches(
+ /[0-9]/,
+ t('SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_NUMBER')
+ )
+ .matches(
+ /[A-Z]/,
+ t('SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_AN_UPPERCASE_LETTER')
+ )
+ .matches(
+ /[a-z]/,
+ t('SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_LOWERCASE_LETTER')
+ )
+ .required(t('SIGNUP_FORM_PASSWORD_IS_A_REQUIRED_FIELD')),
+ }),
+ name: yup.string().when('step', {
+ is: 2,
+ then: yup.string().required(t('SIGNUP_FORM_NAME_IS_REQUIRED')),
+ }),
+ surname: yup.string().when('step', {
+ is: 2,
+ then: yup.string().required(t('SIGNUP_FORM_SURNAME_IS_REQUIRED')),
+ }),
+ roleId: yup.number().when('step', {
+ is: 2,
+ then: yup.number().positive(t('SIGNUP_FORM_ROLE_IS_REQUIRED')),
+ }),
+ workspace: yup.string().when('step', {
+ is: 3,
+ then: yup.string().required(t('SIGNUP_FORM_WORKSPACE_IS_REQUIRED')),
+ }),
+ });
+};
diff --git a/src/pages/JoinPage/valuesType.ts b/src/pages/JoinPage/valuesType.ts
new file mode 100644
index 000000000..44cac27c8
--- /dev/null
+++ b/src/pages/JoinPage/valuesType.ts
@@ -0,0 +1,9 @@
+export type JoinFormValues = {
+ step: number;
+ email: string;
+ password: string;
+ name: string;
+ surname: string;
+ workspace: string;
+ roleId: number;
+};
diff --git a/src/pages/LoginPage/index.tsx b/src/pages/LoginPage/index.tsx
index b05589f8d..17e6224ab 100644
--- a/src/pages/LoginPage/index.tsx
+++ b/src/pages/LoginPage/index.tsx
@@ -21,6 +21,8 @@ const StyledLogo = styled(Logo)`
const CenteredXYContainer = styled.div`
display: flex;
align-items: center;
+ justify-content: center;
+ text-align: center;
flex-direction: column;
height: 100vh;
@@ -99,8 +101,6 @@ const LoginPage = () => {
if (!values.password) {
errors.password = t('__FORM_FIELD_REQUIRED_MESSAGE');
- } else if (values.password.length < 5) {
- errors.password = t('__LOGIN_FORM_PASSWORD_FIELD_LENGTH_INVALID');
}
return errors;
diff --git a/tests/api/invites/profile/token/_get/200_Example_1.json b/tests/api/invites/profile/token/_get/200_Example_1.json
new file mode 100644
index 000000000..adf5c4c70
--- /dev/null
+++ b/tests/api/invites/profile/token/_get/200_Example_1.json
@@ -0,0 +1,6 @@
+{
+ "name": "John",
+ "surname": "Doe",
+ "email": "jhon.doe@example.com",
+ "workspace": "My new workspace"
+}
\ No newline at end of file
diff --git a/tests/api/plans/pid/_get/200_pending_review.json b/tests/api/plans/pid/_get/200_pending_review.json
new file mode 100644
index 000000000..a5c182490
--- /dev/null
+++ b/tests/api/plans/pid/_get/200_pending_review.json
@@ -0,0 +1,41 @@
+{
+ "id": 13,
+ "workspace_id": 1,
+ "status": "pending_review",
+ "project": {
+ "id": 90,
+ "name": "MyProject"
+ },
+ "config": {
+ "modules": [
+ {
+ "type": "title",
+ "variant": "default",
+ "output": "My Plan"
+ },
+ {
+ "type": "dates",
+ "variant": "default",
+ "output": {
+ "start": "2041-12-17T08:00:00.000Z"
+ }
+ },
+ {
+ "type": "tasks",
+ "variant": "default",
+ "output": [
+ {
+ "kind": "bug",
+ "title": "Search for bugs",
+ "description": "description kind bug"
+ },
+ {
+ "kind": "video",
+ "title": "Think aloud",
+ "description": "description kind video"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/tests/api/users/_post/200_Example_1.json b/tests/api/users/_post/200_Example_1.json
new file mode 100644
index 000000000..824b2d03c
--- /dev/null
+++ b/tests/api/users/_post/200_Example_1.json
@@ -0,0 +1,3 @@
+{
+ "workspaceId": 123
+}
diff --git a/tests/api/users/_post/200_projectId.json b/tests/api/users/_post/200_projectId.json
new file mode 100644
index 000000000..97b998b8e
--- /dev/null
+++ b/tests/api/users/_post/200_projectId.json
@@ -0,0 +1,4 @@
+{
+ "workspaceId": 1,
+ "projectId": 1
+}
diff --git a/tests/api/users/roles/_get/200_Example_1.json b/tests/api/users/roles/_get/200_Example_1.json
new file mode 100644
index 000000000..b8d0b4232
--- /dev/null
+++ b/tests/api/users/roles/_get/200_Example_1.json
@@ -0,0 +1,14 @@
+[
+ {
+ "id": 1,
+ "name": "Developer"
+ },
+ {
+ "id": 2,
+ "name": "Designer"
+ },
+ {
+ "id": 3,
+ "name": "Project Manager"
+ }
+]
diff --git a/tests/e2e/join/index.spec.ts b/tests/e2e/join/index.spec.ts
new file mode 100644
index 000000000..ba0629f12
--- /dev/null
+++ b/tests/e2e/join/index.spec.ts
@@ -0,0 +1,202 @@
+import { test, expect } from '../../fixtures/app';
+import { Join } from '../../fixtures/pages/Join';
+import { Step1 } from '../../fixtures/pages/Join/Step1';
+import { Step2 } from '../../fixtures/pages/Join/Step2';
+import { Step3 } from '../../fixtures/pages/Join/Step3';
+
+test.describe('The Join page first step - case new user', () => {
+ let join: Join;
+ let step1: Step1;
+ let step2: Step2;
+
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ step1 = new Step1(page);
+ step2 = new Step2(page);
+ await join.open();
+ });
+
+ test('display a form with user email and password input, a CTA to go to the next step', async () => {
+ await expect(step1.elements().container()).toBeVisible();
+ await expect(step1.elements().emailInput()).toBeVisible();
+ await expect(step1.elements().passwordInput()).toBeVisible();
+ await expect(step1.elements().buttonGoToStep2()).toBeVisible();
+ });
+
+ test('the password input check if the password is strong enough', async ({
+ page,
+ i18n,
+ }) => {
+ await step1.elements().buttonGoToStep2().click();
+ await expect(step1.elements().passwordError()).toHaveText(
+ i18n.t('SIGNUP_FORM_PASSWORD_IS_A_REQUIRED_FIELD')
+ );
+
+ await expect(step1.elements().passwordRequirements()).toBeVisible();
+
+ await step1.fillPassword('weak');
+ await expect(
+ page.getByText(
+ i18n.t('SIGNUP_FORM_PASSWORD_MUST_BE_AT_LEAST_6_CHARACTER_LONG')
+ )
+ ).toBeVisible();
+
+ await step1.fillPassword('weakpassword');
+ await expect(
+ page.getByText(
+ i18n.t('SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_NUMBER')
+ )
+ ).toBeVisible();
+
+ await step1.fillPassword('weakpassword123');
+ await expect(
+ page.getByText(
+ i18n.t('SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_AN_UPPERCASE_LETTER')
+ )
+ ).toBeVisible();
+
+ await step1.fillPassword('WEAKPASSWORD123');
+ await expect(
+ page.getByText(
+ i18n.t('SIGNUP_FORM_PASSWORD_MUST_CONTAIN_AT_LEAST_A_LOWERCASE_LETTER')
+ )
+ ).toBeVisible();
+
+ await step1.fillValidPassword();
+ await expect(page.getByTestId('message-error-password')).not.toBeVisible();
+ });
+
+ test('the email input check if the email is valid', async ({
+ page,
+ i18n,
+ }) => {
+ await step1.elements().buttonGoToStep2().click();
+ await expect(step1.elements().emailError()).toHaveText(
+ i18n.t('SIGNUP_FORM_EMAIL_IS_REQUIRED')
+ );
+ await step1.fillEmail('invalid-email');
+ await expect(
+ page.getByText(i18n.t('SIGNUP_FORM_EMAIL_MUST_BE_A_VALID_EMAIL'))
+ ).toBeVisible();
+
+ await step1.fillRegisteredEmail();
+ await expect(
+ page.getByText(i18n.t('SIGNUP_FORM_EMAIL_ALREADY_TAKEN'))
+ ).toBeVisible();
+
+ await step1.fillValidEmail();
+ await expect(page.getByTestId('message-error-email')).not.toBeVisible();
+ });
+
+ test('when the user click the next step cta we validate current inputs and if ok goes to the next step', async () => {
+ await step1.goToNextStep();
+ await expect(step1.elements().container()).not.toBeVisible();
+ await expect(step2.elements().container()).toBeVisible();
+ });
+ test('display two links to go to app.unguess and a link to terms and conditions', async () => {});
+});
+
+test.describe('The Join page second step', () => {
+ let join: Join;
+ let step1: Step1;
+ let step2: Step2;
+ let step3: Step3;
+
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ step1 = new Step1(page);
+ step2 = new Step2(page);
+ step3 = new Step3(page);
+
+ await step2.mockGetRoles();
+ await join.open();
+ await step1.goToNextStep();
+ });
+ test('display required inputs for name, surname and a job role dropdown populated from api userRole', async ({
+ i18n,
+ }) => {
+ await expect(step2.elements().nameInput()).toBeVisible();
+ await expect(step2.elements().surnameInput()).toBeVisible();
+ await expect(step2.elements().roleSelect()).toBeVisible();
+ await step2.elements().roleSelect().click();
+ await expect(step2.elements().roleSelectOptions()).toHaveCount(3);
+ await step2.elements().buttonGoToStep3().click();
+ await expect(step2.elements().nameError()).toHaveText(
+ i18n.t('SIGNUP_FORM_NAME_IS_REQUIRED')
+ );
+ await expect(step2.elements().surnameError()).toHaveText(
+ i18n.t('SIGNUP_FORM_SURNAME_IS_REQUIRED')
+ );
+ await expect(step2.elements().roleSelectError()).toHaveText(
+ i18n.t('SIGNUP_FORM_ROLE_IS_REQUIRED')
+ );
+ await step2.fillValidFields();
+ await expect(step2.elements().nameError()).not.toBeVisible();
+ await expect(step2.elements().surnameError()).not.toBeVisible();
+ await expect(step2.elements().roleSelectError()).not.toBeVisible();
+ });
+ test('display back and next navigation, clicking on next validate this step and goes to step 3', async () => {
+ await expect(step2.elements().buttonBackToStep1()).toBeVisible();
+ await expect(step2.elements().buttonGoToStep3()).toBeVisible();
+ await step2.goToNextStep();
+ await expect(step2.elements().container()).not.toBeVisible();
+ await expect(step3.elements().container()).toBeVisible();
+ });
+});
+
+test.describe('The Join page third step', () => {
+ let join: Join;
+ let step1: Step1;
+ let step2: Step2;
+ let step3: Step3;
+
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ step1 = new Step1(page);
+ step2 = new Step2(page);
+ step3 = new Step3(page);
+
+ await join.open();
+ await join.mockPostNewUser();
+ await step1.goToNextStep();
+ await step2.goToNextStep();
+ });
+ test('display a required text input for the workspace name and a back button to return to step 2', async () => {
+ await expect(step3.elements().workspaceInput()).toBeVisible();
+ await expect(step3.elements().buttonBackToStep2()).toBeVisible();
+ await step3.elements().buttonBackToStep2().click();
+ await expect(step3.elements().container()).not.toBeVisible();
+ await expect(step2.elements().container()).toBeVisible();
+ });
+ test('display a submit-button, clicking on submit-button validate the whole form and calls the api post', async ({
+ page,
+ i18n,
+ }) => {
+ const postPromise = page.waitForResponse(
+ (response) =>
+ /\/api\/users/.test(response.url()) &&
+ response.status() === 200 &&
+ response.request().method() === 'POST'
+ );
+ await step3.elements().buttonSubmit().click();
+ await expect(step3.elements().workspaceError()).toHaveText(
+ i18n.t('SIGNUP_FORM_WORKSPACE_IS_REQUIRED')
+ );
+ await step3.fillValidWorkspace();
+ await expect(step3.elements().workspaceError()).not.toBeVisible();
+ await step3.elements().buttonSubmit().click();
+ const response = await postPromise;
+ const data = response.request().postDataJSON();
+ expect(data).toEqual(
+ expect.objectContaining({
+ type: 'new',
+ email: 'new.user@example.com',
+ password: 'ValidPassword123',
+ name: step2.name,
+ surname: step2.surname,
+ roleId: step2.roleId,
+ workspace: step3.workspace,
+ })
+ );
+ });
+});
diff --git a/tests/e2e/join/invited-user.spec.ts b/tests/e2e/join/invited-user.spec.ts
new file mode 100644
index 000000000..6f9876bf5
--- /dev/null
+++ b/tests/e2e/join/invited-user.spec.ts
@@ -0,0 +1,110 @@
+import { test, expect } from '../../fixtures/app';
+import { Join } from '../../fixtures/pages/Join';
+import { Step1 } from '../../fixtures/pages/Join/Step1';
+import { Step2 } from '../../fixtures/pages/Join/Step2';
+import { Step3 } from '../../fixtures/pages/Join/Step3';
+
+test.describe('The Join page if the get invites respond 400', () => {
+ let join: Join;
+
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ await join.mockGetInvitedUserError();
+ await page.goto(join.urlInvitedUser);
+ });
+ test('should render an error state', async () => {
+ await expect(join.elements().errorState()).toBeVisible();
+ });
+});
+
+test.describe('The Join page first step - case valid invited user only', () => {
+ let join: Join;
+ let step1: Step1;
+
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ step1 = new Step1(page);
+
+ await join.mockGetInvitedUser();
+ await page.goto(join.urlInvitedUser);
+ });
+
+ test('before rendering page evaluate invited parameters from the url', async ({
+ page,
+ }) => {
+ const getPromise = page.waitForResponse(
+ (response) =>
+ response
+ .url()
+ .includes(`api/invites/${join.profileId}/${join.token}`) &&
+ response.status() === 200 &&
+ response.request().method() === 'GET'
+ );
+ await page.goto(join.urlInvitedUser);
+
+ const response = await getPromise;
+ expect(response).toBeDefined();
+ });
+
+ test('the email input, is precompiled (with invited user email from api) and disabled', async () => {
+ await expect(step1.elements().emailInput()).toBeDisabled();
+ await expect(step1.elements().emailInput()).toHaveValue(
+ join.validInvitedUser.email
+ );
+ });
+});
+
+test.describe('The Join page second step - case invited user only', () => {
+ let join: Join;
+ let step2: Step2;
+ let step1: Step1;
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ step2 = new Step2(page);
+ step1 = new Step1(page);
+
+ await join.mockGetInvitedUser();
+ await step2.mockGetRoles();
+ await page.goto(join.urlInvitedUser);
+ await step1.goToNextStepAsInvitedUser();
+ });
+ test('display two inputs for name and surname precopiled if present in api response', async () => {
+ await expect(step2.elements().nameInput()).toBeEnabled();
+ await expect(step2.elements().nameInput()).toHaveValue(
+ join.validInvitedUser.name
+ );
+ await expect(step2.elements().surnameInput()).toBeEnabled();
+ await expect(step2.elements().surnameInput()).toHaveValue(
+ join.validInvitedUser.surname
+ );
+ });
+});
+
+test.describe('The Join page third step - case invited user only', () => {
+ let join: Join;
+ let step1: Step1;
+ let step2: Step2;
+ let step3: Step3;
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+ step2 = new Step2(page);
+ step1 = new Step1(page);
+ step3 = new Step3(page);
+
+ await join.mockGetInvitedUser();
+ await step2.mockGetRoles();
+ await page.goto(join.urlInvitedUser);
+ await step1.goToNextStepAsInvitedUser();
+ await step2.elements().roleSelect().click();
+ await step2.elements().roleSelectOptions().first().click();
+ await step2.elements().buttonGoToStep3().click();
+ });
+
+ test('display the workspace name input precompiled from api and disabled', async () => {
+ await expect(step3.elements().workspaceInput()).not.toBeEnabled();
+ await expect(step3.elements().workspaceInput()).toHaveValue(
+ join.validInvitedUser.workspace
+ );
+ });
+ test('the POST should NOT answer with a projectId therefore submitting the form redirect to the homepage', async () => {});
+});
diff --git a/tests/e2e/join/logged-in-user.spec.ts b/tests/e2e/join/logged-in-user.spec.ts
new file mode 100644
index 000000000..0c91be9f1
--- /dev/null
+++ b/tests/e2e/join/logged-in-user.spec.ts
@@ -0,0 +1,28 @@
+import { test, expect } from '../../fixtures/app';
+import { Join } from '../../fixtures/pages/Join';
+
+test.describe('The Join page - already logged in user:', () => {
+ let join: Join;
+
+ test.beforeEach(async ({ page }) => {
+ join = new Join(page);
+
+ await join.loggedIn();
+ await join.mockPreferences();
+ await join.mockWorkspace();
+ await join.mockWorkspacesList();
+ await join.mockExperientialCampaign();
+ });
+ test('If there is not a query parameter redirectTo the user is redirected to home', async ({
+ page,
+ }) => {
+ await join.open();
+ await expect(page).toHaveURL('/');
+ });
+ test('If there is a query parameter redirectTo, the user is redirected to a specific page', async ({
+ page,
+ }) => {
+ await page.goto('/join?redirectTo=/campaigns/1');
+ await expect(page).toHaveURL('/campaigns/1');
+ });
+});
diff --git a/tests/fixtures/pages/Join/Step1.ts b/tests/fixtures/pages/Join/Step1.ts
new file mode 100644
index 000000000..dec48ac2d
--- /dev/null
+++ b/tests/fixtures/pages/Join/Step1.ts
@@ -0,0 +1,103 @@
+import { Page } from '@playwright/test';
+import { i18n } from 'i18next';
+import { getI18nInstance } from 'playwright-i18next-fixture';
+
+export class Step1 {
+ readonly page: Page;
+
+ readonly i18n: i18n;
+
+ constructor(page: Page) {
+ this.page = page;
+ this.i18n = getI18nInstance() as unknown as i18n;
+ }
+
+ elements() {
+ return {
+ container: () => this.page.getByTestId('step-1'),
+ emailInput: () => this.page.getByRole('textbox', { name: 'Email' }),
+ emailError: () => this.page.getByTestId('message-error-email'),
+ passwordInput: () => this.page.getByRole('textbox', { name: 'Password' }),
+ passwordError: () => this.page.getByTestId('message-error-password'),
+ buttonGoToStep2: () =>
+ this.page.getByRole('button', {
+ name: this.i18n.t('SIGNUP_FORM_GO_TO_STEP_2'),
+ }),
+ passwordRequirements: () =>
+ this.page.getByTestId('password-requirements'),
+ termsLink: () => this.page.getByTestId('terms-and-conditions'),
+ };
+ }
+
+ expectToBeVisible() {
+ const tab = this.elements().container();
+ return tab.isVisible();
+ }
+
+ async goToNextStep() {
+ await this.fillValidEmail();
+ await this.fillValidPassword();
+ await this.elements().buttonGoToStep2().click();
+ }
+
+ async fillPassword(pass: string) {
+ const passwordInput = this.elements().passwordInput();
+ await passwordInput.fill(pass);
+ await passwordInput.blur();
+ }
+
+ async goToNextStepAsInvitedUser() {
+ await this.fillValidPassword();
+ await this.elements().buttonGoToStep2().click();
+ }
+
+ async fillValidPassword() {
+ const passwordInput = this.elements().passwordInput();
+ await passwordInput.fill('ValidPassword123');
+ await passwordInput.blur();
+ }
+
+ async fillEmail(email: string) {
+ const emailInput = this.elements().emailInput();
+ await emailInput.fill(email);
+ await emailInput.blur();
+ }
+
+ async fillRegisteredEmail() {
+ await this.mockMailExist();
+ const emailInput = this.elements().emailInput();
+ await emailInput.fill('user.registerd@example.com');
+ await emailInput.blur();
+ }
+
+ async fillValidEmail() {
+ await this.mockMailDoesNotExist();
+ const emailInput = this.elements().emailInput();
+ await emailInput.fill('new.user@example.com');
+ await emailInput.blur();
+ }
+
+ async mockMailExist() {
+ await this.page.route(
+ `*/**/api/users/by-email/user.registerd@example.com`,
+ async (route) => {
+ await route.fulfill({
+ body: '{}',
+ status: 200,
+ });
+ }
+ );
+ }
+
+ async mockMailDoesNotExist() {
+ await this.page.route(
+ `*/**/api/users/by-email/new.user@example.com`,
+ async (route) => {
+ await route.fulfill({
+ body: '{}',
+ status: 404,
+ });
+ }
+ );
+ }
+}
diff --git a/tests/fixtures/pages/Join/Step2.ts b/tests/fixtures/pages/Join/Step2.ts
new file mode 100644
index 000000000..4cd71030b
--- /dev/null
+++ b/tests/fixtures/pages/Join/Step2.ts
@@ -0,0 +1,65 @@
+import { Page } from '@playwright/test';
+import { i18n } from 'i18next';
+import { getI18nInstance } from 'playwright-i18next-fixture';
+import roles from '../../../api/users/roles/_get/200_Example_1.json';
+
+export class Step2 {
+ readonly page: Page;
+
+ readonly i18n: i18n;
+
+ readonly name = 'John';
+
+ readonly surname = 'Doe';
+
+ readonly roleId = roles[0].id;
+
+ constructor(page: Page) {
+ this.page = page;
+ this.i18n = getI18nInstance() as unknown as i18n;
+ }
+
+ elements() {
+ return {
+ container: () => this.page.getByTestId('step-2'),
+ nameInput: () =>
+ this.page.getByLabel(this.i18n.t('SIGNUP_FORM_NAME_LABEL')),
+ nameError: () => this.page.getByTestId('signup-name-error'),
+ surnameInput: () =>
+ this.page.getByLabel(this.i18n.t('SIGNUP_FORM_SURNAME_LABEL')),
+ surnameError: () => this.page.getByTestId('signup-surname-error'),
+ roleSelect: () => this.page.getByTestId('roleId-select'),
+ roleSelectOptions: () => this.elements().roleSelect().getByRole('option'),
+ roleSelectError: () => this.page.getByTestId('signup-role-error'),
+ buttonBackToStep1: () =>
+ this.page.getByRole('button', {
+ name: this.i18n.t('SIGNUP_FORM_RETURN_TO_STEP_1'),
+ }),
+ buttonGoToStep3: () =>
+ this.page.getByRole('button', {
+ name: this.i18n.t('SIGNUP_FORM_GO_TO_STEP_3'),
+ }),
+ };
+ }
+
+ async fillValidFields() {
+ await this.elements().roleSelect().click();
+ await this.elements().roleSelectOptions().first().click();
+ await this.elements().surnameInput().fill(this.surname);
+ await this.elements().nameInput().fill(this.name);
+ await this.elements().nameInput().blur();
+ }
+
+ async goToNextStep() {
+ await this.fillValidFields();
+ await this.elements().buttonGoToStep3().click();
+ }
+
+ async mockGetRoles() {
+ await this.page.route('*/**/api/users/roles', async (route) => {
+ await route.fulfill({
+ path: 'tests/api/users/roles/_get/200_Example_1.json',
+ });
+ });
+ }
+}
diff --git a/tests/fixtures/pages/Join/Step3.ts b/tests/fixtures/pages/Join/Step3.ts
new file mode 100644
index 000000000..8b11244be
--- /dev/null
+++ b/tests/fixtures/pages/Join/Step3.ts
@@ -0,0 +1,38 @@
+import { Page } from '@playwright/test';
+import { i18n } from 'i18next';
+import { getI18nInstance } from 'playwright-i18next-fixture';
+
+export class Step3 {
+ readonly page: Page;
+
+ readonly i18n: i18n;
+
+ readonly workspace = 'Test Workspace';
+
+ constructor(page: Page) {
+ this.page = page;
+ this.i18n = getI18nInstance() as unknown as i18n;
+ }
+
+ elements() {
+ return {
+ container: () => this.page.getByTestId('step-3'),
+ workspaceInput: () =>
+ this.page.getByRole('textbox', { name: 'workspace' }),
+ workspaceError: () => this.page.getByTestId('signup-workspace-error'),
+ buttonBackToStep2: () =>
+ this.page.getByRole('button', {
+ name: this.i18n.t('SIGNUP_FORM_RETURN_TO_STEP_2'),
+ }),
+ buttonSubmit: () =>
+ this.page.getByRole('button', {
+ name: this.i18n.t('SIGNUP_FORM_SUBMIT'),
+ }),
+ };
+ }
+
+ async fillValidWorkspace() {
+ await this.elements().workspaceInput().fill(this.workspace);
+ await this.elements().workspaceInput().blur();
+ }
+}
diff --git a/tests/fixtures/pages/Join/index.ts b/tests/fixtures/pages/Join/index.ts
new file mode 100644
index 000000000..4a06a2942
--- /dev/null
+++ b/tests/fixtures/pages/Join/index.ts
@@ -0,0 +1,86 @@
+import { type Page } from '@playwright/test';
+import { UnguessPage } from '../../UnguessPage';
+import validInvitedUser from '../../../api/invites/profile/token/_get/200_Example_1.json';
+
+export class Join extends UnguessPage {
+ readonly page: Page;
+
+ readonly url = '/join';
+
+ readonly profileId = '1';
+
+ readonly token = 'token123';
+
+ readonly urlInvitedUser = `${this.url}/invites/${this.profileId}/${this.token}`;
+
+ readonly validInvitedUser = validInvitedUser;
+
+ constructor(page: Page) {
+ super(page);
+ this.page = page;
+ }
+
+ elements() {
+ return {
+ ...super.elements(),
+ loader: () => this.page.getByTestId('join-page-loader'),
+ errorState: () => this.page.getByTestId('join-page-error'),
+ };
+ }
+
+ async mockGetInvitedUser() {
+ await this.page.route(
+ `*/**/api/invites/${this.profileId}/${this.token}`,
+ async (route) => {
+ if (route.request().method() === 'GET') {
+ await route.fulfill({
+ path: 'tests/api/invites/profile/token/_get/200_Example_1.json',
+ });
+ } else {
+ await route.fallback();
+ }
+ }
+ );
+ }
+
+ async mockGetInvitedUserError() {
+ await this.page.route(
+ `*/**/api/invites/${this.profileId}/${this.token}`,
+ async (route) => {
+ if (route.request().method() === 'GET') {
+ await route.fulfill({
+ status: 400,
+ });
+ } else {
+ await route.fallback();
+ }
+ }
+ );
+ }
+
+ // new user response has a welcome project id for the redirect
+ async mockPostNewUser() {
+ await this.page.route(`*/**/api/users`, async (route) => {
+ if (route.request().method() === 'POST') {
+ await route.fulfill({
+ path: 'tests/api/users/_post/200_projectId.json',
+ });
+ } else {
+ await route.fallback();
+ }
+ });
+ }
+
+ // existing user response has no project id
+ async mockPostExistingUser() {
+ await this.page.route(`*/**/api/users`, async (route) => {
+ if (route.request().method() === 'POST') {
+ await route.fulfill({
+ path: 'tests/api/users/_post/200_Example_1.json',
+ });
+ } else {
+ await route.fallback();
+ }
+ });
+ }
+}
diff --git a/yarn.lock b/yarn.lock
index 8fb6399f6..98574dacb 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4628,6 +4628,15 @@ formik@^2.2.9:
tiny-warning "^1.0.2"
tslib "^2.0.0"
+framer-motion@^12.15.0:
+ version "12.15.0"
+ resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.15.0.tgz#6892283fc7967b071f537d6d160ab49e3d5e73ae"
+ integrity sha512-XKg/LnKExdLGugZrDILV7jZjI599785lDIJZLxMiiIFidCsy0a4R2ZEf+Izm67zyOuJgQYTHOmodi7igQsw3vg==
+ dependencies:
+ motion-dom "^12.15.0"
+ motion-utils "^12.12.1"
+ tslib "^2.4.0"
+
fs-extra@9.1.0:
version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
@@ -6059,6 +6068,26 @@ modern-normalize@^2.0.0:
resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-2.0.0.tgz#3d04ed01c81a3d4e0a0fd9ceba6abd1b16f5964b"
integrity sha512-CxBoEVKh5U4DH3XuNbc5ONLF6dQBc8dSc7pdZ1957FGbIO5JBqGqqchhET9dTexri8/pk9xBL6+5ceOtCIp1QA==
+motion-dom@^12.15.0:
+ version "12.15.0"
+ resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.15.0.tgz#eca7c9d8c28976b8c920f175f92d5288f5a17785"
+ integrity sha512-D2ldJgor+2vdcrDtKJw48k3OddXiZN1dDLLWrS8kiHzQdYVruh0IoTwbJBslrnTXIPgFED7PBN2Zbwl7rNqnhA==
+ dependencies:
+ motion-utils "^12.12.1"
+
+motion-utils@^12.12.1:
+ version "12.12.1"
+ resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.12.1.tgz#63e28751325cb9d1cd684f3c273a570022b0010e"
+ integrity sha512-f9qiqUHm7hWSLlNW8gS9pisnsN7CRFRD58vNjptKdsqFLpkVnX00TNeD6Q0d27V9KzT7ySFyK1TZ/DShfVOv6w==
+
+motion@^12.15.0:
+ version "12.15.0"
+ resolved "https://registry.yarnpkg.com/motion/-/motion-12.15.0.tgz#dbfc09a0c3c60e9b40aa5f2f855a8822bb5d36de"
+ integrity sha512-HLouXyIb1uQFiZgJTYGrtEzbatPc6vK+HP+Qt6afLQjaudiGiLLVsoy71CwzD/Stlh06FUd5OpyiXqn6XvqjqQ==
+ dependencies:
+ framer-motion "^12.15.0"
+ tslib "^2.4.0"
+
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -8199,7 +8228,7 @@ tslib@^1.8.1:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
-tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.6.2:
+tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.2:
version "2.8.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==