diff --git a/.claude/settings.json b/.claude/settings.json deleted file mode 100644 index 41e8c3c4a..000000000 --- a/.claude/settings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(npx playwright test --list)", - "Bash(source ~/.zshrc)", - "Bash(node --version)" - ] - } -} diff --git a/src/common/schema.ts b/src/common/schema.ts index 5abe196c3..d281d88b5 100644 --- a/src/common/schema.ts +++ b/src/common/schema.ts @@ -9,6 +9,9 @@ export interface paths { get: operations["get-root"]; parameters: {}; }; + "/ai/agents/generate-video-tasks": { + post: operations["post-ai-agents-generate-video-tasks"]; + }; "/analytics/views/campaigns/{cid}": { post: operations["post-analytics-views-campaigns-cid"]; parameters: { @@ -2113,6 +2116,32 @@ export interface operations { 500: components["responses"]["Error"]; }; }; + "post-ai-agents-generate-video-tasks": { + responses: { + /** OK */ + 200: { + content: { + "application/json": { + tasks: components["schemas"]["OutputModuleTaskVideo"][]; + }; + }; + }; + 400: components["responses"]["Error"]; + 403: components["responses"]["Error"]; + 500: components["responses"]["Error"]; + 502: components["responses"]["Error"]; + }; + requestBody: { + content: { + "application/json": { + modules: components["schemas"]["Module"][]; + plan_id?: number; + input_prompt?: string; + usecase_number?: number; + }; + }; + }; + }; "post-analytics-views-campaigns-cid": { parameters: { path: { diff --git a/src/features/api/index.ts b/src/features/api/index.ts index c3fd54f6e..5594adc37 100644 --- a/src/features/api/index.ts +++ b/src/features/api/index.ts @@ -4,6 +4,16 @@ const injectedRtkApi = api.injectEndpoints({ $get: build.query<$getApiResponse, $getApiArg>({ query: () => ({ url: `/` }), }), + postAiAgentsGenerateVideoTasks: build.mutation< + PostAiAgentsGenerateVideoTasksApiResponse, + PostAiAgentsGenerateVideoTasksApiArg + >({ + query: (queryArg) => ({ + url: `/ai/agents/generate-video-tasks`, + method: 'POST', + body: queryArg.body, + }), + }), postAnalyticsViewsCampaignsByCid: build.mutation< PostAnalyticsViewsCampaignsByCidApiResponse, PostAnalyticsViewsCampaignsByCidApiArg @@ -1024,6 +1034,17 @@ const injectedRtkApi = api.injectEndpoints({ export { injectedRtkApi as unguessApi }; export type $getApiResponse = /** status 200 OK */ {}; export type $getApiArg = void; +export type PostAiAgentsGenerateVideoTasksApiResponse = /** status 200 OK */ { + tasks: SubcomponentTaskVideo[]; +}; +export type PostAiAgentsGenerateVideoTasksApiArg = { + body: { + modules: Module[]; + plan_id?: number; + input_prompt?: string; + usecase_number?: number; + }; +}; export type PostAnalyticsViewsCampaignsByCidApiResponse = /** status 200 OK */ { success?: boolean; }; @@ -2489,734 +2510,734 @@ export type Error = { error: boolean; message: string; }; -export type Authentication = { - email: string; - exp?: number; - iat?: number; - id: number; - name: string; - picture?: string; - role: string; - token: string; -}; -export type Campaign = { - base_bug_internal_id?: string; - /** -1: no bug form; - 0: only bug form; - 1: bug form with bug parade; */ - bug_form?: number; - close_date: string; - customer_title: string; +export type SubcomponentTaskVideo = { description?: string; - end_date: string; - family: { - id: number; - name: string; - }; - id: number; - is_public: number; - project: { - id: number; - name: string; - }; - start_date: string; - status: { - id: number; - name: string; - }; + id?: string; + kind: 'video'; title: string; - type: { - id: number; - name: string; - }; - workspace: { - id: number; - name: string; - }; + url?: string; }; -export type Output = 'bugs' | 'media' | 'insights'; -export type CampaignWithOutput = Campaign & { - outputs?: Output[]; +export type ModuleTitle = { + output: string; + type: 'title'; + variant: string; }; -export type BugType = { - id: number; - name: string; +export type ModuleDate = { + output: { + start: string; + }; + type: 'dates'; + variant: string; }; -export type BugCustomStatusPhase = { - id: number; - name: string; +export type SubcomponentTaskBug = { + description?: string; + id?: string; + kind: 'bug'; + title: string; + url?: string; }; -export type BugCustomStatus = { - color: string; - id: number; - is_default: number; - name: string; - phase: BugCustomStatusPhase; +export type SubcomponentTaskSurvey = { + description?: string; + id?: string; + kind: 'survey'; + title: string; + url?: string; }; -export type Smartphone = { - manufacturer: string; - model: string; - os: string; - os_version: string; - type: 'smartphone'; +export type OutputModuleTaskModerateVideo = { + description?: string; + id?: string; + kind: 'moderate-video'; + title: string; + url?: string; }; -export type Tablet = { - manufacturer: string; - model: string; - os: string; - os_version: string; - type: 'tablet'; +export type OutputModuleTaskExplorativeBug = { + description?: string; + id?: string; + kind: 'explorative-bug'; + title: string; + url?: string; }; -export type Desktop = { - desktop_type: string; - os: string; - os_version: string; - type: 'desktop'; +export type OutputModuleTaskAccessibility = { + description?: string; + id?: string; + kind: 'accessibility'; + title: string; + url?: string; }; -export type BugPriority = { - id: number; - name: string; +export type SubcomponentTask = + | SubcomponentTaskVideo + | SubcomponentTaskBug + | SubcomponentTaskSurvey + | OutputModuleTaskModerateVideo + | OutputModuleTaskExplorativeBug + | OutputModuleTaskAccessibility; +export type ModuleTask = { + output: SubcomponentTask[]; + type: 'tasks'; + variant: string; }; -export type BugReplicability = { - id: number; - name: string; +export type OutputModuleAge = { + max: number; + min: number; + percentage: number; +}[]; +export type ModuleAge = { + output: OutputModuleAge; + type: 'age'; + variant: string; }; -export type BugSeverity = { - id: number; - name: string; +export type ModuleLanguage = { + output: string; + type: 'language'; + variant: string; }; -export type BugStatus = { - id: number; - name: string; +export type OutputModuleLiteracy = { + level: 'beginner' | 'intermediate' | 'expert'; + percentage: number; +}[]; +export type ModuleLiteracy = { + output: OutputModuleLiteracy; + type: 'literacy'; + variant: string; }; -export type BugTitle = { - /** Bug title without context. */ - compact: string; - context?: string[]; - full: string; +export type ModuleTarget = { + output: number; + type: 'target'; + variant: string; }; -export type Bug = { - application_section: { - id?: number; - prefix_title?: string; - simple_title?: string; - title?: string; - }; - campaign_id: 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 ModuleGoal = { + output: string; + type: 'goal'; + variant: string; }; -export type BugAdditionalFieldRegex = { - kind: 'regex'; - validation: string; +export type OutputModuleGender = { + gender: 'male' | 'female'; + percentage: number; +}[]; +export type ModuleGender = { + output: OutputModuleGender; + type: 'gender'; + variant: string; }; -export type BugAdditionalFieldSelect = { - kind: 'select'; - options: string[]; +export type ModuleOutOfScope = { + output: string; + type: 'out_of_scope'; + variant: string; }; -export type BugAdditionalField = { - id: number; - name: string; - value: string; -} & (BugAdditionalFieldRegex | BugAdditionalFieldSelect); -export type BugMedia = { - creation_date: string; - mime_type: { - extension: string; - type: 'video' | 'image' | 'other'; - }; - url: string; +export type OutputModuleBrowser = { + name: 'firefox' | 'edge' | 'chrome' | 'safari'; + percentage: number; +}[]; +export type ModuleBrowser = { + output: OutputModuleBrowser; + type: 'browser'; + variant: string; }; -export type BugTag = { - author_tid?: number; - author_wp_id?: number; - bug_id: number; - campaign_id: number; - creation_date: string; - id: number; - is_visible_to_customer?: number; - name: string; - slug: string; - tag_id: number; +export type ModuleTargetNote = { + output: string; + type: 'target_note'; + variant: string; }; -export type BugComment = { - creation_date: string; - creator: { - id: number; - isInternal: boolean; - name: string; - }; - id: number; - media?: { - id: number; - type: string; - url: string; - }[]; - text: string; +export type ModuleInstructionNote = { + output: string; + type: 'instruction_note'; + variant: string; }; -export type Cluster = { - id: number; - name: string; +export type ModuleSetupNote = { + output: string; + type: 'setup_note'; + variant: string; }; -export type VideoTag = { - group: { - id: number; - name: string; - }; - tag: { - id: number; - name: string; - style: string; - usageNumber: number; +export type OutputModuleTouchpointsAppDesktop = { + form_factor: 'desktop'; + kind: 'app'; + os: { + linux?: string; + macos?: string; + windows?: string; }; }; -export type Observation = { - description: string; - end: number; - id: number; - quotes: string; - start: number; - tags: VideoTag[]; - title: string; - uxNote?: string; -}; -export type Insight = { - comment?: string; - description: string; - id: number; - observations: (Observation & { - uploaderId: number; - usecaseTitle: string; - video: { - deviceType: string; - id: number; - }; - })[]; - severity: { - id: number; - name: string; - style: string; +export type OutputModuleTouchpointsAppTablet = { + form_factor: 'tablet'; + kind: 'app'; + os: { + ios?: string; + android?: string; }; - title: string; - visible?: number; }; -export type Grape = { - observations: (Observation & { - deviceType: string; - mediaId: number; - uploaderId: number; - usecaseTitle: string; - })[]; - severity: string; - title: string; - usersNumber: number; +export type OutputModuleTouchpointsAppSmartphone = { + form_factor: 'smartphone'; + kind: 'app'; + os: { + android?: string; + ios?: string; + }; }; -export type ReportExtensions = - | 'pdf' - | 'doc' - | 'docx' - | 'xls' - | 'xlsx' - | 'ppt' - | 'pptx' - | 'rar' - | 'txt' - | 'csv' - | 'zip' - | 'gzip' - | 'gz' - | '7z'; -export type Report = { - creation_date?: string; - description?: string; - file_type?: { - domain_name?: string; - extension?: ReportExtensions; - type: string; +export type OutputModuleTouchpointsWebDesktop = { + form_factor: 'desktop'; + kind: 'web'; + os: { + linux?: string; + macos?: string; + windows?: 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; - invitationPending: boolean; - name: string; - permissionFrom?: { - id?: number; - type?: 'workspace' | 'project'; +export type OutputModuleTouchpointsWebTablet = { + form_factor: 'tablet'; + kind: 'web'; + os: { + android?: string; + ios?: string; }; - profile_id: number; }; -export type MediaSentiment = { - paragraphs: { - end: number; - reason: string; - start: number; - value: number; - }[]; - reason: string; - value: number; +export type OutputModuleTouchpointsWebSmartphone = { + form_factor: 'smartphone'; + kind: 'web'; + os: { + android?: string; + ios?: string; + }; }; -export type Word = { - end: number; - /** Id of Speaker */ - speaker?: number; - start: number; - word: string; +export type SubcomponentTouchpoints = + | OutputModuleTouchpointsAppDesktop + | OutputModuleTouchpointsAppTablet + | OutputModuleTouchpointsAppSmartphone + | OutputModuleTouchpointsWebDesktop + | OutputModuleTouchpointsWebTablet + | OutputModuleTouchpointsWebSmartphone; +export type ModuleTouchpoints = { + output: SubcomponentTouchpoints[]; + type: 'touchpoints'; + variant: string; }; -export type Paragraph = { - end: number; - /** Id Of speaker */ - speaker?: number; - start: number; - text: string; - words: Word[]; +export type ModuleAdditionalTarget = { + output: string; + type: 'additional_target'; + variant: string; }; -export type Transcript = { - paragraphs: Paragraph[]; - /** Number of spekers */ - speakers: number; +export type ModuleEmployment = { + /** cuf values of cuf employment */ + output: ( + | 'EMPLOYEE' + | 'FREELANCER' + | 'RETIRED' + | 'STUDENT' + | 'UNEMPLOYED' + | 'HOMEMAKER' + )[]; + type: 'employment'; + variant: string; }; -export type Video = { - duration?: number; - id: number; - poster?: string; - sentiment?: MediaSentiment; - streamUrl?: string; - tester: { - device: { - type: 'smartphone' | 'tablet' | 'desktop' | 'other'; - }; - id: number; - name: string; - surname: string; - }; - transcript?: Transcript; - url: string; +export type OutputModuleLocality = { + type: string; + values: string[]; +}[]; +export type ModuleLocality = { + output: OutputModuleLocality; + type: 'locality'; + variant: string; }; -export type PaginationData = { - limit?: number; - size?: number; - start?: number; - total?: number; +export type OutputServiceProviders = { + isOther?: number; + name: string; +}[]; +export type ModuleBank = { + output: OutputServiceProviders; + type: 'bank'; + variant: string; }; -export type WidgetBugsByUseCase = { - data: { - bugs: number; - description: string; - title: { - full: string; - info?: string; - prefix?: string; - simple?: string; - }; - uniqueBugs?: number; - usecase_completion?: number; - usecase_id: number; - }[]; - kind: 'bugsByUseCase'; -}; -export type WidgetBugsByDevice = { - data: ((Smartphone | Desktop | Tablet) & { - /** Unique bugs */ - bugs: number; - unique_bugs: number; - })[]; - kind: 'bugsByDevice'; -}; -export type WidgetCampaignProgress = { - data: { - end_date: string; - /** 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: { - total: number; - trend: number; - unique: number; - }; - kind: 'campaignUniqueBugs'; -}; -export type WidgetBugsByDuplicates = { - data: (Bug & { - duplicates: number; - })[]; - kind: 'bugsByDuplicates'; -}; -export type WidgetCampaignUxTaggingVideoCompletionData = { - data: { - countMedia: number; - countMediaWithObservation: number; - }; - kind: 'uxTaggingVideoCompletion'; +export type ModuleElettricitySupply = { + output: OutputServiceProviders; + type: 'elettricity_supply'; + variant: string; }; -export type WidgetCampaignUxTotalTitlesVsRecurrentTitles = { - data: { - countObservationNoTitle: number; - countRecurrentTitles: number; - countTitleTag: number; - }; - kind: 'uxTotalTitlesVsRecurrentTitles'; +export type ModuleMobileInternet = { + output: OutputServiceProviders; + type: 'mobile_internet'; + variant: string; }; -export type WidgetCampaignUxSeveritiesDistribution = { - data: { - countObservations: number; - severitiesDistribution: { - countMajorIssue: number; - countMinorIssue: number; - countObservationSeverity: number; - countPositiveFindings: number; - }; - }; - kind: 'uxSeveritiesDistribution'; +export type ModuleHomeInternet = { + output: OutputServiceProviders; + type: 'home_internet'; + variant: string; }; -export type WidgetCampaignUxMostUsedTitles = { - data: { - mostUsedTitles: { - mainSeverityAssignment: string; - title: string; - usage: number; - }[]; - }; - kind: 'uxMostUsedTitles'; +export type ModuleGasSupply = { + output: OutputServiceProviders; + type: 'gas_supply'; + variant: string; }; -export type ModuleTitle = { - output: string; - type: 'title'; +export type OutputModuleIncomeRange = { + max: number; + min: number; + percentage: number; +}[]; +export type ModuleAnnualIncomeRange = { + output: OutputModuleIncomeRange; + type: 'annual_income_range'; variant: string; }; -export type ModuleDate = { - output: { - start: string; - }; - type: 'dates'; +export type ModuleAcnSaver = { + output: ( + | 'ACN.PRAGMATICO DIGITALE' + | 'ACN.EMERGENTE ASPIRAZIONALE' + | 'ACN.INVESTITORE SOFISTICATO' + | 'ACN.SOCIALE COLLABORATIVO' + | 'ACN.CONSERVATORE PRUDENTE' + )[]; + type: 'acn_saver_personas'; variant: string; }; -export type SubcomponentTaskVideo = { - description?: string; - id?: string; - kind: 'video'; - title: string; - url?: string; +export type Module = + | ModuleTitle + | ModuleDate + | ModuleTask + | ModuleAge + | ModuleLanguage + | ModuleLiteracy + | ModuleTarget + | ModuleGoal + | ModuleGender + | ModuleOutOfScope + | ModuleBrowser + | ModuleTargetNote + | ModuleInstructionNote + | ModuleSetupNote + | ModuleTouchpoints + | ModuleAdditionalTarget + | ModuleEmployment + | ModuleLocality + | ModuleBank + | ModuleElettricitySupply + | ModuleMobileInternet + | ModuleHomeInternet + | ModuleGasSupply + | ModuleAnnualIncomeRange + | ModuleAcnSaver; +export type Authentication = { + email: string; + exp?: number; + iat?: number; + id: number; + name: string; + picture?: string; + role: string; + token: string; }; -export type SubcomponentTaskBug = { +export type Campaign = { + base_bug_internal_id?: string; + /** -1: no bug form; + 0: only bug form; + 1: bug form with bug parade; */ + bug_form?: number; + close_date: string; + customer_title: string; description?: string; - id?: string; - kind: 'bug'; + end_date: string; + family: { + id: number; + name: string; + }; + id: number; + is_public: number; + project: { + id: number; + name: string; + }; + start_date: string; + status: { + id: number; + name: string; + }; title: string; - url?: string; + type: { + id: number; + name: string; + }; + workspace: { + id: number; + name: string; + }; }; -export type SubcomponentTaskSurvey = { - description?: string; - id?: string; - kind: 'survey'; - title: string; - url?: string; +export type Output = 'bugs' | 'media' | 'insights'; +export type CampaignWithOutput = Campaign & { + outputs?: Output[]; }; -export type OutputModuleTaskModerateVideo = { - description?: string; - id?: string; - kind: 'moderate-video'; - title: string; - url?: string; +export type BugType = { + id: number; + name: string; }; -export type OutputModuleTaskExplorativeBug = { - description?: string; - id?: string; - kind: 'explorative-bug'; - title: string; - url?: string; +export type BugCustomStatusPhase = { + id: number; + name: string; }; -export type OutputModuleTaskAccessibility = { - description?: string; - id?: string; - kind: 'accessibility'; - title: string; - url?: string; +export type BugCustomStatus = { + color: string; + id: number; + is_default: number; + name: string; + phase: BugCustomStatusPhase; }; -export type SubcomponentTask = - | SubcomponentTaskVideo - | SubcomponentTaskBug - | SubcomponentTaskSurvey - | OutputModuleTaskModerateVideo - | OutputModuleTaskExplorativeBug - | OutputModuleTaskAccessibility; -export type ModuleTask = { - output: SubcomponentTask[]; - type: 'tasks'; - variant: string; +export type Smartphone = { + manufacturer: string; + model: string; + os: string; + os_version: string; + type: 'smartphone'; }; -export type OutputModuleAge = { - max: number; - min: number; - percentage: number; -}[]; -export type ModuleAge = { - output: OutputModuleAge; - type: 'age'; - variant: string; -}; -export type ModuleLanguage = { - output: string; - type: 'language'; - variant: string; +export type Tablet = { + manufacturer: string; + model: string; + os: string; + os_version: string; + type: 'tablet'; }; -export type OutputModuleLiteracy = { - level: 'beginner' | 'intermediate' | 'expert'; - percentage: number; -}[]; -export type ModuleLiteracy = { - output: OutputModuleLiteracy; - type: 'literacy'; - variant: string; +export type Desktop = { + desktop_type: string; + os: string; + os_version: string; + type: 'desktop'; }; -export type ModuleTarget = { - output: number; - type: 'target'; - variant: string; +export type BugPriority = { + id: number; + name: string; }; -export type ModuleGoal = { - output: string; - type: 'goal'; - variant: string; +export type BugReplicability = { + id: number; + name: string; }; -export type OutputModuleGender = { - gender: 'male' | 'female'; - percentage: number; -}[]; -export type ModuleGender = { - output: OutputModuleGender; - type: 'gender'; - variant: string; +export type BugSeverity = { + id: number; + name: string; }; -export type ModuleOutOfScope = { - output: string; - type: 'out_of_scope'; - variant: string; +export type BugStatus = { + id: number; + name: string; }; -export type OutputModuleBrowser = { - name: 'firefox' | 'edge' | 'chrome' | 'safari'; - percentage: number; -}[]; -export type ModuleBrowser = { - output: OutputModuleBrowser; - type: 'browser'; - variant: string; +export type BugTitle = { + /** Bug title without context. */ + compact: string; + context?: string[]; + full: string; }; -export type ModuleTargetNote = { - output: string; - type: 'target_note'; - variant: string; +export type Bug = { + application_section: { + id?: number; + prefix_title?: string; + simple_title?: string; + title?: string; + }; + campaign_id: 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 ModuleInstructionNote = { - output: string; - type: 'instruction_note'; - variant: string; +export type BugAdditionalFieldRegex = { + kind: 'regex'; + validation: string; }; -export type ModuleSetupNote = { - output: string; - type: 'setup_note'; - variant: string; +export type BugAdditionalFieldSelect = { + kind: 'select'; + options: string[]; }; -export type OutputModuleTouchpointsAppDesktop = { - form_factor: 'desktop'; - kind: 'app'; - os: { - linux?: string; - macos?: string; - windows?: string; +export type BugAdditionalField = { + id: number; + name: string; + value: string; +} & (BugAdditionalFieldRegex | BugAdditionalFieldSelect); +export type BugMedia = { + creation_date: string; + mime_type: { + extension: string; + type: 'video' | 'image' | 'other'; }; + url: string; }; -export type OutputModuleTouchpointsAppTablet = { - form_factor: 'tablet'; - kind: 'app'; - os: { - ios?: string; - android?: string; - }; +export type BugTag = { + author_tid?: number; + author_wp_id?: number; + bug_id: number; + campaign_id: number; + creation_date: string; + id: number; + is_visible_to_customer?: number; + name: string; + slug: string; + tag_id: number; }; -export type OutputModuleTouchpointsAppSmartphone = { - form_factor: 'smartphone'; - kind: 'app'; - os: { - android?: string; - ios?: string; +export type BugComment = { + creation_date: string; + creator: { + id: number; + isInternal: boolean; + name: string; }; + id: number; + media?: { + id: number; + type: string; + url: string; + }[]; + text: string; }; -export type OutputModuleTouchpointsWebDesktop = { - form_factor: 'desktop'; - kind: 'web'; - os: { - linux?: string; - macos?: string; - windows?: string; - }; +export type Cluster = { + id: number; + name: string; }; -export type OutputModuleTouchpointsWebTablet = { - form_factor: 'tablet'; - kind: 'web'; - os: { - android?: string; - ios?: string; +export type VideoTag = { + group: { + id: number; + name: string; }; -}; -export type OutputModuleTouchpointsWebSmartphone = { - form_factor: 'smartphone'; - kind: 'web'; - os: { - android?: string; - ios?: string; + tag: { + id: number; + name: string; + style: string; + usageNumber: number; }; }; -export type SubcomponentTouchpoints = - | OutputModuleTouchpointsAppDesktop - | OutputModuleTouchpointsAppTablet - | OutputModuleTouchpointsAppSmartphone - | OutputModuleTouchpointsWebDesktop - | OutputModuleTouchpointsWebTablet - | OutputModuleTouchpointsWebSmartphone; -export type ModuleTouchpoints = { - output: SubcomponentTouchpoints[]; - type: 'touchpoints'; - variant: string; +export type Observation = { + description: string; + end: number; + id: number; + quotes: string; + start: number; + tags: VideoTag[]; + title: string; + uxNote?: string; }; -export type ModuleAdditionalTarget = { - output: string; - type: 'additional_target'; - variant: string; +export type Insight = { + 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; }; -export type ModuleEmployment = { - /** cuf values of cuf employment */ - output: ( - | 'EMPLOYEE' - | 'FREELANCER' - | 'RETIRED' - | 'STUDENT' - | 'UNEMPLOYED' - | 'HOMEMAKER' - )[]; - type: 'employment'; - variant: string; +export type Grape = { + observations: (Observation & { + deviceType: string; + mediaId: number; + uploaderId: number; + usecaseTitle: string; + })[]; + severity: string; + title: string; + usersNumber: number; }; -export type OutputModuleLocality = { - type: string; - values: string[]; -}[]; -export type ModuleLocality = { - output: OutputModuleLocality; - type: 'locality'; - variant: string; +export type ReportExtensions = + | 'pdf' + | 'doc' + | 'docx' + | 'xls' + | 'xlsx' + | 'ppt' + | 'pptx' + | 'rar' + | 'txt' + | 'csv' + | 'zip' + | 'gzip' + | 'gz' + | '7z'; +export type Report = { + creation_date?: string; + description?: string; + file_type?: { + domain_name?: string; + extension?: ReportExtensions; + type: string; + }; + id?: number; + title?: string; + update_date?: string; + url: string; }; -export type OutputServiceProviders = { - isOther?: number; +export type BannerType = + | 'banner_testing_automation' + | 'banner_user_experience' + | 'banner_cyber_security'; +export type Tenant = { + email: string; + /** tryber wp_user_id */ + id: number; + invitationPending: boolean; name: string; -}[]; -export type ModuleBank = { - output: OutputServiceProviders; - type: 'bank'; - variant: string; + permissionFrom?: { + id?: number; + type?: 'workspace' | 'project'; + }; + profile_id: number; }; -export type ModuleElettricitySupply = { - output: OutputServiceProviders; - type: 'elettricity_supply'; - variant: string; +export type MediaSentiment = { + paragraphs: { + end: number; + reason: string; + start: number; + value: number; + }[]; + reason: string; + value: number; }; -export type ModuleMobileInternet = { - output: OutputServiceProviders; - type: 'mobile_internet'; - variant: string; +export type Word = { + end: number; + /** Id of Speaker */ + speaker?: number; + start: number; + word: string; }; -export type ModuleHomeInternet = { - output: OutputServiceProviders; - type: 'home_internet'; - variant: string; +export type Paragraph = { + end: number; + /** Id Of speaker */ + speaker?: number; + start: number; + text: string; + words: Word[]; }; -export type ModuleGasSupply = { - output: OutputServiceProviders; - type: 'gas_supply'; - variant: string; +export type Transcript = { + paragraphs: Paragraph[]; + /** Number of spekers */ + speakers: number; }; -export type OutputModuleIncomeRange = { - max: number; - min: number; - percentage: number; -}[]; -export type ModuleAnnualIncomeRange = { - output: OutputModuleIncomeRange; - type: 'annual_income_range'; - variant: string; +export type Video = { + duration?: number; + id: number; + poster?: string; + sentiment?: MediaSentiment; + streamUrl?: string; + tester: { + device: { + type: 'smartphone' | 'tablet' | 'desktop' | 'other'; + }; + id: number; + name: string; + surname: string; + }; + transcript?: Transcript; + url: string; }; -export type ModuleAcnSaver = { - output: ( - | 'ACN.PRAGMATICO DIGITALE' - | 'ACN.EMERGENTE ASPIRAZIONALE' - | 'ACN.INVESTITORE SOFISTICATO' - | 'ACN.SOCIALE COLLABORATIVO' - | 'ACN.CONSERVATORE PRUDENTE' - )[]; - type: 'acn_saver_personas'; - variant: string; +export type PaginationData = { + limit?: number; + size?: number; + start?: number; + total?: number; +}; +export type WidgetBugsByUseCase = { + data: { + bugs: number; + description: string; + title: { + full: string; + info?: string; + prefix?: string; + simple?: string; + }; + uniqueBugs?: number; + usecase_completion?: number; + usecase_id: number; + }[]; + kind: 'bugsByUseCase'; +}; +export type WidgetBugsByDevice = { + data: ((Smartphone | Desktop | Tablet) & { + /** Unique bugs */ + bugs: number; + unique_bugs: number; + })[]; + kind: 'bugsByDevice'; +}; +export type WidgetCampaignProgress = { + data: { + end_date: string; + /** 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: { + total: number; + trend: number; + unique: number; + }; + kind: 'campaignUniqueBugs'; +}; +export type WidgetBugsByDuplicates = { + data: (Bug & { + duplicates: number; + })[]; + kind: 'bugsByDuplicates'; +}; +export type WidgetCampaignUxTaggingVideoCompletionData = { + data: { + countMedia: number; + countMediaWithObservation: number; + }; + kind: 'uxTaggingVideoCompletion'; +}; +export type WidgetCampaignUxTotalTitlesVsRecurrentTitles = { + data: { + countObservationNoTitle: number; + countRecurrentTitles: number; + countTitleTag: number; + }; + kind: 'uxTotalTitlesVsRecurrentTitles'; +}; +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 Module = - | ModuleTitle - | ModuleDate - | ModuleTask - | ModuleAge - | ModuleLanguage - | ModuleLiteracy - | ModuleTarget - | ModuleGoal - | ModuleGender - | ModuleOutOfScope - | ModuleBrowser - | ModuleTargetNote - | ModuleInstructionNote - | ModuleSetupNote - | ModuleTouchpoints - | ModuleAdditionalTarget - | ModuleEmployment - | ModuleLocality - | ModuleBank - | ModuleElettricitySupply - | ModuleMobileInternet - | ModuleHomeInternet - | ModuleGasSupply - | ModuleAnnualIncomeRange - | ModuleAcnSaver; export type PlanStatus = 'pending_review' | 'draft' | 'approved' | 'paying'; export type PurchasablePlanRules = | 'number_of_modules' @@ -3363,6 +3384,7 @@ export type CpReqTemplate = { }; export const { use$getQuery, + usePostAiAgentsGenerateVideoTasksMutation, usePostAnalyticsViewsCampaignsByCidMutation, usePostAuthenticateMutation, usePostBuyMutation, diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 224ced97d..2e3468f54 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -785,6 +785,23 @@ "__PLAN_PAGE_ADD_MODULE_BLOCK_BUTTON": "Add item", "__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_SUBTITLE": "Provide the necessary details to describe this activity", "__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_TITLE": "Available informations", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_ALERT_TEXT": "Describe the part of the experience you want to observe.
The study goal is already defined, so focus on the specific area or flow you want testers to explore. Example:

Area: car listing form
Context: users want to sell their car
Goal: understand if they experience difficulties while creating the ad", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_ALERT_TITLE": "What to include", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CANCEL_BUTTON": "Close", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_ANYWAY": "Confirm", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_BODY": "Heads up! Anything you've typed or started generating will be lost if you close this modal.", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_CANCEL": "Cancel", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_HEADER": "Are you sure you want to close?", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CREATE_BUTTON": "Generate tasks", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_ERROR": "Something went wrong. Please try again.", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_HEADER": "Create tasks with AI", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_INFO": "The AI will use the goal and setup of your activity to generate test tasks. Describe the specific areas of your product that testers should explore.", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_LABEL": "Which areas or flows should testers explore?", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_PLACEHOLDER": "Checkout – payment step\nPromo code field\nShipping address form", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_TOOLTIP": "Tests longer than 20 minutes may reduce data quality.
Most usability tests work best with 3–5 tasks.", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_STOP_BUTTON": "Stop Generation", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_SUCCESS_TOAST": "Tasks successfully generated! Review them below and save your plan to move forward.", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_TASKS_QUANTITY_LABEL": "Tasks to generate", "__PLAN_PAGE_BUY_BUTTON_LABEL": "Go to cart and launch", "__PLAN_PAGE_DELETE_PLAN_MODAL_BODY": "You're about to delete \"{{planTitle}}\".

This action will permanently remove all information you've entered.
After deletion, you'll be redirected to your Activities dashboard.
", "__PLAN_PAGE_DELETE_PLAN_MODAL_BUTTON_CANCEL": "Keep editing", @@ -1016,11 +1033,10 @@ "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_ACCESSIBILITY_TASK_ACCESSIBILITY_BUTTON": "Accessibility Task", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_ACCESSIBILITY_TASKS_LABEL": "Accessibility", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_BETA_TAG": "Beta", - "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_BETA_TOOLTIP": "New beta feature. We’re actively improving it, please review results before final use.", - "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_DISCLAIMER": "Want to speed things up? Generate structured functional tasks automatically based on your project details.", + "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_DISCLAIMER": "Want to speed things up? Generate structured tasks automatically based on your project details.", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_ALERT_TEXT": "List the key pages or flows you want tested. Example for 3 tasks:", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_ALERT_TITLE": "How to describe your areas:", - "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_BUTTON": "Create functional tasks AI", + "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_BUTTON": "Create tasks with AI", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_CANCEL": "Close", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_CONFIRM_CLOSE_BODY": "Heads up! Anything you’ve typed or started generating will be lost if you close this modal.", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_CONFIRM_CLOSE_CLOSE_ANYWAY": "Confirm", @@ -1054,6 +1070,7 @@ "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_SURVEY_TASK_SURVEY_BUTTON": "Survey", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_SURVEY_TASKS_LABEL": "Survey", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_TITLE": "Add task", + "__PLAN_PAGE_MODULE_TASKS_ADD_VIDEO_TASK_MODAL_AI_DISCLAIMER": "Want to speed things up? Automatically generate structured thinking-aloud test tasks for unmoderated tests based on your project details.", "__PLAN_PAGE_MODULE_TASKS_EXPERIENTIAL_TASK_MODERATE_DESCRIPTION_DEFAULT": "Insert moderate video task description", "__PLAN_PAGE_MODULE_TASKS_EXPERIENTIAL_TASK_MODERATE_TITLE_DEFAULT": "Moderate video", "__PLAN_PAGE_MODULE_TASKS_EXPERIENTIAL_TASK_THINKING_ALOUD_DESCRIPTION_DEFAULT": "Create a realistic situation for users to experience", diff --git a/src/locales/it/translation.json b/src/locales/it/translation.json index d2544ec98..6281e3c4c 100644 --- a/src/locales/it/translation.json +++ b/src/locales/it/translation.json @@ -815,6 +815,23 @@ "__PLAN_PAGE_ADD_MODULE_BLOCK_BUTTON": "", "__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_SUBTITLE": "", "__PLAN_PAGE_ADD_MODULE_BLOCK_MODAL_TITLE": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_ALERT_TEXT": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_ALERT_TITLE": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CANCEL_BUTTON": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_ANYWAY": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_BODY": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_CANCEL": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CONFIRM_CLOSE_HEADER": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_CREATE_BUTTON": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_ERROR": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_HEADER": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_INFO": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_LABEL": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_PLACEHOLDER": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_PROMPT_TOOLTIP": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_STOP_BUTTON": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_SUCCESS_TOAST": "", + "__PLAN_PAGE_ADD_VIDEO_TASK_MODAL_AI_TASKS_QUANTITY_LABEL": "", "__PLAN_PAGE_BUY_BUTTON_LABEL": "", "__PLAN_PAGE_DELETE_PLAN_MODAL_BODY": "", "__PLAN_PAGE_DELETE_PLAN_MODAL_BUTTON_CANCEL": "", @@ -1047,7 +1064,6 @@ "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_ACCESSIBILITY_TASK_ACCESSIBILITY_BUTTON": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_ACCESSIBILITY_TASKS_LABEL": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_BETA_TAG": "", - "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_BETA_TOOLTIP": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_AI_DISCLAIMER": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_ALERT_TEXT": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_CREATE_WITH_AI_ALERT_TITLE": "", @@ -1085,6 +1101,7 @@ "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_SURVEY_TASK_SURVEY_BUTTON": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_SURVEY_TASKS_LABEL": "", "__PLAN_PAGE_MODULE_TASKS_ADD_TASK_MODAL_TITLE": "", + "__PLAN_PAGE_MODULE_TASKS_ADD_VIDEO_TASK_MODAL_AI_DISCLAIMER": "", "__PLAN_PAGE_MODULE_TASKS_EXPERIENTIAL_TASK_MODERATE_DESCRIPTION_DEFAULT": "", "__PLAN_PAGE_MODULE_TASKS_EXPERIENTIAL_TASK_MODERATE_TITLE_DEFAULT": "", "__PLAN_PAGE_MODULE_TASKS_EXPERIENTIAL_TASK_THINKING_ALOUD_DESCRIPTION_DEFAULT": "", diff --git a/src/pages/Plan/modules/Factory/modules/Tasks/Component/context/index.tsx b/src/pages/Plan/modules/Factory/modules/Tasks/Component/context/index.tsx index c66c651cb..23438842a 100644 --- a/src/pages/Plan/modules/Factory/modules/Tasks/Component/context/index.tsx +++ b/src/pages/Plan/modules/Factory/modules/Tasks/Component/context/index.tsx @@ -5,6 +5,8 @@ interface ModuleTasksContextType { setModalRef: (ref: HTMLButtonElement | null) => void; isOpenCreateTasksWithAIModal: boolean; setIsOpenCreateTasksWithAIModal: (value: boolean) => void; + isOpenCreateVideoTasksWithAIModal: boolean; + setIsOpenCreateVideoTasksWithAIModal: (value: boolean) => void; } const ModuleTasksContext = createContext(null); @@ -18,6 +20,10 @@ export const ModuleTasksContextProvider = ({ useState(null); const [isOpenCreateTasksWithAIModal, setIsOpenCreateTasksWithAIModal] = useState(false); + const [ + isOpenCreateVideoTasksWithAIModal, + setIsOpenCreateVideoTasksWithAIModal, + ] = useState(false); const moduleTasksContextValue = useMemo( () => ({ @@ -25,8 +31,15 @@ export const ModuleTasksContextProvider = ({ setModalRef, isOpenCreateTasksWithAIModal, setIsOpenCreateTasksWithAIModal, + isOpenCreateVideoTasksWithAIModal, + setIsOpenCreateVideoTasksWithAIModal, }), - [modalRef, setModalRef, isOpenCreateTasksWithAIModal] + [ + modalRef, + setModalRef, + isOpenCreateTasksWithAIModal, + isOpenCreateVideoTasksWithAIModal, + ] ); return ( diff --git a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/TasksList.tsx b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/TasksList.tsx index 001634a56..46c089aee 100644 --- a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/TasksList.tsx +++ b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/TasksList.tsx @@ -16,11 +16,9 @@ import useWindowSize from 'src/hooks/useWindowSize'; import { DeleteModuleConfirmationModal } from 'src/pages/Plan/modules/modal/DeleteModuleConfirmationModal'; import styled from 'styled-components'; import { useIconWithValidation } from '../../useIcon'; -import { useModuleTasksContext } from '../context'; import { useModuleTasks } from '../hooks'; import { AddTaskButton } from './AddTaskButton'; import { TasksModal } from './modal'; -import { CreateTaskListsWithAI } from './modal/CreateTaskListsWithAI'; import { TasksContainerAnimation } from './TasksContainerAnimation'; const StyledCard = styled(ContainerCard)` @@ -53,7 +51,6 @@ const TasksList = () => { const { getPlanStatus } = useModuleConfiguration(); const { t } = useTranslation(); const { hasFeatureFlag } = useFeatureFlag(); - const { isOpenCreateTasksWithAIModal } = useModuleTasksContext(); const [isOpenDeleteModal, setIsOpenDeleteModal] = useState(false); const Icon = useIconWithValidation(); const { width } = useWindowSize(); @@ -132,7 +129,6 @@ const TasksList = () => { onConfirm={remove} /> )} - {isOpenCreateTasksWithAIModal && } ); }; diff --git a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/modal/AiGeneratorSection.tsx b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/modal/AiGeneratorSection.tsx index 49a196131..298703c26 100644 --- a/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/modal/AiGeneratorSection.tsx +++ b/src/pages/Plan/modules/Factory/modules/Tasks/Component/parts/modal/AiGeneratorSection.tsx @@ -1,5 +1,5 @@ import { Button, MD, Tag } from '@appquality/unguess-design-system'; -import { useMemo } from 'react'; +import { ReactNode, useMemo } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { appTheme } from 'src/app/theme'; import { ReactComponent as AiIcon } from 'src/assets/icons/ai-icon.svg'; @@ -8,22 +8,31 @@ import { useCanShowAiChat } from 'src/pages/Dashboard/hooks/useCanShowAiChat'; type AiGeneratorSectionProps = { onOpenCreateWithAI: () => void; + checkApiHealth?: boolean; + label?: ReactNode; }; const AiGeneratorSection = ({ onOpenCreateWithAI, + checkApiHealth = true, + label, }: AiGeneratorSectionProps) => { const { t } = useTranslation(); const canShowChat = useCanShowAiChat(); - const { data: apiK_HealthResponse } = useGetServicesApiKHealthQuery(); - - const canShowAiFeatures = useMemo( - () => - canShowChat && - apiK_HealthResponse?.success && - apiK_HealthResponse?.status === 'healthy', - [apiK_HealthResponse, canShowChat] + const { data: apiK_HealthResponse } = useGetServicesApiKHealthQuery( + undefined, + { + skip: !checkApiHealth, + } ); + + const canShowAiFeatures = useMemo(() => { + if (!canShowChat) return false; + if (!checkApiHealth) return true; + return ( + apiK_HealthResponse?.success && apiK_HealthResponse?.status === 'healthy' + ); + }, [apiK_HealthResponse, canShowChat, checkApiHealth]); if (!canShowAiFeatures) { return null; } @@ -39,12 +48,14 @@ const AiGeneratorSection = ({ marginBottom: appTheme.space.md, }} > - , - }} - /> + {label || ( + , + }} + /> + )}