From 9904d369228f757f3a7790b451c5b90f7236e95b Mon Sep 17 00:00:00 2001 From: ZecD Date: Mon, 30 Jun 2025 17:06:19 +0200 Subject: [PATCH 1/6] Add AiSuggestion and AiScore components for displaying AI review status and scores - Implemented AiSuggestion component to fetch and display AI review status with styled indication based on status (approved, refused, need review). - Implemented AiScore component to fetch and display AI score percentage with styled indication based on score range. - Both components utilize the useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery for data retrieval. --- src/pages/BugsList/Table/AISuggestion.tsx | 38 + src/pages/BugsList/Table/AiScore.tsx | 34 + src/pages/BugsList/Table/index.tsx | 20 + src/services/tryberApi/index.ts | 21 + src/utils/schema.ts | 1872 +++++++++++---------- 5 files changed, 1068 insertions(+), 917 deletions(-) create mode 100644 src/pages/BugsList/Table/AISuggestion.tsx create mode 100644 src/pages/BugsList/Table/AiScore.tsx diff --git a/src/pages/BugsList/Table/AISuggestion.tsx b/src/pages/BugsList/Table/AISuggestion.tsx new file mode 100644 index 00000000..75a9b3e0 --- /dev/null +++ b/src/pages/BugsList/Table/AISuggestion.tsx @@ -0,0 +1,38 @@ +import { useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery } from "src/services/tryberApi"; +import styled from "styled-components"; + +const StyledSuggestion = styled.span<{ suggestion: string }>` + ${({ suggestion }) => suggestion === "refused" && `color: #800208;`} + ${({ suggestion }) => suggestion === "need_review" && `color: #C78430;`} + ${({ suggestion }) => suggestion === "approved" && `color: #02807A;`} + text-transform: capitalize; +`; + +const AiSuggestion = ({ + campaignId, + bugId, +}: { + campaignId: string; + bugId: number; +}) => { + const { data, isError } = useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery({ + campaign: campaignId, + bugId: bugId.toString(), + }); + const labelMap: Record = { + approved: "Approved", + refused: "Refused", + need_review: "Need Review", + }; + + if (!data || isError) { + return null; + } + const label = labelMap[data.ai_status] || data.ai_status; + + return ( + {label} + ); +}; + +export default AiSuggestion; diff --git a/src/pages/BugsList/Table/AiScore.tsx b/src/pages/BugsList/Table/AiScore.tsx new file mode 100644 index 00000000..c732d572 --- /dev/null +++ b/src/pages/BugsList/Table/AiScore.tsx @@ -0,0 +1,34 @@ +import { useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery } from "src/services/tryberApi"; +import styled from "styled-components"; + +const StyledScore = styled.span<{ score: number }>` + ${({ score }) => score < 40 && `color: #800208;`} + ${({ score }) => score >= 40 && score < 60 && `color: #C78430;`} + ${({ score }) => score >= 60 && `color: #02807A;`} + text-transform: capitalize; +`; + +const AiScore = ({ + campaignId, + bugId, +}: { + campaignId: string; + bugId: number; +}) => { + const { data, isError } = useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery({ + campaign: campaignId, + bugId: bugId.toString(), + }); + + if (!data || isError) { + return null; + } + + return ( + + {data?.score_percentage}% + + ); +}; + +export default AiScore; diff --git a/src/pages/BugsList/Table/index.tsx b/src/pages/BugsList/Table/index.tsx index c8ddbb6e..4448e1a3 100644 --- a/src/pages/BugsList/Table/index.tsx +++ b/src/pages/BugsList/Table/index.tsx @@ -13,6 +13,8 @@ import { useFiltersCardContext } from "../FilterContext"; import Button from "./TableButton"; import Severity from "./Severity"; import Type from "./Type"; +import AiSuggestion from "./AISuggestion"; +import AiScore from "./AiScore"; const LIMIT = 100; @@ -80,6 +82,12 @@ const BugsTable = ({ id }: { id: string }) => { title: r.severity.name, content: , }, + ai_suggestion: { + content: , + }, + score: { + content: , + }, status: { title: r.status.name, content: r.status.name, @@ -135,6 +143,18 @@ const BugsTable = ({ id }: { id: string }) => { dataIndex: "title", key: "title", }, + { + title: "AI Suggestion", + dataIndex: "ai_suggestion", + key: "ai_suggestion", + maxWidth: "15ch", + }, + { + title: "Score", + dataIndex: "score", + key: "score", + maxWidth: "10ch", + }, { title: "Status", dataIndex: "status", diff --git a/src/services/tryberApi/index.ts b/src/services/tryberApi/index.ts index 332e3db1..1328abf8 100644 --- a/src/services/tryberApi/index.ts +++ b/src/services/tryberApi/index.ts @@ -189,6 +189,14 @@ const injectedRtkApi = api.injectEndpoints({ url: `/campaigns/${queryArg.campaign}/bugs/${queryArg.bugId}`, }), }), + getCampaignsByCampaignBugsAndBugIdAiReview: build.query< + GetCampaignsByCampaignBugsAndBugIdAiReviewApiResponse, + GetCampaignsByCampaignBugsAndBugIdAiReviewApiArg + >({ + query: (queryArg) => ({ + url: `/campaigns/${queryArg.campaign}/bugs/${queryArg.bugId}/aiReview`, + }), + }), getCampaignsByCampaignCandidates: build.query< GetCampaignsByCampaignCandidatesApiResponse, GetCampaignsByCampaignCandidatesApiArg @@ -1380,6 +1388,18 @@ export type GetCampaignsByCampaignBugsAndBugIdApiArg = { campaign: string; bugId: string; }; +export type GetCampaignsByCampaignBugsAndBugIdAiReviewApiResponse = + /** status 200 OK */ { + ai_status: string; + ai_reason: string; + score_percentage: number; + ai_notes?: string; + }; +export type GetCampaignsByCampaignBugsAndBugIdAiReviewApiArg = { + /** A campaign id */ + campaign: string; + bugId: string; +}; export type GetCampaignsByCampaignCandidatesApiResponse = /** status 200 OK */ { results?: { age: number; @@ -3241,6 +3261,7 @@ export const { usePutCampaignsByCampaignMutation, useGetCampaignsByCampaignBugsQuery, useGetCampaignsByCampaignBugsAndBugIdQuery, + useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery, useGetCampaignsByCampaignCandidatesQuery, usePostCampaignsByCampaignCandidatesMutation, useGetCampaignsByCampaignClustersQuery, diff --git a/src/utils/schema.ts b/src/utils/schema.ts index 4b7430e2..c3334e69 100644 --- a/src/utils/schema.ts +++ b/src/utils/schema.ts @@ -44,12 +44,35 @@ export interface paths { }; }; }; + "/campaignTypes": { + get: operations["get-campaign-types"]; + parameters: {}; + }; "/campaigns": { /** Get all the Campaigns you have access to */ get: operations["get-campaigns"]; /** Create a new Campaign if you have access to the creation */ post: operations["post-campaigns"]; }; + "/campaigns/forms": { + get: operations["get-campaigns-forms"]; + post: operations["post-campaigns-forms"]; + parameters: {}; + }; + "/campaigns/forms/{formId}": { + get: operations["get-campaigns-forms-formId"]; + put: operations["put-campaigns-forms-formId"]; + parameters: { + path: { + formId: string; + }; + }; + }; + "/campaigns/owners": { + /** Get all the owners of campaigns you have access to */ + get: operations["get-campaigns-owners"]; + parameters: {}; + }; "/campaigns/{campaign}": { /** Get the data of a Campaign if you have access to it */ get: operations["get-campaigns-campaign"]; @@ -83,6 +106,17 @@ export interface paths { }; }; }; + "/campaigns/{campaign}/bugs/{bugId}/aiReview": { + /** Get ai review for a single bug of a Campaign if you have access to it */ + get: operations["get-campaigns-single-bug-ai-review"]; + parameters: { + path: { + /** A campaign id */ + campaign: string; + bugId: string; + }; + }; + }; "/campaigns/{campaign}/candidates": { get: operations["get-campaigns-campaign-candidates"]; /** The Tryber will be inserted as a candidate Tryber on a specific Campaign */ @@ -207,29 +241,6 @@ export interface paths { }; }; }; - "/campaigns/forms": { - get: operations["get-campaigns-forms"]; - post: operations["post-campaigns-forms"]; - parameters: {}; - }; - "/campaigns/forms/{formId}": { - get: operations["get-campaigns-forms-formId"]; - put: operations["put-campaigns-forms-formId"]; - parameters: { - path: { - formId: string; - }; - }; - }; - "/campaigns/owners": { - /** Get all the owners of campaigns you have access to */ - get: operations["get-campaigns-owners"]; - parameters: {}; - }; - "/campaignTypes": { - get: operations["get-campaign-types"]; - parameters: {}; - }; "/certifications": { /** Get all certificatio */ get: operations["get-certifications"]; @@ -243,6 +254,10 @@ export interface paths { }; }; }; + "/custom_user_fields": { + get: operations["get-customUserFields"]; + parameters: {}; + }; "/customers": { /** Get all the customers you have access to */ get: operations["get-customers"]; @@ -258,10 +273,6 @@ export interface paths { }; }; }; - "/custom_user_fields": { - get: operations["get-customUserFields"]; - parameters: {}; - }; "/devices/{device_type}/models": { /** Get all model of devices with theirs manufacturers */ get: operations["get-devices-devices-type-model"]; @@ -303,6 +314,15 @@ export interface paths { }; }; }; + "/dossiers/{campaign}/manual": { + post: operations["post-dossiers-campaign-manual"]; + parameters: { + path: { + /** A campaign id */ + campaign: components["parameters"]["campaign"]; + }; + }; + }; "/dossiers/{campaign}/phases": { put: operations["put-dossiers-campaign-phases"]; parameters: { @@ -312,6 +332,15 @@ export interface paths { }; }; }; + "/dossiers/{campaign}/preview": { + post: operations["post-dossiers-campaign-preview"]; + parameters: { + path: { + /** A campaign id */ + campaign: components["parameters"]["campaign"]; + }; + }; + }; "/dossiers/{campaign}/quotations": { post: operations["post-dossiers-campaign-quotations"]; parameters: { @@ -348,15 +377,6 @@ export interface paths { /** Get all employments */ get: operations["get-employments"]; }; - "/jotforms/{campaign}": { - post: operations["post-jotforms-campaignId"]; - parameters: { - path: { - /** A campaign id */ - campaign: string; - }; - }; - }; "/jotforms/forms": { get: operations["get-jotforms"]; parameters: {}; @@ -369,6 +389,15 @@ export interface paths { }; }; }; + "/jotforms/{campaign}": { + post: operations["post-jotforms-campaignId"]; + parameters: { + path: { + /** A campaign id */ + campaign: string; + }; + }; + }; "/languages": { /** Get all languages */ get: operations["get-languages"]; @@ -488,15 +517,6 @@ export interface paths { }; }; }; - "/users/me/campaigns/{campaign}/compatible_devices": { - get: operations["get-users-me-campaigns-campaignId-compatible-devices"]; - parameters: { - path: { - /** A campaign id */ - campaign: string; - }; - }; - }; "/users/me/campaigns/{campaignId}/bugs": { /** Send a user bug on a specific campaign */ post: operations["post-users-me-campaigns-campaign-bugs"]; @@ -532,6 +552,15 @@ export interface paths { }; }; }; + "/users/me/campaigns/{campaign}/compatible_devices": { + get: operations["get-users-me-campaigns-campaignId-compatible-devices"]; + parameters: { + path: { + /** A campaign id */ + campaign: string; + }; + }; + }; "/users/me/certifications": { /** Add one certification to your profile */ post: operations["post-users-me-certifications"]; @@ -638,52 +667,34 @@ export interface paths { "/users/me/rank/list": { get: operations["get-users-me-rank-list"]; }; - "/dossiers/{campaign}/manual": { - post: operations["post-dossiers-campaign-manual"]; - parameters: { - path: { - /** A campaign id */ - campaign: components["parameters"]["campaign"]; - }; - }; - }; - "/dossiers/{campaign}/preview": { - post: operations["post-dossiers-campaign-preview"]; - parameters: { - path: { - /** A campaign id */ - campaign: components["parameters"]["campaign"]; - }; - }; - }; } export interface components { schemas: { AdditionalField: { field_id: number; + is_candidate?: boolean; name: string; - value: string; text?: string; - is_candidate?: boolean; + value: string; }; Agreement: { - title: string; - tokens: number; - unitPrice: number; - startDate: string; expirationDate: string; - note?: string; /** @default false */ isTokenBased?: boolean; + note?: string; + startDate: string; + title: string; + tokens: number; + unitPrice: number; }; /** Bug */ Bug: { - severity?: components["schemas"]["BugSeverity"]; - status?: components["schemas"]["BugStatus"]; campaign?: components["schemas"]["CampaignOptional"] & { id?: number; }; + severity?: components["schemas"]["BugSeverity"]; + status?: components["schemas"]["BugStatus"]; title?: string; }; /** BugSeverity */ @@ -693,9 +704,9 @@ export interface components { }; /** BugStatus */ BugStatus: { + description?: string; id?: number; name?: string; - description?: string; }; /** BugTag */ BugTag: { @@ -710,19 +721,19 @@ export interface components { components["schemas"]["CampaignRequired"]; /** CampaignAdditionalField */ CampaignAdditionalField: { + error: string; name: string; slug: string; - error: string; } & ( | { + options: string[]; /** @enum {string} */ type: "select"; - options: string[]; } | { + regex: string; /** @enum {string} */ type: "text"; - regex: string; } ); /** CampaignField */ @@ -730,43 +741,43 @@ export interface components { id?: number; }; CampaignOptional: { - name?: string; + additionalFields?: components["schemas"]["CampaignField"][]; + allowed?: { + bug_types?: components["schemas"]["BugType"][]; + replicabilities?: components["schemas"]["Replicability"][]; + severities?: components["schemas"]["BugSeverity"][]; + }; + /** @description True if you applied on this Campaign */ + applied?: boolean; + /** @description If bugform is deactivated is a boolean else contains URLs to bugforms for each languages */ + bugform_link?: boolean | components["schemas"]["TranslatablePage"]; + /** @default 0 */ + csm_effort?: number; + customerCanViewReviewing?: boolean; customer_title?: string; - internal_id?: string; dates?: { - start?: string; - end?: string; close?: string; + end?: string; + start?: string; }; - status?: boolean; - language?: string; - public?: boolean; - hasBugParade?: boolean; devices?: { id?: string; }[]; + hasBugParade?: boolean; + internal_id?: string; + language?: string; + manual_link?: components["schemas"]["TranslatablePage"]; minNumberOfMedia?: number; - titleRule?: boolean; - allowed?: { - severities?: components["schemas"]["BugSeverity"][]; - bug_types?: components["schemas"]["BugType"][]; - replicabilities?: components["schemas"]["Replicability"][]; - }; + name?: string; + preview_link?: components["schemas"]["TranslatablePage"]; projectManager?: components["schemas"]["User"]; - customerCanViewReviewing?: boolean; - additionalFields?: components["schemas"]["CampaignField"][]; + public?: boolean; + status?: boolean; + titleRule?: boolean; /** @default 0 */ tokens?: number; /** @default 0 */ - csm_effort?: number; - /** @default 0 */ ux_effort?: number; - preview_link?: components["schemas"]["TranslatablePage"]; - manual_link?: components["schemas"]["TranslatablePage"]; - /** @description If bugform is deactivated is a boolean else contains URLs to bugforms for each languages */ - bugform_link?: boolean | components["schemas"]["TranslatablePage"]; - /** @description True if you applied on this Campaign */ - applied?: boolean; visibility?: { freeSpots?: number; totalSpots?: number; @@ -775,34 +786,39 @@ export interface components { }; }; CampaignRequired: { - name: string; + campaign_type: components["schemas"]["CampaignType"]; dates: { - start: string; - end: string; close: string; + end: string; + start: string; }; - campaign_type: components["schemas"]["CampaignType"]; + name: string; }; CampaignType: string | number; Certification: { - id?: number; - name: string; - area: string; - institute: string; /** Format: date */ achievement_date: string; + area: string; + id?: number; + institute: string; + name: string; }; /** CountryCode */ CountryCode: string; + /** Currency */ + Currency: { + currency: string; + value: number; + }; /** CustomUserFieldsData */ CustomUserFieldsData: { - id: number; - type: components["schemas"]["CustomUserFieldsType"]; - placeholder?: components["schemas"]["TranslatablePage"]; allow_other?: boolean; - name: components["schemas"]["TranslatablePage"]; format?: string; + id: number; + name: components["schemas"]["TranslatablePage"]; options?: components["schemas"]["CustomUserFieldsDataOption"][]; + placeholder?: components["schemas"]["TranslatablePage"]; + type: components["schemas"]["CustomUserFieldsType"]; }; /** CustomUserFieldsDataOption */ CustomUserFieldsDataOption: { @@ -814,60 +830,56 @@ export interface components { * @enum {string} */ CustomUserFieldsType: "text" | "select" | "multiselect"; - /** Currency */ - Currency: { - value: number; - currency: string; - }; DossierCreationData: { - project: number; - testType: number; - title: { - customer: string; - tester?: string; - }; - /** Format: date-time */ - startDate: string; - /** Format: date-time */ - endDate?: string; + additionals?: ({ + showInStats?: boolean; + } & components["schemas"]["CampaignAdditionalField"])[]; + browsers?: number[]; + bugTypes?: number[]; /** Format: date-time */ closeDate?: string; - deviceList: number[]; + countries?: components["schemas"]["CountryCode"][]; csm?: number; + description?: string; + deviceList: number[]; + deviceRequirements?: string; + /** Format: date-time */ + endDate?: string; + goal?: string; + languages?: string[]; + notes?: string; + outOfScope?: string; + productLink?: string; + productType?: number; + project: number; roles?: { role: number; user: number; }[]; - description?: string; - productLink?: string; - goal?: string; - outOfScope?: string; - deviceRequirements?: string; + /** Format: date-time */ + startDate: string; target?: { - notes?: string; - size?: number; cap?: number; genderQuote?: string; + notes?: string; + size?: number; + }; + testType: number; + title: { + customer: string; + tester?: string; }; - countries?: components["schemas"]["CountryCode"][]; - languages?: string[]; - browsers?: number[]; - productType?: number; - notes?: string; - additionals?: ({ - showInStats?: boolean; - } & components["schemas"]["CampaignAdditionalField"])[]; - bugTypes?: number[]; visibilityCriteria?: { + ageRanges?: { + max: number; + min: number; + }[]; cuf?: { cufId: number; cufValueIds: number[]; }[]; gender?: number[]; - ageRanges?: { - min: number; - max: number; - }[]; + provinces?: string[]; }; }; /** FiscalBirthCity */ @@ -897,17 +909,27 @@ export interface components { Gender: "male" | "female" | "not-specified" | "other"; /** LevelDefinition */ LevelDefinition: { + hold?: number; id: number; name: string; reach?: number; - hold?: number; }; /** MonthlyLevel */ MonthlyLevel: { id: number; name: string; }; + Olp: number[] | boolean; + /** PaginationData */ + PaginationData: { + limit?: number; + size: number; + start: number; + total?: number; + }; Popup: { + content?: string; + once?: boolean; profiles?: | number[] | ( @@ -917,18 +939,8 @@ export interface components { | "logged-in-year" | "not-logged-in-year" ); - once?: boolean; - content?: string; title?: string; }; - Olp: number[] | boolean; - /** PaginationData */ - PaginationData: { - start: number; - limit?: number; - size: number; - total?: number; - }; /** PreselectionFormQuestion */ PreselectionFormQuestion: { question: string; @@ -938,18 +950,18 @@ export interface components { type: components["schemas"]["PreselectionQuestionSimple"]; } | { - type: components["schemas"]["PreselectionQuestionMultiple"]; options?: { - value: string; isInvalid?: boolean; + value: string; }[]; + type: components["schemas"]["PreselectionQuestionMultiple"]; } | { - type: components["schemas"]["PreselectionQuestionCuf"]; options?: { - value: number; isInvalid?: boolean; + value: number; }[]; + type: components["schemas"]["PreselectionQuestionCuf"]; } ); /** PreselectionQuestionCuf */ @@ -974,11 +986,11 @@ export interface components { */ ProspectStatus: "draft" | "confirmed" | "done"; RankingItem: { - position: number; - image: string; id: number; - name: string; + image: string; monthly_exp: number; + name: string; + position: number; }; /** Replicability */ Replicability: { @@ -988,87 +1000,86 @@ export interface components { Task: components["schemas"]["TaskOptional"] & components["schemas"]["TaskRequired"]; TaskOptional: { - name?: string; - content?: string; + allow_media?: boolean; campaign_id?: number; + content?: string; group?: number; - allow_media?: boolean; + name?: string; }; TaskRequired: { - name: string; - content: string; campaign_id: number; + content: string; + name: string; }; /** TranslatablePage */ TranslatablePage: { en?: string; - it?: string; es?: string; + it?: string; }; /** User */ User: { - username?: string; - name?: string; - surname?: string; /** Format: email */ email?: string; + id?: number; /** Format: uri */ image?: string; - id?: number; - wp_user_id?: number; - role?: string; is_verified?: boolean; + name?: string; + role?: string; + surname?: string; + username?: string; + wp_user_id?: number; }; /** UserDevice */ UserDevice: { - type: string; - id: number; device: | { + id?: number; manufacturer: string; model: string; - id?: number; } | { pc_type: string; }; + id: number; operating_system: { id: number; platform: string; version: string; }; + type: string; }; }; responses: { - /** A user */ - UserData: { - content: { - "application/json": components["schemas"]["User"]; - }; - }; /** Authentication data. The token can be used to authenticate the protected requests */ Authentication: { content: { "application/json": { - id?: number; + exp?: number; firstName?: string; + iat?: number; + id?: number; lastName?: string; token?: string; username?: string; - iat?: number; - exp?: number; }; }; }; - /** A single Campaigns with the Campaign id and Project data */ - SingleCampaign: { + /** An error due to missing required parameters */ + MissingParameters: { content: { - "application/json": components["schemas"]["Campaign"] & { - id: number; - } & { - project?: components["schemas"]["Project"] & { - id?: number; - }; + "application/json": { + message: string; + }; + }; + }; + /** An error due to insufficient authorization to access the resource */ + NotAuthorized: { + content: { + "application/json": { + code?: string; + message?: string; }; }; }; @@ -1076,54 +1087,55 @@ export interface components { NotFound: { content: { "application/json": { + code?: string; element: string; id: number; message: string; - code?: string; }; }; }; - /** An error due to missing required parameters */ - MissingParameters: { + /** A single Campaigns with the Campaign id and Project data */ + SingleCampaign: { content: { - "application/json": { - message: string; + "application/json": components["schemas"]["Campaign"] & { + id: number; + } & { + project?: components["schemas"]["Project"] & { + id?: number; + }; }; }; }; - /** An error due to insufficient authorization to access the resource */ - NotAuthorized: { + /** A user */ + UserData: { content: { - "application/json": { - message?: string; - code?: string; - }; + "application/json": components["schemas"]["User"]; }; }; }; parameters: { /** @description A campaign id */ campaign: string; - /** @description A task id */ - task: string; /** @description A customer id */ customer: string; - /** @description A project id */ - project: string; - /** @description Max items to retrieve */ - limit: number; - /** @description Items to skip for pagination */ - start: number; /** @description Key-value Array for item filtering */ filterBy: { [key: string]: unknown }; - /** @description How to order values (ASC, DESC) */ - order: "ASC" | "DESC"; + /** @description Max items to retrieve */ + limit: number; /** @description How to localize values */ locale: "en" | "it"; - /** @description A comma separated list of fields which will be searched */ - searchBy: string; + /** @description How to order values (ASC, DESC) */ + order: "ASC" | "DESC"; + /** @description A project id */ + project: string; /** @description The value to search for */ search: string; + /** @description A comma separated list of fields which will be searched */ + searchBy: string; + /** @description Items to skip for pagination */ + start: number; + /** @description A task id */ + task: string; testerId: string; }; requestBodies: {}; @@ -1163,8 +1175,8 @@ export interface operations { id: number; } & components["schemas"]["Agreement"] & { customer: { - id: number; company: string; + id: number; }; })[]; } & components["schemas"]["PaginationData"]; @@ -1212,8 +1224,8 @@ export interface operations { id: number; } & components["schemas"]["Agreement"] & { customer: { - id: number; company: string; + id: number; }; }; }; @@ -1238,8 +1250,8 @@ export interface operations { id: number; } & components["schemas"]["Agreement"] & { customer: { - id: number; company: string; + id: number; }; }; }; @@ -1293,8 +1305,8 @@ export interface operations { requestBody: { content: { "application/json": { - username: string; password: string; + username: string; }; }; }; @@ -1342,6 +1354,23 @@ export interface operations { }; }; }; + "get-campaign-types": { + parameters: {}; + responses: { + 200: { + content: { + "application/json": { + customRoles: { + roleId: number; + userIds: number[]; + }[]; + id: number; + name: string; + }[]; + }; + }; + }; + }; /** Get all the Campaigns you have access to */ "get-campaigns": { parameters: { @@ -1368,22 +1397,6 @@ export interface operations { content: { "application/json": { items?: { - id?: number; - name?: string; - customerTitle?: string; - startDate?: string; - endDate?: string; - /** @enum {string} */ - status?: "running" | "closed" | "incoming"; - /** @enum {string} */ - visibility?: - | "admin" - | "smallgroup" - | "logged" - | "public" - | "target"; - /** @enum {string} */ - resultType?: "bug" | "bugparade" | "no"; csm?: { id: number; name: string; @@ -1393,19 +1406,25 @@ export interface operations { id?: number; name: string; }; - type?: { + customerTitle?: string; + endDate?: string; + id?: number; + name?: string; + phase?: { + id: number; name: string; - /** @enum {string} */ - area: "quality" | "experience"; }; project?: { id?: number; name: string; }; - phase?: { + quote?: { id: number; - name: string; + price: string; + status: string; }; + /** @enum {string} */ + resultType?: "bug" | "bugparade" | "no"; roles?: { role: { id: number; @@ -1417,11 +1436,21 @@ export interface operations { surname: string; }; }[]; - quote?: { - id: number; - price: string; - status: string; - }; + startDate?: string; + /** @enum {string} */ + status?: "running" | "closed" | "incoming"; + type?: { + /** @enum {string} */ + area: "quality" | "experience"; + name: string; + }; + /** @enum {string} */ + visibility?: + | "admin" + | "smallgroup" + | "logged" + | "public" + | "target"; }[]; } & components["schemas"]["PaginationData"]; }; @@ -1446,6 +1475,157 @@ export interface operations { }; }; }; + "get-campaigns-forms": { + parameters: { + query: { + /** A comma separated list of fields which will be searched */ + searchBy?: components["parameters"]["searchBy"]; + /** The value to search for */ + search?: components["parameters"]["search"]; + /** Max items to retrieve */ + limit?: components["parameters"]["limit"]; + /** Items to skip for pagination */ + start?: components["parameters"]["start"]; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": { + limit?: number; + results: { + campaign?: number; + id: number; + name: string; + }[]; + size: number; + start: number; + total?: number; + }; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + }; + "post-campaigns-forms": { + parameters: {}; + responses: { + /** Created */ + 201: { + content: { + "application/json": { + campaign?: { + id: number; + name: string; + }; + fields?: ({ + id: number; + } & components["schemas"]["PreselectionFormQuestion"])[]; + id: number; + name: string; + }; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + requestBody: { + content: { + "application/json": { + campaign?: number; + creationDate?: string; + fields: components["schemas"]["PreselectionFormQuestion"][]; + name: string; + }; + }; + }; + }; + "get-campaigns-forms-formId": { + parameters: { + path: { + formId: string; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": { + campaign?: { + id: number; + name: string; + }; + fields: ({ + id: number; + } & components["schemas"]["PreselectionFormQuestion"])[]; + id: number; + /** @example My form */ + name: string; + }; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + }; + "put-campaigns-forms-formId": { + parameters: { + path: { + formId: string; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": { + campaign?: { + id: number; + name: string; + }; + fields: ({ + id: number; + } & components["schemas"]["PreselectionFormQuestion"])[]; + id: number; + name: string; + }; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + requestBody: { + content: { + "application/json": { + campaign?: number; + fields: ({ + id?: number; + } & components["schemas"]["PreselectionFormQuestion"])[]; + name: string; + }; + }; + }; + }; + /** Get all the owners of campaigns you have access to */ + "get-campaigns-owners": { + parameters: {}; + responses: { + /** OK */ + 200: { + content: { + "application/json": { + id: number; + name: string; + surname: string; + }[]; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + }; /** Get the data of a Campaign if you have access to it */ "get-campaigns-campaign": { parameters: { @@ -1460,14 +1640,14 @@ export interface operations { content: { "application/json": { id: number; - title: string; - type: string; - typeDescription: string; - preselectionFormId?: number; plan?: { id: number; name: string; }; + preselectionFormId?: number; + title: string; + type: string; + typeDescription: string; }; }; }; @@ -1524,29 +1704,29 @@ export interface operations { content: { "application/json": { items: { + created: string; + /** @enum {string} */ + duplication: "father" | "unique" | "duplicated"; id: number; - title: string; internalId: string; - status: { + isFavourite: boolean; + severity: { id: number; name: string; }; - type: { + status: { id: number; name: string; }; - severity: { + tags?: components["schemas"]["BugTag"][]; + tester: { id: number; - name: string; }; - tester: { + title: string; + type: { id: number; + name: string; }; - tags?: components["schemas"]["BugTag"][]; - /** @enum {string} */ - duplication: "father" | "unique" | "duplicated"; - isFavourite: boolean; - created: string; updated: string; }[]; } & components["schemas"]["PaginationData"]; @@ -1570,36 +1750,61 @@ export interface operations { 200: { content: { "application/json": { - id: number; - title: string; - description: string; actual_result: string; + description: string; expected_result: string; - severity: components["schemas"]["BugSeverity"]; + id: number; + media: { + id: number; + }[]; + note: string; + reason: string; replicability: { id: number; name: string; }; + severity: components["schemas"]["BugSeverity"]; + status: components["schemas"]["BugStatus"]; + status_history: { + date: string; + reason: string; + status: string; + }[]; + title: string; type: { id: number; name: string; }; - status: components["schemas"]["BugStatus"]; - reason: string; - note: string; usecase: { + description: string; id: number; title: string; - description: string; }; - media: { - id: number; - }[]; - status_history: { - status: string; - reason: string; - date: string; - }[]; + }; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + }; + /** Get ai review for a single bug of a Campaign if you have access to it */ + "get-campaigns-single-bug-ai-review": { + parameters: { + path: { + /** A campaign id */ + campaign: string; + bugId: string; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": { + ai_status: string; + ai_reason: string; + score_percentage: number; + ai_notes?: string; }; }; }; @@ -1640,25 +1845,24 @@ export interface operations { content: { "application/json": { results?: { - id: number; - name: string; - surname: string; - gender: components["schemas"]["Gender"]; age: number; - experience: number; businessCps: number; businessCpsLastMonth: number; - levels: { - bugHunting: string; - metal: string; - }; devices: { + id: number; manufacturer?: string; model?: string; os: string; osVersion: string; - id: number; }[]; + experience: number; + gender: components["schemas"]["Gender"]; + id: number; + levels: { + bugHunting: string; + metal: string; + }; + name: string; questions?: { id?: number; title?: string; @@ -1666,6 +1870,7 @@ export interface operations { }[]; /** @enum {string} */ status?: "candidate" | "excluded" | "selected"; + surname: string; }[]; } & components["schemas"]["PaginationData"]; }; @@ -1688,9 +1893,9 @@ export interface operations { content: { "application/json": { results: { - tester_id: number; - device?: "any" | number; campaignId?: number; + device?: "any" | number; + tester_id: number; }[]; }; }; @@ -1699,12 +1904,12 @@ export interface operations { 207: { content: { "application/json": { + invalidTesters?: number[]; results: { - tester_id: number; - device?: "any" | number; campaignId?: number; + device?: "any" | number; + tester_id: number; }[]; - invalidTesters?: number[]; }; }; }; @@ -1715,12 +1920,12 @@ export interface operations { content: { "application/json": | { - tester_id: number; device?: number | "random"; + tester_id: number; }[] | { - tester_id: number; device?: number | "random"; + tester_id: number; }; }; }; @@ -1809,22 +2014,22 @@ export interface operations { content: { "application/json": { items: { - id: number; - name: string; - time: number; - tester: { - id: number; - name: string; - }; cluster: { id: number; name: string; }; + id: number; media: { id: number; - url: string; streamUrl: string; + url: string; + }; + name: string; + tester: { + id: number; + name: string; }; + time: number; }[]; }; }; @@ -1845,20 +2050,20 @@ export interface operations { 200: { content: { "application/json": { - maxBonusBug: number; completionRule: { bugs?: number; usecases?: number; }; - testSuccess: { + maxBonusBug: number; + testFailure: { + message: string; payout: number; points: number; - message: string; }; - testFailure: { + testSuccess: { + message: string; payout: number; points: number; - message: string; }; }; }; @@ -1885,38 +2090,38 @@ export interface operations { content: { "application/json": { items: { - tester: { - id: number; - name: string; - surname: string; - group: number; - }; - usecases: { - completed: number; - required: number; - }; bugs: { critical: number; high: number; - medium: number; - low: number; - }; - payout: { - completion: number; - bug: number; - refund: number; - extra: number; + low: number; + medium: number; }; experience: { completion: number; extra: number; }; + isCompleted: boolean; + isTopTester: boolean; note: string; + payout: { + bug: number; + completion: number; + extra: number; + refund: number; + }; /** @enum {string} */ status: "pending" | "done"; + tester: { + group: number; + id: number; + name: string; + surname: string; + }; + usecases: { + completed: number; + required: number; + }; weightedBugs: number; - isCompleted: boolean; - isTopTester: boolean; }[]; status: components["schemas"]["ProspectStatus"]; }; @@ -1946,24 +2151,24 @@ export interface operations { requestBody: { content: { "application/json": { - status: components["schemas"]["ProspectStatus"]; items: { - tester: { - id: number; - }; + completed: boolean; experience: { completion: number; extra: number; }; + note?: string; payout: { - completion: number; bug: number; + completion: number; extra: number; refund: number; }; - note?: string; - completed: boolean; + tester: { + id: number; + }; }[]; + status: components["schemas"]["ProspectStatus"]; }; }; }; @@ -2005,18 +2210,18 @@ export interface operations { 200: { content: { "application/json": { - payout: { + completed: boolean; + experience: { completion: number; - bugs: number; - refund: number; extra: number; }; - experience: { + note: string; + payout: { + bugs: number; completion: number; extra: number; + refund: number; }; - note: string; - completed: boolean; }; }; }; @@ -2024,18 +2229,18 @@ export interface operations { requestBody: { content: { "application/json": { - payout: { + completed: boolean; + experience: { completion: number; - bugs: number; - refund: number; extra: number; }; - experience: { + note: string; + payout: { + bugs: number; completion: number; extra: number; + refund: number; }; - note: string; - completed: boolean; }; }; }; @@ -2161,239 +2366,71 @@ export interface operations { content: { "application/json": { goal: string; - usersNumber: number; - sentiments: { - id: number; - value: number; - comment: string; - cluster: { - id: number; - name: string; - }; - }[]; methodology: { + description: string; name: string; /** @enum {string} */ type: "qualitative" | "quantitative" | "quali-quantitative"; - description: string; }; questions: { id: number; name: string; }[]; - visible: number; - }; - }; - }; - 403: components["responses"]["NotAuthorized"]; - 404: components["responses"]["NotFound"]; - }; - }; - "patch-campaigns-campaign-ux": { - parameters: { - path: { - /** A campaign id */ - campaign: string; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": { [key: string]: unknown }; - }; - }; - 403: components["responses"]["Authentication"]; - 404: components["responses"]["NotFound"]; - }; - requestBody: { - content: { - "application/json": { - goal?: string; - usersNumber?: number; - visible?: number; - methodology?: { - description: string; - type: string; - }; - sentiments?: { - clusterId: number; - value: number; - comment: string; - id?: number; - }[]; - questions?: { - name: string; - id?: number; - }[]; - }; - }; - }; - }; - "get-campaigns-forms": { - parameters: { - query: { - /** A comma separated list of fields which will be searched */ - searchBy?: components["parameters"]["searchBy"]; - /** The value to search for */ - search?: components["parameters"]["search"]; - /** Max items to retrieve */ - limit?: components["parameters"]["limit"]; - /** Items to skip for pagination */ - start?: components["parameters"]["start"]; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": { - results: { + sentiments: { + cluster: { + id: number; + name: string; + }; + comment: string; id: number; - name: string; - campaign?: number; + value: number; }[]; - limit?: number; - start: number; - size: number; - total?: number; - }; - }; - }; - 403: components["responses"]["NotAuthorized"]; - 404: components["responses"]["NotFound"]; - }; - }; - "post-campaigns-forms": { - parameters: {}; - responses: { - /** Created */ - 201: { - content: { - "application/json": { - id: number; - name: string; - campaign?: { - id: number; - name: string; - }; - fields?: ({ - id: number; - } & components["schemas"]["PreselectionFormQuestion"])[]; - }; - }; - }; - 403: components["responses"]["NotAuthorized"]; - 404: components["responses"]["NotFound"]; - }; - requestBody: { - content: { - "application/json": { - name: string; - fields: components["schemas"]["PreselectionFormQuestion"][]; - campaign?: number; - creationDate?: string; - }; - }; - }; - }; - "get-campaigns-forms-formId": { - parameters: { - path: { - formId: string; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": { - id: number; - /** @example My form */ - name: string; - campaign?: { - id: number; - name: string; - }; - fields: ({ - id: number; - } & components["schemas"]["PreselectionFormQuestion"])[]; - }; - }; - }; - 403: components["responses"]["NotAuthorized"]; - 404: components["responses"]["NotFound"]; - }; - }; - "put-campaigns-forms-formId": { - parameters: { - path: { - formId: string; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": { - id: number; - name: string; - fields: ({ - id: number; - } & components["schemas"]["PreselectionFormQuestion"])[]; - campaign?: { - id: number; - name: string; - }; + usersNumber: number; + visible: number; }; }; }; - 403: components["responses"]["NotAuthorized"]; - 404: components["responses"]["NotFound"]; - }; - requestBody: { - content: { - "application/json": { - name: string; - campaign?: number; - fields: ({ - id?: number; - } & components["schemas"]["PreselectionFormQuestion"])[]; - }; - }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; }; }; - /** Get all the owners of campaigns you have access to */ - "get-campaigns-owners": { - parameters: {}; + "patch-campaigns-campaign-ux": { + parameters: { + path: { + /** A campaign id */ + campaign: string; + }; + }; responses: { /** OK */ 200: { content: { - "application/json": { - id: number; - name: string; - surname: string; - }[]; + "application/json": { [key: string]: unknown }; }; }; - 403: components["responses"]["NotAuthorized"]; + 403: components["responses"]["Authentication"]; 404: components["responses"]["NotFound"]; }; - }; - "get-campaign-types": { - parameters: {}; - responses: { - 200: { - content: { - "application/json": { - id: number; + requestBody: { + content: { + "application/json": { + goal?: string; + methodology?: { + description: string; + type: string; + }; + questions?: { + id?: number; name: string; - customRoles: { - roleId: number; - userIds: number[]; - }[]; }[]; + sentiments?: { + clusterId: number; + comment: string; + id?: number; + value: number; + }[]; + usersNumber?: number; + visible?: number; }; }; }; @@ -2411,10 +2448,10 @@ export interface operations { 200: { content: { "application/json": { - id: number; - name: string; area: string; + id: number; institute: string; + name: string; }[]; }; }; @@ -2443,6 +2480,24 @@ export interface operations { }; }; }; + "get-customUserFields": { + parameters: {}; + responses: { + /** OK */ + 200: { + content: { + "application/json": { + fields?: components["schemas"]["CustomUserFieldsData"][]; + group: { + description?: components["schemas"]["TranslatablePage"]; + id: number; + name: components["schemas"]["TranslatablePage"]; + }; + }[]; + }; + }; + }; + }; /** Get all the customers you have access to */ "get-customers": { parameters: {}; @@ -2525,24 +2580,6 @@ export interface operations { }; }; }; - "get-customUserFields": { - parameters: {}; - responses: { - /** OK */ - 200: { - content: { - "application/json": { - group: { - id: number; - name: components["schemas"]["TranslatablePage"]; - description?: components["schemas"]["TranslatablePage"]; - }; - fields?: components["schemas"]["CustomUserFieldsData"][]; - }[]; - }; - }; - }; - }; /** Get all model of devices with theirs manufacturers */ "get-devices-devices-type-model": { parameters: { @@ -2648,12 +2685,12 @@ export interface operations { content: { "application/json": components["schemas"]["DossierCreationData"] & { duplicate?: { + campaign?: number; fields?: number; - useCases?: number; mailMerges?: number; pages?: number; testers?: number; - campaign?: number; + useCases?: number; }; } & { /** @default 0 */ @@ -2674,34 +2711,46 @@ export interface operations { 200: { content: { "application/json": { - id: number; - title: { - customer: string; - tester: string; - }; - /** Format: date-time */ - startDate: string; - /** Format: date-time */ - endDate: string; + browsers?: { + id: number; + name: string; + }[]; /** Format: date-time */ closeDate: string; - customer: { + countries?: components["schemas"]["CountryCode"][]; + csm: { id: number; name: string; }; - project: { + customer: { id: number; name: string; }; - testType: { + description?: string; + deviceList: { + id: number; + name: string; + }[]; + deviceRequirements?: string; + /** Format: date-time */ + endDate: string; + goal?: string; + id: number; + languages?: { + name: string; + }[]; + notes?: string; + outOfScope?: string; + phase: { id: number; name: string; }; - deviceList: { + productLink?: string; + productType?: { id: number; name: string; - }[]; - csm: { + }; + project: { id: number; name: string; }; @@ -2716,44 +2765,33 @@ export interface operations { surname: string; }; }[]; - description?: string; - productLink?: string; - goal?: string; - outOfScope?: string; - deviceRequirements?: string; + /** Format: date-time */ + startDate: string; target?: { - notes?: string; - size?: number; cap?: number; genderQuote?: string; + notes?: string; + size?: number; }; - countries?: components["schemas"]["CountryCode"][]; - languages?: { - name: string; - }[]; - browsers?: { - id: number; - name: string; - }[]; - productType?: { + testType: { id: number; name: string; }; - phase: { - id: number; - name: string; + title: { + customer: string; + tester: string; }; - notes?: string; visibilityCriteria?: { + ageRanges?: { + max: number; + min: number; + }[]; cuf?: { cufId: number; cufValueIds: number[]; }[]; - ageRanges?: { - min: number; - max: number; - }[]; gender?: number[]; + province?: string[]; }; }; }; @@ -2781,6 +2819,29 @@ export interface operations { }; }; }; + "post-dossiers-campaign-manual": { + parameters: { + path: { + /** A campaign id */ + campaign: components["parameters"]["campaign"]; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": { [key: string]: unknown }; + }; + }; + }; + requestBody: { + content: { + "application/json": { + importFrom: number; + }; + }; + }; + }; "put-dossiers-campaign-phases": { parameters: { path: { @@ -2807,6 +2868,29 @@ export interface operations { }; }; }; + "post-dossiers-campaign-preview": { + parameters: { + path: { + /** A campaign id */ + campaign: components["parameters"]["campaign"]; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": { [key: string]: unknown }; + }; + }; + }; + requestBody: { + content: { + "application/json": { + importFrom: number; + }; + }; + }; + }; "post-dossiers-campaign-quotations": { parameters: { path: { @@ -2829,8 +2913,8 @@ export interface operations { requestBody: { content: { "application/json": { - quote?: string; notes?: string; + quote?: string; }; }; }; @@ -2876,13 +2960,13 @@ export interface operations { items: { campaign: { id: number; - title: string; phase_id: number; phase_name: string; + title: string; }; quote: { - id: number; amount: string; + id: number; /** @enum {string} */ status: "pending" | "proposed" | "approved" | "rejected"; }; @@ -2924,42 +3008,39 @@ export interface operations { 404: components["responses"]["NotFound"]; }; }; - "post-jotforms-campaignId": { - parameters: { - path: { - /** A campaign id */ - campaign: string; - }; - }; + "get-jotforms": { + parameters: {}; responses: { /** OK */ 200: { content: { - "application/json": { [key: string]: unknown }; + "application/json": { + createdAt: string; + id: string; + name: string; + }[]; }; }; /** Forbidden */ 403: unknown; }; - requestBody: { - content: { - "application/json": { - formId: string; - testerIdColumn: string; - }; + }; + "get-jotforms-forms-formId-questions": { + parameters: { + path: { + formId: string; }; }; - }; - "get-jotforms": { - parameters: {}; responses: { /** OK */ 200: { content: { "application/json": { + description?: string; id: string; name: string; - createdAt: string; + title: string; + type: string; }[]; }; }; @@ -2967,28 +3048,31 @@ export interface operations { 403: unknown; }; }; - "get-jotforms-forms-formId-questions": { + "post-jotforms-campaignId": { parameters: { path: { - formId: string; + /** A campaign id */ + campaign: string; }; }; responses: { /** OK */ 200: { content: { - "application/json": { - id: string; - name: string; - title: string; - description?: string; - type: string; - }[]; + "application/json": { [key: string]: unknown }; }; }; /** Forbidden */ 403: unknown; }; + requestBody: { + content: { + "application/json": { + formId: string; + testerIdColumn: string; + }; + }; + }; }; /** Get all languages */ "get-languages": { @@ -3029,13 +3113,13 @@ export interface operations { 200: { content: { "application/json": { - files: { + failed?: { + errorCode: string; name: string; - path: string; }[]; - failed?: { + files: { name: string; - errorCode: string; + path: string; }[]; }; }; @@ -3087,29 +3171,29 @@ export interface operations { 200: { content: { "application/json": { - limit?: number; - size: number; - start: number; - total?: number; items: { - /** @description The timestamp (GMT) of the request creation */ - created: string; - /** @description The timestamp (GMT) of the request last update */ - updated: string; - id: number; amount: { - value: number; currency: string; + value: number; }; - /** @enum {string} */ - type: "paypal" | "transferwise"; + /** @description The timestamp (GMT) of the request creation */ + created: string; + error?: string; + id: number; tryber: { id: number; name: string; surname: string; }; - error?: string; + /** @enum {string} */ + type: "paypal" | "transferwise"; + /** @description The timestamp (GMT) of the request last update */ + updated: string; }[]; + limit?: number; + size: number; + start: number; + total?: number; }; }; }; @@ -3335,19 +3419,19 @@ export interface operations { requestBody: { content: { "application/json": { - name: string; - surname: string; + /** Format: date */ + birthDate: string; + country: string; /** Format: email */ email: string; + name: string; password: string; - country: string; - /** Format: date */ - birthDate: string; /** * @description A referral code (formatted as TESTER_ID-CAMPAIGN_ID) * @example 555-1234 */ referral?: string; + surname: string; }; }; }; @@ -3401,53 +3485,53 @@ export interface operations { 200: { content: { "application/json": { - username?: string; - name?: string; - surname?: string; - /** Format: email */ - email?: string; - image?: string; - id: number; - wp_user_id?: number; - role?: string; - is_verified?: boolean; - rank?: string; - total_exp_pts?: number; + additional?: components["schemas"]["AdditionalField"][]; + approved_bugs?: number; + attended_cp?: number; + /** Format: date */ + birthDate?: string; booty?: { - net?: components["schemas"]["Currency"]; gross: components["schemas"]["Currency"]; - }; - pending_booty?: { net?: components["schemas"]["Currency"]; - gross: components["schemas"]["Currency"]; }; + booty_threshold?: { + isOver: boolean; + value: number; + }; + certifications?: components["schemas"]["Certification"][] | boolean; + city?: string; + completionPercent?: number; + country?: string; + education?: { + id: number; + name: string; + }; + /** Format: email */ + email?: string; + gender?: components["schemas"]["Gender"]; + id: number; + image?: string; + is_verified?: boolean; languages?: { name?: string; }[]; + name?: string; onboarding_completed?: boolean; - additional?: components["schemas"]["AdditionalField"][]; - gender?: components["schemas"]["Gender"]; - /** Format: date */ - birthDate?: string; - phone?: string; - education?: { - id: number; - name: string; + pending_booty?: { + gross: components["schemas"]["Currency"]; + net?: components["schemas"]["Currency"]; }; + phone?: string; profession?: { id: number; name: string; }; - certifications?: components["schemas"]["Certification"][] | boolean; - completionPercent?: number; - country?: string; - city?: string; - attended_cp?: number; - approved_bugs?: number; - booty_threshold?: { - value: number; - isOver: boolean; - }; + rank?: string; + role?: string; + surname?: string; + total_exp_pts?: number; + username?: string; + wp_user_id?: number; }; }; }; @@ -3466,10 +3550,10 @@ export interface operations { requestBody: { content: { "application/json": { + email?: string; name?: string; - surname?: string; password?: string; - email?: string; + surname?: string; }; }; }; @@ -3495,50 +3579,50 @@ export interface operations { 200: { content: { "application/json": { - username?: string; - name?: string; - surname?: string; - email?: string; - image?: string; - id: number; - wp_user_id?: number; - role?: string; - is_verified?: boolean; - rank?: string; - total_exp_pts?: number; + additional?: components["schemas"]["AdditionalField"][]; + approved_bugs?: number; + attended_cp?: number; + /** Format: date */ + birthDate?: string; booty?: { gross: components["schemas"]["Currency"]; net?: components["schemas"]["Currency"]; }; - pending_booty?: { - gross: components["schemas"]["Currency"]; - net?: components["schemas"]["Currency"]; + certifications?: components["schemas"]["Certification"][] | boolean; + city?: string; + completionPercent?: number; + country?: string; + education?: { + id: number; + name: string; }; + email?: string; + /** @enum {string} */ + gender?: "male" | "female" | "not-specified" | "other"; + id: number; + image?: string; + is_verified?: boolean; languages?: { id?: number; name?: string; }[]; + name?: string; onboarding_completed?: boolean; - additional?: components["schemas"]["AdditionalField"][]; - /** @enum {string} */ - gender?: "male" | "female" | "not-specified" | "other"; - /** Format: date */ - birthDate?: string; - phone?: string; - education?: { - id: number; - name: string; + pending_booty?: { + gross: components["schemas"]["Currency"]; + net?: components["schemas"]["Currency"]; }; + phone?: string; profession?: { id: number; name: string; }; - certifications?: components["schemas"]["Certification"][] | boolean; - completionPercent?: number; - country?: string; - city?: string; - attended_cp?: number; - approved_bugs?: number; + rank?: string; + role?: string; + surname?: string; + total_exp_pts?: number; + username?: string; + wp_user_id?: number; }; }; }; @@ -3549,21 +3633,21 @@ export interface operations { requestBody: { content: { "application/json": { - name?: string; + birthDate?: string; + city?: string; + country?: string; + education?: number; /** Format: email */ email?: string; - onboarding_completed?: boolean; - surname?: string; /** @enum {string} */ gender?: "male" | "female" | "not-specified" | "other"; - birthDate?: string; + name?: string; + oldPassword?: string; + onboarding_completed?: boolean; + password?: string; phone?: string; - education?: number; profession?: number; - country?: string; - city?: string; - password?: string; - oldPassword?: string; + surname?: string; }; }; }; @@ -3592,12 +3676,12 @@ export interface operations { content: { "application/json": | { - value: string; is_candidate?: boolean; + value: string; }[] | { - value: string; is_candidate?: boolean; + value: string; }; }; }; @@ -3623,10 +3707,10 @@ export interface operations { 200: { content: { "application/json": { + limit?: number; results: ({ id: number; } & components["schemas"]["Bug"])[]; - limit?: number; size?: number; start?: number; total?: number; @@ -3672,10 +3756,10 @@ export interface operations { 200: { content: { "application/json": { + limit?: number; results?: ({ id: number; } & components["schemas"]["Campaign"])[]; - limit?: number; size?: number; start?: number; total?: number; @@ -3699,59 +3783,41 @@ export interface operations { 200: { content: { "application/json": { - id: number; - title: string; - language?: { - code: string; - message: string; - }; - titleRule?: boolean; - minimumMedia: number; - useCases: { - id: number; - name: string; - }[]; additionalFields?: components["schemas"]["CampaignAdditionalField"][]; - bugTypes: { - valid: string[]; + bugReplicability: { invalid: string[]; + valid: string[]; }; bugSeverity: { - valid: string[]; invalid: string[]; - }; - bugReplicability: { valid: string[]; + }; + bugTypes: { invalid: string[]; + valid: string[]; }; - hasBugForm: boolean; devices?: ({ id: number; } & components["schemas"]["UserDevice"])[]; + hasBugForm: boolean; + id: number; + language?: { + code: string; + message: string; + }; + minimumMedia: number; + title: string; + titleRule?: boolean; + useCases: { + id: number; + name: string; + }[]; validFileExtensions: string[]; }; }; }; }; }; - "get-users-me-campaigns-campaignId-compatible-devices": { - parameters: { - path: { - /** A campaign id */ - campaign: string; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": components["schemas"]["UserDevice"][]; - }; - }; - 403: components["responses"]["NotAuthorized"]; - 404: components["responses"]["NotFound"]; - }; - }; /** Send a user bug on a specific campaign */ "post-users-me-campaigns-campaign-bugs": { parameters: { @@ -3765,28 +3831,28 @@ export interface operations { 200: { content: { "application/json": { + additional?: { + slug: string; + value: string; + }[]; + current: string; + description: string; + device: components["schemas"]["UserDevice"]; + expected: string; id: number; internalId?: string; - testerId: number; - title: string; - description: string; + media: string[]; + notes: string; /** @enum {string} */ - status: "PENDING" | "APPROVED" | "REFUSED" | "NEED-REVIEW"; - expected: string; - current: string; + replicability: "ONCE" | "SOMETIMES" | "ALWAYS"; /** @enum {string} */ severity: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"; /** @enum {string} */ - replicability: "ONCE" | "SOMETIMES" | "ALWAYS"; + status: "PENDING" | "APPROVED" | "REFUSED" | "NEED-REVIEW"; + testerId: number; + title: string; type: string; - notes: string; usecase: string; - device: components["schemas"]["UserDevice"]; - media: string[]; - additional?: { - slug: string; - value: string; - }[]; }; }; }; @@ -3796,24 +3862,24 @@ export interface operations { requestBody: { content: { "application/json": { - title: string; + additional?: { + slug: string; + value: string; + }[]; + current: string; description: string; + device: number; expected: string; - current: string; - /** @enum {string} */ - severity: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"; + lastSeen: string; + media: string[]; + notes: string; /** @enum {string} */ replicability: "ONCE" | "SOMETIMES" | "ALWAYS"; + /** @enum {string} */ + severity: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"; + title: string; type: string; - notes: string; - lastSeen: string; usecase: number; - device: number; - media: string[]; - additional?: { - slug: string; - value: string; - }[]; }; }; }; @@ -3846,8 +3912,13 @@ export interface operations { 200: { content: { "application/json": ({ + id: number; question: string; short_name?: string; + validation?: { + error?: string; + regex: string; + }; value?: | number | { @@ -3856,22 +3927,17 @@ export interface operations { } | number[] | string; - validation?: { - regex: string; - error?: string; - }; - id: number; } & ( | { type: components["schemas"]["PreselectionQuestionSimple"]; } | { - type: components["schemas"]["PreselectionQuestionMultiple"]; options: string[]; + type: components["schemas"]["PreselectionQuestionMultiple"]; } | { - type: components["schemas"]["PreselectionQuestionCuf"]; options?: number[]; + type: components["schemas"]["PreselectionQuestionCuf"]; } ))[]; }; @@ -3895,7 +3961,9 @@ export interface operations { requestBody: { content: { "application/json": { + device?: number[]; form?: { + question: number; value: { id?: number | number[]; serialized?: @@ -3906,9 +3974,7 @@ export interface operations { country: string; }; }; - question: number; }[]; - device?: number[]; }; }; }; @@ -3924,17 +3990,17 @@ export interface operations { 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; + }[]; + files?: { + name: string; + path: string; }[]; }; }; @@ -3948,6 +4014,24 @@ export interface operations { }; }; }; + "get-users-me-campaigns-campaignId-compatible-devices": { + parameters: { + path: { + /** A campaign id */ + campaign: string; + }; + }; + responses: { + /** OK */ + 200: { + content: { + "application/json": components["schemas"]["UserDevice"][]; + }; + }; + 403: components["responses"]["NotAuthorized"]; + 404: components["responses"]["NotFound"]; + }; + }; /** Add one certification to your profile */ "post-users-me-certifications": { responses: { @@ -3970,9 +4054,9 @@ export interface operations { certifications: boolean; } | { - certification_id: number; /** Format: date */ achievement_date: string; + certification_id: number; }; }; }; @@ -4145,27 +4229,27 @@ export interface operations { 200: { content: { "application/json": { + limit?: number; results: { - id: number; activity: { id: number; }; + amount: number; campaign: { id: number; title?: string; }; /** Format: date */ date: string; - amount: number; + id: number; note?: string; }[]; - limit?: number; size?: number; start?: number; - /** @description The total number of experience entries */ - total?: number; /** @description The total sum of experience */ sum: number; + /** @description The total number of experience entries */ + total?: number; }; }; }; @@ -4181,14 +4265,13 @@ export interface operations { content: { "application/json": { address: { + city: string; + cityCode: string; country: string; province: string; - city: string; street: string; streetNumber?: string; - cityCode: string; }; - type: components["schemas"]["FiscalType"] | "internal"; birthPlace: { city?: string; province?: string; @@ -4198,6 +4281,7 @@ export interface operations { fiscalStatus: "Verified" | "Unverified"; /** @enum {string} */ gender: "male" | "female"; + type: components["schemas"]["FiscalType"] | "internal"; }; }; }; @@ -4213,14 +4297,13 @@ export interface operations { content: { "application/json": { address: { + city: string; + cityCode: string; country: string; province: string; - city: string; street: string; streetNumber?: string; - cityCode: string; }; - type: components["schemas"]["FiscalType"]; birthPlace?: { city?: string; province?: string; @@ -4230,6 +4313,7 @@ export interface operations { fiscalStatus: "Verified" | "Unverified"; /** @enum {string} */ gender: "male" | "female"; + type: components["schemas"]["FiscalType"]; }; }; }; @@ -4239,18 +4323,18 @@ export interface operations { content: { "application/json": { address: { + city: string; + cityCode: string; country: string; province: string; - city: string; street: string; streetNumber: string; - cityCode: string; }; - type: components["schemas"]["FiscalType"]; birthPlace?: components["schemas"]["FiscalBirthCity"]; fiscalId: string; /** @enum {string} */ gender: "male" | "female"; + type: components["schemas"]["FiscalType"]; }; }; }; @@ -4263,14 +4347,13 @@ export interface operations { content: { "application/json": { address: { + city: string; + cityCode: string; country: string; province: string; - city: string; street: string; streetNumber?: string; - cityCode: string; }; - type: components["schemas"]["FiscalType"]; birthPlace?: { city?: string; province?: string; @@ -4280,6 +4363,7 @@ export interface operations { fiscalStatus: "Verified" | "Unverified"; /** @enum {string} */ gender: "male" | "female"; + type: components["schemas"]["FiscalType"]; }; }; }; @@ -4289,18 +4373,18 @@ export interface operations { content: { "application/json": { address: { + city: string; + cityCode: string; country: string; province: string; - city: string; street: string; streetNumber: string; - cityCode: string; }; - type: components["schemas"]["FiscalType"]; birthPlace?: components["schemas"]["FiscalBirthCity"]; fiscalId: string; /** @enum {string} */ gender: "male" | "female"; + type: components["schemas"]["FiscalType"]; }; }; }; @@ -4385,25 +4469,25 @@ export interface operations { 200: { content: { "application/json": { + limit?: number; results?: ({ id: number; } & { - /** @enum {string} */ - status: "paid" | "processing"; amount: { - net: components["schemas"]["Currency"]; gross: components["schemas"]["Currency"]; + net: components["schemas"]["Currency"]; }; - paidDate: string; method: { + note: string; /** @enum {string} */ type: "paypal" | "iban"; - note: string; }; + paidDate: string; /** Format: uri-reference */ receipt?: string; + /** @enum {string} */ + status: "paid" | "processing"; })[]; - limit?: number; size: number; start: number; total?: number; @@ -4421,8 +4505,8 @@ export interface operations { 200: { content: { "application/json": { - id?: number; amount?: number; + id?: number; }; }; }; @@ -4433,15 +4517,15 @@ export interface operations { "application/json": { method: | { + email: string; /** @enum {string} */ type: "paypal"; - email: string; } | { - /** @enum {string} */ - type: "iban"; accountHolderName: string; iban: string; + /** @enum {string} */ + type: "iban"; }; }; }; @@ -4469,22 +4553,22 @@ export interface operations { 200: { content: { "application/json": { + limit?: number; results: ({ id: number; } & { - type: string; + activity: string; amount: { - net?: components["schemas"]["Currency"]; gross: components["schemas"]["Currency"]; + net?: components["schemas"]["Currency"]; }; /** Format: date */ date: string; - activity: string; + type: string; })[]; - limit?: number; size: number; - total?: number; start: number; + total?: number; }; }; }; @@ -4517,19 +4601,19 @@ export interface operations { 200: { content: { "application/json": { + limit?: number; results?: ({ id: number; } & { - name: string; + activity: string; amount: { - net?: components["schemas"]["Currency"]; gross: components["schemas"]["Currency"]; + net?: components["schemas"]["Currency"]; }; /** Format: date */ attributionDate: string; - activity: string; + name: string; })[]; - limit?: number; size: number; start: number; total?: number; @@ -4576,10 +4660,10 @@ export interface operations { 200: { content: { "application/json": { - id?: number; - title?: string; content?: string; + id?: number; once?: boolean; + title?: string; }[]; }; }; @@ -4612,17 +4696,17 @@ export interface operations { content: { "application/json": { level: components["schemas"]["MonthlyLevel"]; - previousLevel: components["schemas"]["MonthlyLevel"]; - rank: number; points: number; + previousLevel: components["schemas"]["MonthlyLevel"]; prospect: { level: components["schemas"]["MonthlyLevel"]; maintenance?: number; next?: { - points: number; level: components["schemas"]["MonthlyLevel"]; + points: number; }; }; + rank: number; }; }; }; @@ -4635,8 +4719,8 @@ export interface operations { 200: { content: { "application/json": { - tops: components["schemas"]["RankingItem"][]; peers: components["schemas"]["RankingItem"][]; + tops: components["schemas"]["RankingItem"][]; }; }; }; @@ -4644,52 +4728,6 @@ export interface operations { 404: components["responses"]["NotFound"]; }; }; - "post-dossiers-campaign-manual": { - parameters: { - path: { - /** A campaign id */ - campaign: components["parameters"]["campaign"]; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": { [key: string]: unknown }; - }; - }; - }; - requestBody: { - content: { - "application/json": { - importFrom: number; - }; - }; - }; - }; - "post-dossiers-campaign-preview": { - parameters: { - path: { - /** A campaign id */ - campaign: components["parameters"]["campaign"]; - }; - }; - responses: { - /** OK */ - 200: { - content: { - "application/json": { [key: string]: unknown }; - }; - }; - }; - requestBody: { - content: { - "application/json": { - importFrom: number; - }; - }; - }; - }; } export interface external {} From 4491daaaf2c83b3e4ca6cc3325e53d6b4a2b85c5 Mon Sep 17 00:00:00 2001 From: ZecD Date: Tue, 1 Jul 2025 15:01:10 +0200 Subject: [PATCH 2/6] feat(BugsTable): add AI Score info modal and info icon --- src/assets/info-icon.svg | 3 +++ src/pages/BugsList/Table/index.tsx | 35 ++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 src/assets/info-icon.svg diff --git a/src/assets/info-icon.svg b/src/assets/info-icon.svg new file mode 100644 index 00000000..68d18d66 --- /dev/null +++ b/src/assets/info-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/pages/BugsList/Table/index.tsx b/src/pages/BugsList/Table/index.tsx index 4448e1a3..0d675a87 100644 --- a/src/pages/BugsList/Table/index.tsx +++ b/src/pages/BugsList/Table/index.tsx @@ -4,17 +4,21 @@ import { Card, icons, aqBootstrapTheme as theme, + Modal, } from "@appquality/appquality-design-system"; import { useGetCampaignsByCampaignBugsQuery, GetCampaignsByCampaignBugsApiArg, } from "src/services/tryberApi"; import { useFiltersCardContext } from "../FilterContext"; +import { Button as AppQualityButton } from "@appquality/appquality-design-system"; +import { ReactComponent as InfoIcon } from "src/assets/info-icon.svg"; import Button from "./TableButton"; import Severity from "./Severity"; import Type from "./Type"; import AiSuggestion from "./AISuggestion"; import AiScore from "./AiScore"; +import { useState } from "react"; const LIMIT = 100; @@ -22,6 +26,7 @@ const StarFill = icons.StarFill; const BugsTable = ({ id }: { id: string }) => { const { filters, page, setPage, order, setOrder } = useFiltersCardContext(); + const [infoModal, setInfoModal] = useState(false); let orderBy: GetCampaignsByCampaignBugsApiArg["orderBy"] = "id"; if (order.field === "internalId") orderBy = "id"; @@ -150,10 +155,21 @@ const BugsTable = ({ id }: { id: string }) => { maxWidth: "15ch", }, { - title: "Score", + title: ( +
+ Score + setInfoModal(true)} + kind="transparent" + style={{ paddingLeft: 4 }} + > + + +
+ ), dataIndex: "score", key: "score", - maxWidth: "10ch", + maxWidth: "15ch", }, { title: "Status", @@ -195,6 +211,21 @@ const BugsTable = ({ id }: { id: string }) => { maxPages={Math.ceil(data.total / data.limit)} /> ) : null} + {infoModal && ( + setInfoModal(false)} + title="AI Score" + > +

+ The AI Score is a percentage that reflects how accurately the tester + has evaluated the bug according to the AI based on several criteria + — including scope relevance, a well-formed title and aligned to the + usecase, a clear description, appropriate severity, correct type, + and attached media. +

+
+ )} ); }; From b8bf8c8ae2e2d86ba70f8ebc5b1d238fb6bfdd83 Mon Sep 17 00:00:00 2001 From: ZecD Date: Thu, 3 Jul 2025 10:39:19 +0200 Subject: [PATCH 3/6] refactor(api): streamline response type comments for clarity From b33535b85be15eeb221d0c5b74ecc5d6c992982f Mon Sep 17 00:00:00 2001 From: ZecD Date: Thu, 3 Jul 2025 10:59:00 +0200 Subject: [PATCH 4/6] feat(AISuggestion): add modal for AI status reason and update suggestion display --- src/pages/BugsList/Table/AISuggestion.tsx | 21 ++++++++++- src/pages/BugsList/Table/index.tsx | 45 +++++++++++++++++++---- 2 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/pages/BugsList/Table/AISuggestion.tsx b/src/pages/BugsList/Table/AISuggestion.tsx index 75a9b3e0..50104681 100644 --- a/src/pages/BugsList/Table/AISuggestion.tsx +++ b/src/pages/BugsList/Table/AISuggestion.tsx @@ -1,3 +1,5 @@ +import { Modal } from "@appquality/appquality-design-system"; +import { useState } from "react"; import { useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery } from "src/services/tryberApi"; import styled from "styled-components"; @@ -15,6 +17,7 @@ const AiSuggestion = ({ campaignId: string; bugId: number; }) => { + const [statusInfoModal, setInfoModal] = useState(false); const { data, isError } = useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery({ campaign: campaignId, bugId: bugId.toString(), @@ -31,7 +34,23 @@ const AiSuggestion = ({ const label = labelMap[data.ai_status] || data.ai_status; return ( - {label} + <> + setInfoModal(true)} + suggestion={data.ai_status} + > + {label} + + {statusInfoModal && ( + setInfoModal(false)} + title="AI Status Reason" + > +

{data.ai_reason}

+
+ )} + ); }; diff --git a/src/pages/BugsList/Table/index.tsx b/src/pages/BugsList/Table/index.tsx index 0d675a87..ceb8dcd7 100644 --- a/src/pages/BugsList/Table/index.tsx +++ b/src/pages/BugsList/Table/index.tsx @@ -26,7 +26,8 @@ const StarFill = icons.StarFill; const BugsTable = ({ id }: { id: string }) => { const { filters, page, setPage, order, setOrder } = useFiltersCardContext(); - const [infoModal, setInfoModal] = useState(false); + const [scoreModal, setScoreModal] = useState(false); + const [statusModal, setStatusModal] = useState(false); let orderBy: GetCampaignsByCampaignBugsApiArg["orderBy"] = "id"; if (order.field === "internalId") orderBy = "id"; @@ -149,17 +150,28 @@ const BugsTable = ({ id }: { id: string }) => { key: "title", }, { - title: "AI Suggestion", + title: ( +
+ AI Suggestion + setStatusModal(true)} + kind="transparent" + style={{ paddingLeft: 4 }} + > + + +
+ ), dataIndex: "ai_suggestion", key: "ai_suggestion", - maxWidth: "15ch", + maxWidth: "25ch", }, { title: (
Score setInfoModal(true)} + onClick={() => setScoreModal(true)} kind="transparent" style={{ paddingLeft: 4 }} > @@ -211,10 +223,10 @@ const BugsTable = ({ id }: { id: string }) => { maxPages={Math.ceil(data.total / data.limit)} /> ) : null} - {infoModal && ( + {scoreModal && ( setInfoModal(false)} + isOpen={scoreModal} + onClose={() => setScoreModal(false)} title="AI Score" >

@@ -226,6 +238,25 @@ const BugsTable = ({ id }: { id: string }) => {

)} + {statusModal && ( + setStatusModal(false)} + title="AI Suggestion" + > +

+ The AI Suggestion is a status recommendation provided by the AI + based on the score percentage achieved by the bug based on the score + criteria. It can be: +
+ Approved : 60% or more +
+ Need Review : Between 40% and 60% +
+ Refused : Less than 40% +

+
+ )} ); }; From 51ede0b742c121200b47626103c55f820f4f8e62 Mon Sep 17 00:00:00 2001 From: ZecD Date: Thu, 3 Jul 2025 11:11:21 +0200 Subject: [PATCH 5/6] style(AISuggestion): ensure cursor is pointer for better UX on suggestion display --- src/pages/BugsList/Table/AISuggestion.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/BugsList/Table/AISuggestion.tsx b/src/pages/BugsList/Table/AISuggestion.tsx index 50104681..556c116d 100644 --- a/src/pages/BugsList/Table/AISuggestion.tsx +++ b/src/pages/BugsList/Table/AISuggestion.tsx @@ -8,6 +8,7 @@ const StyledSuggestion = styled.span<{ suggestion: string }>` ${({ suggestion }) => suggestion === "need_review" && `color: #C78430;`} ${({ suggestion }) => suggestion === "approved" && `color: #02807A;`} text-transform: capitalize; + cursor: pointer; `; const AiSuggestion = ({ From 467081fada3a1822fa59e9a65cac95880ac9cf98 Mon Sep 17 00:00:00 2001 From: ZecD Date: Thu, 3 Jul 2025 11:18:47 +0200 Subject: [PATCH 6/6] feat(AISuggestion): add info button for AI status reason modal --- src/pages/BugsList/Table/AISuggestion.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/pages/BugsList/Table/AISuggestion.tsx b/src/pages/BugsList/Table/AISuggestion.tsx index 556c116d..0e5912a1 100644 --- a/src/pages/BugsList/Table/AISuggestion.tsx +++ b/src/pages/BugsList/Table/AISuggestion.tsx @@ -1,6 +1,8 @@ import { Modal } from "@appquality/appquality-design-system"; import { useState } from "react"; import { useGetCampaignsByCampaignBugsAndBugIdAiReviewQuery } from "src/services/tryberApi"; +import { Button as AppQualityButton } from "@appquality/appquality-design-system"; +import { ReactComponent as InfoIcon } from "src/assets/info-icon.svg"; import styled from "styled-components"; const StyledSuggestion = styled.span<{ suggestion: string }>` @@ -8,7 +10,6 @@ const StyledSuggestion = styled.span<{ suggestion: string }>` ${({ suggestion }) => suggestion === "need_review" && `color: #C78430;`} ${({ suggestion }) => suggestion === "approved" && `color: #02807A;`} text-transform: capitalize; - cursor: pointer; `; const AiSuggestion = ({ @@ -36,12 +37,14 @@ const AiSuggestion = ({ return ( <> - {label} + setInfoModal(true)} - suggestion={data.ai_status} + kind="transparent" + style={{ paddingLeft: 4 }} > - {label} - + + {statusInfoModal && (