Traduz e corrige os relatórios de insights do Capitão: centraliza traduções, corrige fuso horário na data e adiciona polling automático
This commit is contained in:
parent
dc3d1bbcf7
commit
9a7599d971
@ -1,5 +1,4 @@
|
||||
class Api::V1::Accounts::Captain::Reports::InsightsController < Api::V1::Accounts::BaseController
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def index
|
||||
unit_id = params[:unit_id].present? ? params[:unit_id].to_i : nil
|
||||
inbox_id = params[:inbox_id].present? ? params[:inbox_id].to_i : nil
|
||||
@ -7,13 +6,11 @@ class Api::V1::Accounts::Captain::Reports::InsightsController < Api::V1::Account
|
||||
scope = Captain::ConversationInsight.where(account_id: Current.account.id)
|
||||
scope = scope.where(captain_unit_id: unit_id) if unit_id
|
||||
scope = scope.where(inbox_id: inbox_id) if inbox_id
|
||||
scope = scope.where(captain_unit_id: nil, inbox_id: nil) if !unit_id && !inbox_id
|
||||
|
||||
insights = scope.order(period_start: :desc).limit(12)
|
||||
|
||||
render json: insights.map { |i| format_insight(i) }
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def show
|
||||
insight = Captain::ConversationInsight.find_by!(
|
||||
|
||||
@ -57,6 +57,7 @@
|
||||
"SCHEDULED": "Scheduled",
|
||||
"PENDING_PAYMENT": "Awaiting payment",
|
||||
"ACTIVE": "Active",
|
||||
"CONFIRMED": "Confirmed",
|
||||
"COMPLETED": "Completed",
|
||||
"CANCELLED": "Cancelled",
|
||||
"DRAFT": "Draft"
|
||||
@ -298,5 +299,100 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"CAPTAIN": {
|
||||
"BANNER": {
|
||||
"RESPONSES": "You have used more than 80% of your responses limit. To continue using Captain AI, please upgrade.",
|
||||
"DOCUMENTS": "Documents limit reached. Please upgrade to continue using Captain AI."
|
||||
},
|
||||
"FORM": {
|
||||
"CANCEL": "Cancel",
|
||||
"CREATE": "Create",
|
||||
"EDIT": "Update"
|
||||
},
|
||||
"RESPONSES": {
|
||||
"HEADER": "FAQs",
|
||||
"PENDING_FAQS": "Pending FAQs",
|
||||
"ADD_NEW": "Create new FAQ",
|
||||
"DOCUMENTABLE": {
|
||||
"CONVERSATION": "Conversation #{id}"
|
||||
},
|
||||
"SELECTED": "{count} selected",
|
||||
"SELECT_ALL": "Select all ({count})",
|
||||
"UNSELECT_ALL": "Unselect all ({count})",
|
||||
"SEARCH_PLACEHOLDER": "Search FAQs...",
|
||||
"BULK_APPROVE_BUTTON": "Approve",
|
||||
"BULK_DELETE_BUTTON": "Delete",
|
||||
"BULK_APPROVE": {
|
||||
"SUCCESS_MESSAGE": "FAQs approved successfully",
|
||||
"ERROR_MESSAGE": "An error occurred while approving FAQs. Try again."
|
||||
},
|
||||
"BULK_DELETE": {
|
||||
"TITLE": "Delete FAQs?",
|
||||
"DESCRIPTION": "Are you sure you want to delete selected FAQs? This action cannot be undone.",
|
||||
"CONFIRM": "Yes, delete all",
|
||||
"SUCCESS_MESSAGE": "FAQs deleted successfully",
|
||||
"ERROR_MESSAGE": "An error occurred while deleting FAQs, please try again."
|
||||
},
|
||||
"DELETE": {
|
||||
"TITLE": "Are you sure you want to delete this FAQ?",
|
||||
"DESCRIPTION": "",
|
||||
"CONFIRM": "Yes, delete",
|
||||
"SUCCESS_MESSAGE": "FAQ deleted successfully",
|
||||
"ERROR_MESSAGE": "An error occurred while deleting FAQ, please try again."
|
||||
}
|
||||
}
|
||||
},
|
||||
"CAPTAIN_REPORTS": {
|
||||
"TITLE": "AI Reports",
|
||||
"DESC": "Weekly AI-generated insights based on each unit's conversations.",
|
||||
"LOADING": "Loading reports...",
|
||||
"ALL_UNITS": "All units",
|
||||
"ALL_INBOXES": "All inboxes",
|
||||
"UNITS_GROUP": "Pix Units",
|
||||
"INBOXES_GROUP": "Inboxes",
|
||||
"TABS": {
|
||||
"INSIGHTS": "AI Insights",
|
||||
"OPERATIONAL": "Operational"
|
||||
},
|
||||
"FILTER_DATE": {
|
||||
"LABEL": "Period:",
|
||||
"START": "Start Date",
|
||||
"END": "End Date",
|
||||
"LAST_7_DAYS": "Last 7 days",
|
||||
"LAST_WEEK": "Last Week",
|
||||
"CURRENT_MONTH": "Current Month",
|
||||
"CUSTOM": "Custom",
|
||||
"SEPARATOR": "-"
|
||||
},
|
||||
"INSIGHT": {
|
||||
"CONVERSATIONS": "conversations",
|
||||
"MESSAGES": "messages",
|
||||
"TOP_TOPICS": "Top Topics",
|
||||
"AI_FAILURES": "AI Failures",
|
||||
"BULLET": "•",
|
||||
"COUNT_PREFIX": "(",
|
||||
"COUNT_SUFFIX": ")"
|
||||
},
|
||||
"EMPTY": {
|
||||
"TITLE": "No reports generated",
|
||||
"MESSAGE": "Generate a new report to analyze support performance."
|
||||
},
|
||||
"GENERATE": {
|
||||
"BUTTON": "Generate Analysis",
|
||||
"SUCCESS": "Report requested successfully! It may take a few minutes.",
|
||||
"ERROR": "Error requesting report generation.",
|
||||
"DATE_REQUIRED": "Please select start and end dates."
|
||||
},
|
||||
"STATUS": {
|
||||
"PENDING": "Pending",
|
||||
"PROCESSING": "Processing",
|
||||
"DONE": "Completed",
|
||||
"FAILED": "Failed"
|
||||
},
|
||||
"OPERATIONAL": {
|
||||
"COMING_SOON": "Coming soon",
|
||||
"COMING_SOON_DESC": "Real-time operational data (reservations, Pix charges, etc.) will be available here soon."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1021,44 +1021,5 @@
|
||||
"CONFIRM_BUTTON_LABEL": "Delete",
|
||||
"CANCEL_BUTTON_LABEL": "Cancel"
|
||||
}
|
||||
},
|
||||
"CAPTAIN_REPORTS": {
|
||||
"TITLE": "AI Reports",
|
||||
"DESC": "Weekly AI-generated insights based on conversations from each inbox.",
|
||||
"LOADING": "Loading reports...",
|
||||
"ALL_UNITS": "All units",
|
||||
"ALL_INBOXES": "All inboxes",
|
||||
"TABS": {
|
||||
"INSIGHTS": "AI Insights",
|
||||
"OPERATIONAL": "Operational"
|
||||
},
|
||||
"STATUS": {
|
||||
"PENDING": "Pending",
|
||||
"PROCESSING": "Processing",
|
||||
"DONE": "Completed",
|
||||
"FAILED": "Failed"
|
||||
},
|
||||
"GENERATE": {
|
||||
"BUTTON": "Generate Analysis",
|
||||
"SUCCESS": "Analysis queued successfully! It will be available shortly.",
|
||||
"ERROR": "Error requesting analysis. Please try again."
|
||||
},
|
||||
"INSIGHT": {
|
||||
"CONVERSATIONS": "conversations",
|
||||
"MESSAGES": "messages",
|
||||
"TOP_TOPICS": "Top Topics",
|
||||
"AI_FAILURES": "AI Improvement Points",
|
||||
"COUNT_PREFIX": "(",
|
||||
"COUNT_SUFFIX": ")",
|
||||
"BULLET": "•"
|
||||
},
|
||||
"EMPTY": {
|
||||
"TITLE": "No analysis available",
|
||||
"MESSAGE": "Click Generate Analysis to create the first weekly report with conversation insights."
|
||||
},
|
||||
"OPERATIONAL": {
|
||||
"COMING_SOON": "Coming Soon",
|
||||
"COMING_SOON_DESC": "Real-time operational data (reservations, Pix charges, etc.) will be available here soon."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,8 +302,8 @@
|
||||
},
|
||||
"CAPTAIN": {
|
||||
"BANNER": {
|
||||
"RESPONSES": "Você usou mais de 80% do seu limite de respostas. Para continuar usando o Captain AI, faça um upgrade.",
|
||||
"DOCUMENTS": "Limite de documentos atingido. Faça um upgrade para continuar usando o Captain AI."
|
||||
"RESPONSES": "Você usou mais de 80% do seu limite de respostas. Para continuar usando o Capitão IA, faça um upgrade.",
|
||||
"DOCUMENTS": "Limite de documentos atingido. Faça um upgrade para continuar usando o Capitão IA."
|
||||
},
|
||||
"FORM": {
|
||||
"CANCEL": "Cancelar",
|
||||
@ -312,7 +312,7 @@
|
||||
},
|
||||
"RESPONSES": {
|
||||
"HEADER": "FAQs",
|
||||
"PENDING_FAQS": "Pending FAQs",
|
||||
"PENDING_FAQS": "FAQs Pendentes",
|
||||
"ADD_NEW": "Criar nova FAQ",
|
||||
"DOCUMENTABLE": {
|
||||
"CONVERSATION": "Conversação #{id}"
|
||||
@ -325,13 +325,13 @@
|
||||
"BULK_DELETE_BUTTON": "Excluir",
|
||||
"BULK_APPROVE": {
|
||||
"SUCCESS_MESSAGE": "Perguntas Frequentes aprovadas com sucesso",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao aprovar as Perguntas Frequentes. Tente novamente."
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao aproveitar as Perguntas Frequentes. Tente novamente."
|
||||
},
|
||||
"BULK_DELETE": {
|
||||
"TITLE": "Excluir as Perguntas Frequentes?",
|
||||
"DESCRIPTION": "Tem certeza que deseja excluir as Perguntas Frequentes selecionadas? Esta ação não pode ser desfeita.",
|
||||
"CONFIRM": "Sim, excluir todas",
|
||||
"SUCCESS_MESSAGE": "Perguntas Frequentes excluídas com sucesso/",
|
||||
"SUCCESS_MESSAGE": "Perguntas Frequentes excluídas com sucesso",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao excluir as Perguntas Frequentes, por favor tente novamente."
|
||||
},
|
||||
"DELETE": {
|
||||
@ -340,66 +340,59 @@
|
||||
"CONFIRM": "Sim, excluir",
|
||||
"SUCCESS_MESSAGE": "FAQ excluída com sucesso",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao excluir a FAQ, por favor tente novamente."
|
||||
},
|
||||
"FILTER": {
|
||||
"ASSISTANT": "Assistente: {selected}",
|
||||
"STATUS": "Status: {selected}",
|
||||
"ALL_ASSISTANTS": "Todos"
|
||||
},
|
||||
"STATUS": {
|
||||
"TITLE": "Status",
|
||||
"PENDING": "Pendentes",
|
||||
"APPROVED": "Aceito",
|
||||
"ALL": "Todos"
|
||||
},
|
||||
"PENDING_BANNER": {
|
||||
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||
"ACTION": "Click here to review"
|
||||
},
|
||||
"FORM_DESCRIPTION": "Adicione uma pergunta e sua resposta correspondente à base de conhecimento e selecione o assistente ao qual deve estar associado.",
|
||||
"CREATE": {
|
||||
"TITLE": "Adicionar uma FAQ",
|
||||
"SUCCESS_MESSAGE": "A resposta foi adicionada com sucesso.",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao adicionar a resposta. Por favor, tente novamente."
|
||||
},
|
||||
"FORM": {
|
||||
"QUESTION": {
|
||||
"LABEL": "Pergunta",
|
||||
"PLACEHOLDER": "Digite a pergunta aqui",
|
||||
"ERROR": "Por favor, forneça uma pergunta válida."
|
||||
},
|
||||
"ANSWER": {
|
||||
"LABEL": "Responder",
|
||||
"PLACEHOLDER": "Digite a resposta aqui",
|
||||
"ERROR": "Por favor, forneça uma resposta válida."
|
||||
},
|
||||
"ASSISTANT": {
|
||||
"LABEL": "Assistente",
|
||||
"PLACEHOLDER": "Selecione um assistente",
|
||||
"ERROR": "Por favor, selecione um assistente."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Atualizar as Perguntas Frequentes",
|
||||
"SUCCESS_MESSAGE": "As Perguntas Frequentes foram atualizadas com sucesso",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao atualizar as Perguntas Frequentes, por favor tente novamente",
|
||||
"APPROVE_SUCCESS_MESSAGE": "As Perguntas Frequentes foram marcadas como aprovadas"
|
||||
},
|
||||
"OPTIONS": {
|
||||
"APPROVE": "Aprovar",
|
||||
"EDIT_RESPONSE": "Alterar",
|
||||
"DELETE_RESPONSE": "Excluir"
|
||||
},
|
||||
"EMPTY_STATE": {
|
||||
"TITLE": "Nenhuma FAQ encontrada",
|
||||
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||
"SUBTITLE": "Perguntas Frequentes ajudam seu assistente a fornecer respostas rápidas e precisas para perguntas de seus clientes. Eles podem ser gerados automaticamente a partir do seu conteúdo ou podem ser adicionados manualmente.",
|
||||
"CLEAR_SEARCH": "Clear active filters",
|
||||
"FEATURE_SPOTLIGHT": {
|
||||
"TITLE": "Captain FAQ",
|
||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"CAPTAIN_REPORTS": {
|
||||
"TITLE": "Relatórios IA",
|
||||
"DESC": "Análises semanais geradas por IA com base nas conversas de cada unidade.",
|
||||
"LOADING": "Carregando relatórios...",
|
||||
"ALL_UNITS": "Todas as unidades",
|
||||
"ALL_INBOXES": "Todas as caixas de entrada",
|
||||
"UNITS_GROUP": "Unidades Pix",
|
||||
"INBOXES_GROUP": "Caixas de Entrada",
|
||||
"TABS": {
|
||||
"INSIGHTS": "Insights IA",
|
||||
"OPERATIONAL": "Operacional"
|
||||
},
|
||||
"FILTER_DATE": {
|
||||
"LABEL": "Período:",
|
||||
"START": "Data Início",
|
||||
"END": "Data Fim",
|
||||
"LAST_7_DAYS": "Últimos 7 dias",
|
||||
"LAST_WEEK": "Semana Passada",
|
||||
"CURRENT_MONTH": "Mês Atual",
|
||||
"CUSTOM": "Personalizado",
|
||||
"SEPARATOR": "-"
|
||||
},
|
||||
"INSIGHT": {
|
||||
"CONVERSATIONS": "conversas",
|
||||
"MESSAGES": "mensagens",
|
||||
"TOP_TOPICS": "Principais tópicos",
|
||||
"AI_FAILURES": "Falhas da IA",
|
||||
"BULLET": "•",
|
||||
"COUNT_PREFIX": "(",
|
||||
"COUNT_SUFFIX": ")"
|
||||
},
|
||||
"EMPTY": {
|
||||
"TITLE": "Nenhum relatório gerado",
|
||||
"MESSAGE": "Gere um novo relatório para analisar o desempenho do atendimento."
|
||||
},
|
||||
"GENERATE": {
|
||||
"BUTTON": "Gerar Análise",
|
||||
"SUCCESS": "Relatório solicitado com sucesso! Pode levar alguns minutos.",
|
||||
"ERROR": "Erro ao solicitar geração do relatório.",
|
||||
"DATE_REQUIRED": "Por favor, selecione as datas de início e fim."
|
||||
},
|
||||
"STATUS": {
|
||||
"PENDING": "Pendente",
|
||||
"PROCESSING": "Processando",
|
||||
"DONE": "Concluído",
|
||||
"FAILED": "Falhou"
|
||||
},
|
||||
"OPERATIONAL": {
|
||||
"COMING_SOON": "Em breve",
|
||||
"COMING_SOON_DESC": "Os dados operacionais em tempo real (reservas, cobranças Pix, etc.) estarão disponíveis aqui em breve."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,12 +361,12 @@
|
||||
},
|
||||
"CAPTAIN": {
|
||||
"NAME": "Capitão",
|
||||
"HEADER_KNOW_MORE": "Know more",
|
||||
"HEADER_KNOW_MORE": "Saiba mais",
|
||||
"ASSISTANT_SWITCHER": {
|
||||
"ASSISTANTS": "Assistentes",
|
||||
"SWITCH_ASSISTANT": "Switch between assistants",
|
||||
"NEW_ASSISTANT": "Create Assistant",
|
||||
"EMPTY_LIST": "No assistants found, please create one to get started"
|
||||
"SWITCH_ASSISTANT": "Alternar entre assistentes",
|
||||
"NEW_ASSISTANT": "Criar Assistente",
|
||||
"EMPTY_LIST": "Nenhum assistente encontrado, crie um para começar"
|
||||
},
|
||||
"COPILOT": {
|
||||
"TITLE": "Copiloto",
|
||||
@ -558,8 +558,8 @@
|
||||
"TITLE": "Não há assistentes disponíveis",
|
||||
"SUBTITLE": "Crie um assistente para fornecer respostas rápidas e precisas aos seus usuários. Ele pode aprender com seus artigos de ajuda e conversas passadas.",
|
||||
"FEATURE_SPOTLIGHT": {
|
||||
"TITLE": "Captain Assistant",
|
||||
"NOTE": "Captain Assistant engages directly with customers, learns from your help docs and past conversations, and delivers instant, accurate responses. It handles the initial queries, providing quick resolutions before transferring to an agent when needed."
|
||||
"TITLE": "Assistente Capitão",
|
||||
"NOTE": "O Assistente Capitão interage diretamente com os clientes, aprende com seus documentos de ajuda e conversas passadas, e entrega respostas instantâneas e precisas. Ele lida com as perguntas iniciais, fornecendo resoluções rápidas antes de transferir para um agente quando necessário."
|
||||
}
|
||||
},
|
||||
"GUARDRAILS": {
|
||||
@ -769,8 +769,8 @@
|
||||
"TITLE": "Nenhum documento disponível",
|
||||
"SUBTITLE": "Os documentos são usados pelo seu assistente para gerar perguntas frequentes. Pode importar documentos para fornecer um contexto para seu assistente.",
|
||||
"FEATURE_SPOTLIGHT": {
|
||||
"TITLE": "Captain Document",
|
||||
"NOTE": "A document in Captain serves as a knowledge resource for the assistant. By connecting your help center or guides, Captain can analyze the content and provide accurate responses for customer inquiries."
|
||||
"TITLE": "Documento do Capitão",
|
||||
"NOTE": "Um documento no Capitão serve como um recurso de conhecimento para o assistente. Ao conectar sua central de ajuda ou guias, o Capitão pode analisar o conteúdo e fornecer respostas precisas para as consultas dos clientes."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -782,110 +782,118 @@
|
||||
"SUBTITLE": "Crie ferramentas personalizadas para conectar com APIs e serviços externos, permitindo obter dados e agir por você.",
|
||||
"FEATURE_SPOTLIGHT": {
|
||||
"TITLE": "Ferramentas Personalizadas",
|
||||
"NOTE": "Ferramentas personalizadas permitem seu assistente interagir com APIs e serviços externos. Crie ferramentas para obter dados, realizar ações ou integre com seus sistemas existentes para melhorar as capacidades do seu assistente."
|
||||
"NOTE": "As ferramentas personalizadas permitem que seu assistente interaja com APIs e serviços externos. Crie ferramentas para buscar dados, realizar ações ou integrar-se aos seus sistemas existentes para aprimorar as capacidades do seu assistente."
|
||||
}
|
||||
},
|
||||
"FORM_DESCRIPTION": "Configure your custom tool to connect with external APIs",
|
||||
"FORM_DESCRIPTION": "Configure sua ferramenta personalizada para conectar-se a APIs externas",
|
||||
"OPTIONS": {
|
||||
"EDIT_TOOL": "Edit tool",
|
||||
"DELETE_TOOL": "Delete tool"
|
||||
"EDIT_TOOL": "Editar ferramenta",
|
||||
"DELETE_TOOL": "Excluir ferramenta"
|
||||
},
|
||||
"CREATE": {
|
||||
"TITLE": "Create Custom Tool",
|
||||
"SUCCESS_MESSAGE": "Custom tool created successfully",
|
||||
"ERROR_MESSAGE": "Failed to create custom tool"
|
||||
"TITLE": "Criar Ferramenta Personalizada",
|
||||
"SUCCESS_MESSAGE": "Ferramenta personalizada criada com sucesso",
|
||||
"ERROR_MESSAGE": "Falha ao criar ferramenta personalizada"
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit Custom Tool",
|
||||
"SUCCESS_MESSAGE": "Custom tool updated successfully",
|
||||
"ERROR_MESSAGE": "Failed to update custom tool"
|
||||
"TITLE": "Editar Ferramenta Personalizada",
|
||||
"SUCCESS_MESSAGE": "Ferramenta personalizada atualizada com sucesso",
|
||||
"ERROR_MESSAGE": "Falha ao atualizar ferramenta personalizada"
|
||||
},
|
||||
"DELETE": {
|
||||
"TITLE": "Delete Custom Tool",
|
||||
"TITLE": "Excluir Ferramenta Personalizada",
|
||||
"DESCRIPTION": "Tem certeza que deseja excluir está ferramenta customizável? Está ação não pode ser desfeita.",
|
||||
"CONFIRM": "Sim, excluir",
|
||||
"SUCCESS_MESSAGE": "Custom tool deleted successfully",
|
||||
"ERROR_MESSAGE": "Failed to delete custom tool"
|
||||
"SUCCESS_MESSAGE": "Ferramenta personalizada excluída com sucesso",
|
||||
"ERROR_MESSAGE": "Falha ao excluir ferramenta personalizada"
|
||||
},
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Nome da Ferramenta",
|
||||
"PLACEHOLDER": "Order Lookup",
|
||||
"ERROR": "Nome da ferramente obrigatória"
|
||||
"PLACEHOLDER": "Ex: Busca de Pedidos",
|
||||
"ERROR": "O nome da ferramenta é obrigatório"
|
||||
},
|
||||
"DESCRIPTION": {
|
||||
"LABEL": "Descrição",
|
||||
"PLACEHOLDER": "Looks up order details by order ID"
|
||||
"PLACEHOLDER": "Descreva o que a ferramenta faz (ex: Busca detalhes do pedido pelo ID)"
|
||||
},
|
||||
"HTTP_METHOD": {
|
||||
"LABEL": "Method"
|
||||
"LABEL": "Método HTTP"
|
||||
},
|
||||
"ENDPOINT_URL": {
|
||||
"LABEL": "Endpoint URL",
|
||||
"PLACEHOLDER": "https://api.example.com/orders/{'{{'} order_id {'}}'}",
|
||||
"ERROR": "Valid URL is required"
|
||||
"LABEL": "URL do Endpoint",
|
||||
"PLACEHOLDER": "https://api.exemplo.com/pedidos/{'{{'} order_id {'}}'}",
|
||||
"ERROR": "Uma URL válida é obrigatória"
|
||||
},
|
||||
"AUTH_TYPE": {
|
||||
"LABEL": "Authentication Type"
|
||||
"LABEL": "Tipo de Autenticação"
|
||||
},
|
||||
"AUTH_TYPES": {
|
||||
"NONE": "Nenhuma",
|
||||
"BEARER": "Bearer Token",
|
||||
"BASIC": "Basic Auth",
|
||||
"API_KEY": "Chave API"
|
||||
"BEARER": "Token Bearer",
|
||||
"BASIC": "Autenticação Básica (Basic Auth)",
|
||||
"API_KEY": "Chave de API",
|
||||
"CUSTOM_HEADERS": "Cabeçalhos Personalizados"
|
||||
},
|
||||
"AUTH_CONFIG": {
|
||||
"BEARER_TOKEN": "Bearer Token",
|
||||
"BEARER_TOKEN_PLACEHOLDER": "Enter your bearer token",
|
||||
"USERNAME": "Username",
|
||||
"USERNAME_PLACEHOLDER": "Enter username",
|
||||
"BEARER_TOKEN": "Token Bearer",
|
||||
"BEARER_TOKEN_PLACEHOLDER": "Digite seu token bearer",
|
||||
"USERNAME": "Usuário",
|
||||
"USERNAME_PLACEHOLDER": "Digite o usuário",
|
||||
"PASSWORD": "Senha",
|
||||
"PASSWORD_PLACEHOLDER": "Enter password",
|
||||
"API_KEY": "Header Name",
|
||||
"PASSWORD_PLACEHOLDER": "Digite a senha",
|
||||
"API_KEY": "Nome do Cabeçalho",
|
||||
"API_KEY_PLACEHOLDER": "X-API-Key",
|
||||
"API_VALUE": "Header Value",
|
||||
"API_VALUE_PLACEHOLDER": "Enter API key value"
|
||||
"API_VALUE": "Valor do Cabeçalho",
|
||||
"API_VALUE_PLACEHOLDER": "Digite o valor da chave de API",
|
||||
"CUSTOM_HEADERS": "Cabeçalhos Personalizados",
|
||||
"CUSTOM_HEADERS_HELP": "Adicione um ou mais cabeçalhos HTTP enviados em cada solicitação (ex: IDs de API, tokens).",
|
||||
"HEADER_NAME": "Nome do Cabeçalho",
|
||||
"HEADER_NAME_PLACEHOLDER": "ex: PLUG-PLAY-ID",
|
||||
"HEADER_VALUE": "Valor do Cabeçalho",
|
||||
"HEADER_VALUE_PLACEHOLDER": "ex: 198",
|
||||
"ADD_HEADER": "Adicionar Cabeçalho"
|
||||
},
|
||||
"PARAMETERS": {
|
||||
"LABEL": "Parameters",
|
||||
"HELP_TEXT": "Define the parameters that will be extracted from user queries"
|
||||
"LABEL": "Parâmetros",
|
||||
"HELP_TEXT": "Defina os parâmetros que serão extraídos das perguntas dos usuários"
|
||||
},
|
||||
"ADD_PARAMETER": "Add Parameter",
|
||||
"ADD_PARAMETER": "Adicionar Parâmetro",
|
||||
"PARAM_NAME": {
|
||||
"PLACEHOLDER": "Parameter name (e.g., order_id)"
|
||||
"PLACEHOLDER": "Nome do parâmetro (ex: order_id)"
|
||||
},
|
||||
"PARAM_TYPE": {
|
||||
"PLACEHOLDER": "Tipo"
|
||||
},
|
||||
"PARAM_TYPES": {
|
||||
"STRING": "String",
|
||||
"STRING": "Texto (String)",
|
||||
"NUMBER": "Número",
|
||||
"BOOLEAN": "Boolean",
|
||||
"ARRAY": "Array",
|
||||
"OBJECT": "Object"
|
||||
"BOOLEAN": "Booleano",
|
||||
"ARRAY": "Lista (Array)",
|
||||
"OBJECT": "Objeto"
|
||||
},
|
||||
"PARAM_DESCRIPTION": {
|
||||
"PLACEHOLDER": "Description of the parameter"
|
||||
"PLACEHOLDER": "Descrição do parâmetro"
|
||||
},
|
||||
"PARAM_REQUIRED": {
|
||||
"LABEL": "Obrigatório"
|
||||
},
|
||||
"REQUEST_TEMPLATE": {
|
||||
"LABEL": "Request Body Template (Optional)",
|
||||
"LABEL": "Modelo do Corpo da Requisição (Opcional)",
|
||||
"PLACEHOLDER": "{'{'}\n \"order_id\": \"{'{{'} order_id {'}}'}\"\n{'}'}"
|
||||
},
|
||||
"RESPONSE_TEMPLATE": {
|
||||
"LABEL": "Response Template (Optional)",
|
||||
"PLACEHOLDER": "Order {'{{'} order_id {'}}'} status: {'{{'} status {'}}'}"
|
||||
"LABEL": "Modelo de Resposta (Opcional)",
|
||||
"PLACEHOLDER": "Status do pedido {'{{'} order_id {'}}'}: {'{{'} status {'}}'}"
|
||||
},
|
||||
"ERRORS": {
|
||||
"PARAM_NAME_REQUIRED": "Parameter name is required"
|
||||
"PARAM_NAME_REQUIRED": "O nome do parâmetro é obrigatório"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RESPONSES": {
|
||||
"HEADER": "FAQs",
|
||||
"PENDING_FAQS": "Pending FAQs",
|
||||
"HEADER": "Perguntas Frequentes (FAQs)",
|
||||
"PENDING_FAQS": "FAQs Pendentes",
|
||||
"ADD_NEW": "Criar nova FAQ",
|
||||
"DOCUMENTABLE": {
|
||||
"CONVERSATION": "Conversação #{id}"
|
||||
@ -904,11 +912,11 @@
|
||||
"TITLE": "Excluir as Perguntas Frequentes?",
|
||||
"DESCRIPTION": "Tem certeza que deseja excluir as Perguntas Frequentes selecionadas? Esta ação não pode ser desfeita.",
|
||||
"CONFIRM": "Sim, excluir todas",
|
||||
"SUCCESS_MESSAGE": "Perguntas Frequentes excluídas com sucesso/",
|
||||
"SUCCESS_MESSAGE": "Perguntas Frequentes excluídas com sucesso",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao excluir as Perguntas Frequentes, por favor tente novamente."
|
||||
},
|
||||
"DELETE": {
|
||||
"TITLE": "Tem certeza que deseja excluir o FAQ?",
|
||||
"TITLE": "Tem certeza que deseja excluir a FAQ?",
|
||||
"DESCRIPTION": "",
|
||||
"CONFIRM": "Sim, excluir",
|
||||
"SUCCESS_MESSAGE": "FAQ excluída com sucesso",
|
||||
@ -922,12 +930,12 @@
|
||||
"STATUS": {
|
||||
"TITLE": "Status",
|
||||
"PENDING": "Pendentes",
|
||||
"APPROVED": "Aceito",
|
||||
"APPROVED": "Aprovadas",
|
||||
"ALL": "Todos"
|
||||
},
|
||||
"PENDING_BANNER": {
|
||||
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||
"ACTION": "Click here to review"
|
||||
"TITLE": "O Capitão encontrou algumas FAQs que seus clientes estavam procurando.",
|
||||
"ACTION": "Clique aqui para revisar"
|
||||
},
|
||||
"FORM_DESCRIPTION": "Adicione uma pergunta e sua resposta correspondente à base de conhecimento e selecione o assistente ao qual deve estar associado.",
|
||||
"CREATE": {
|
||||
@ -942,13 +950,13 @@
|
||||
"ERROR": "Por favor, forneça uma pergunta válida."
|
||||
},
|
||||
"ANSWER": {
|
||||
"LABEL": "Responder",
|
||||
"LABEL": "Resposta",
|
||||
"PLACEHOLDER": "Digite a resposta aqui",
|
||||
"ERROR": "Por favor, forneça uma resposta válida."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Atualizar as Perguntas Frequentes",
|
||||
"TITLE": "Atualizar a FAQ",
|
||||
"SUCCESS_MESSAGE": "As Perguntas Frequentes foram atualizadas com sucesso",
|
||||
"ERROR_MESSAGE": "Ocorreu um erro ao atualizar as Perguntas Frequentes, por favor tente novamente",
|
||||
"APPROVE_SUCCESS_MESSAGE": "As Perguntas Frequentes foram marcadas como aprovadas"
|
||||
@ -960,12 +968,12 @@
|
||||
},
|
||||
"EMPTY_STATE": {
|
||||
"TITLE": "Nenhuma FAQ encontrada",
|
||||
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||
"SUBTITLE": "Perguntas Frequentes ajudam seu assistente a fornecer respostas rápidas e precisas para perguntas de seus clientes. Eles podem ser gerados automaticamente a partir do seu conteúdo ou podem ser adicionados manualmente.",
|
||||
"CLEAR_SEARCH": "Clear active filters",
|
||||
"NO_PENDING_TITLE": "Não há mais FAQs pendentes para revisar",
|
||||
"SUBTITLE": "As Perguntas Frequentes ajudam seu assistente a fornecer respostas rápidas e precisas para as perguntas de seus clientes. Elas podem ser geradas automaticamente a partir do seu conteúdo ou adicionadas manualmente.",
|
||||
"CLEAR_SEARCH": "Limpar filtros ativos",
|
||||
"FEATURE_SPOTLIGHT": {
|
||||
"TITLE": "Captain FAQ",
|
||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||
"TITLE": "FAQ do Capitão",
|
||||
"NOTE": "O Capitão FAQ detecta perguntas comuns dos clientes — sejam elas ausentes na sua base de conhecimento ou frequentemente perguntadas — e gera FAQs relevantes para melhorar o suporte. Você pode revisar cada sugestão e decidir se a aprova ou rejeita."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1002,3 +1010,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -818,46 +818,5 @@
|
||||
"CONFIRM_BUTTON_LABEL": "Excluir",
|
||||
"CANCEL_BUTTON_LABEL": "Cancelar"
|
||||
}
|
||||
},
|
||||
"CAPTAIN_REPORTS": {
|
||||
"TITLE": "Relatórios IA",
|
||||
"DESC": "Análises semanais geradas por IA com base nas conversas de cada unidade.",
|
||||
"LOADING": "Carregando relatórios...",
|
||||
"ALL_UNITS": "Todas as unidades",
|
||||
"ALL_INBOXES": "Todas as caixas de entrada",
|
||||
"TABS": {
|
||||
"INSIGHTS": "Insights IA",
|
||||
"OPERATIONAL": "Operacional"
|
||||
},
|
||||
"UNITS_GROUP": "Unidades Pix",
|
||||
"INBOXES_GROUP": "Caixas de Entrada",
|
||||
"STATUS": {
|
||||
"PENDING": "Pendente",
|
||||
"PROCESSING": "Processando",
|
||||
"DONE": "Concluído",
|
||||
"FAILED": "Falhou"
|
||||
},
|
||||
"GENERATE": {
|
||||
"BUTTON": "Gerar Análise",
|
||||
"SUCCESS": "Análise enfileirada com sucesso! Em breve estará disponível.",
|
||||
"ERROR": "Erro ao solicitar análise. Tente novamente."
|
||||
},
|
||||
"INSIGHT": {
|
||||
"CONVERSATIONS": "conversas",
|
||||
"MESSAGES": "mensagens",
|
||||
"TOP_TOPICS": "Principais Tópicos",
|
||||
"AI_FAILURES": "Pontos de Melhoria da IA",
|
||||
"COUNT_PREFIX": "(",
|
||||
"COUNT_SUFFIX": ")",
|
||||
"BULLET": "•"
|
||||
},
|
||||
"EMPTY": {
|
||||
"TITLE": "Nenhuma análise disponível",
|
||||
"MESSAGE": "Clique em Gerar Análise para criar o primeiro relatório semanal com insights das conversas."
|
||||
},
|
||||
"OPERATIONAL": {
|
||||
"COMING_SOON": "Em breve",
|
||||
"COMING_SOON_DESC": "Os dados operacionais em tempo real (reservas, cobranças Pix, etc.) estarão disponíveis aqui em breve."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, onUnmounted, computed, watch } from 'vue';
|
||||
import { useStore, useMapGetter } from 'dashboard/composables/store';
|
||||
import { useAlert } from 'dashboard/composables';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
@ -16,12 +16,83 @@ const uiFlags = useMapGetter('captainReports/getUIFlags');
|
||||
|
||||
const activeTab = ref('insights');
|
||||
const selectedInboxId = ref(null);
|
||||
const selectedPeriod = ref('last_week');
|
||||
const customStartDate = ref('');
|
||||
const customEndDate = ref('');
|
||||
|
||||
const tabs = [{ key: 'insights' }, { key: 'operational' }];
|
||||
|
||||
const getPeriodDates = period => {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
|
||||
switch (period) {
|
||||
case 'last_7_days':
|
||||
start.setDate(end.getDate() - 7);
|
||||
break;
|
||||
case 'last_week': {
|
||||
// Segunda a Domingo da semana passada
|
||||
const day = end.getDay();
|
||||
const diffToLastSunday = day === 0 ? 7 : day;
|
||||
end.setDate(end.getDate() - diffToLastSunday);
|
||||
start.setDate(end.getDate() - 6);
|
||||
break;
|
||||
}
|
||||
case 'current_month':
|
||||
start.setDate(1);
|
||||
break;
|
||||
case 'custom':
|
||||
return {
|
||||
period_start: customStartDate.value,
|
||||
period_end: customEndDate.value,
|
||||
};
|
||||
default:
|
||||
start.setDate(end.getDate() - 7);
|
||||
}
|
||||
|
||||
return {
|
||||
period_start: start.toISOString().split('T')[0],
|
||||
period_end: end.toISOString().split('T')[0],
|
||||
};
|
||||
};
|
||||
|
||||
let pollInterval = null;
|
||||
|
||||
const startPolling = () => {
|
||||
if (pollInterval) return;
|
||||
pollInterval = setInterval(async () => {
|
||||
await store.dispatch('captainReports/fetchInsights', {
|
||||
inbox_id: selectedInboxId.value,
|
||||
});
|
||||
}, 10000);
|
||||
};
|
||||
|
||||
const stopPolling = () => {
|
||||
if (pollInterval) {
|
||||
clearInterval(pollInterval);
|
||||
pollInterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
const hasProcessingInsights = computed(() => {
|
||||
return insights.value?.some(
|
||||
i => i.status === 'pending' || i.status === 'processing'
|
||||
);
|
||||
});
|
||||
|
||||
watch(hasProcessingInsights, newVal => {
|
||||
if (newVal) startPolling();
|
||||
else stopPolling();
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await store.dispatch('inboxes/get');
|
||||
await store.dispatch('captainReports/fetchInsights', {});
|
||||
if (hasProcessingInsights.value) startPolling();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopPolling();
|
||||
});
|
||||
|
||||
const onFilterChange = async event => {
|
||||
@ -32,11 +103,24 @@ const onFilterChange = async event => {
|
||||
});
|
||||
};
|
||||
|
||||
const onPeriodChange = event => {
|
||||
selectedPeriod.value = event.target.value;
|
||||
};
|
||||
|
||||
const onGenerateInsight = async () => {
|
||||
if (uiFlags.value.isGenerating) return;
|
||||
const { period_start, period_end } = getPeriodDates(selectedPeriod.value);
|
||||
|
||||
if (!period_start || !period_end) {
|
||||
useAlert(t('CAPTAIN_REPORTS.GENERATE.DATE_REQUIRED'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await store.dispatch('captainReports/generateInsight', {
|
||||
inbox_id: selectedInboxId.value,
|
||||
period_start,
|
||||
period_end,
|
||||
});
|
||||
useAlert(t('CAPTAIN_REPORTS.GENERATE.SUCCESS'));
|
||||
} catch (error) {
|
||||
@ -45,7 +129,6 @@ const onGenerateInsight = async () => {
|
||||
useAlert(errorMessage);
|
||||
}
|
||||
};
|
||||
|
||||
const statusLabel = status => {
|
||||
const map = {
|
||||
pending: t('CAPTAIN_REPORTS.STATUS.PENDING'),
|
||||
@ -68,6 +151,12 @@ const statusClass = status => {
|
||||
|
||||
const formatDate = dateStr => {
|
||||
if (!dateStr) return '-';
|
||||
// Use YYYY, MM, DD bits to avoid timezone shift from standard Date parsing
|
||||
const parts = dateStr.split('-');
|
||||
if (parts.length === 3) {
|
||||
const [year, month, day] = parts;
|
||||
return `${day}/${month}/${year}`;
|
||||
}
|
||||
return new Date(dateStr).toLocaleDateString('pt-BR');
|
||||
};
|
||||
|
||||
@ -87,6 +176,46 @@ const periodLabel = insight =>
|
||||
>
|
||||
<template #actions>
|
||||
<div class="flex items-center gap-3">
|
||||
<select
|
||||
class="rounded-lg border border-n-weak bg-n-alpha-1 px-3 py-2 text-sm text-n-slate-12 focus:outline-none focus:ring-2 focus:ring-n-brand"
|
||||
:value="selectedPeriod"
|
||||
@change="onPeriodChange"
|
||||
>
|
||||
<option value="last_7_days">
|
||||
{{ t('CAPTAIN_REPORTS.FILTER_DATE.LAST_7_DAYS') }}
|
||||
</option>
|
||||
<option value="last_week">
|
||||
{{ t('CAPTAIN_REPORTS.FILTER_DATE.LAST_WEEK') }}
|
||||
</option>
|
||||
<option value="current_month">
|
||||
{{ t('CAPTAIN_REPORTS.FILTER_DATE.CURRENT_MONTH') }}
|
||||
</option>
|
||||
<option value="custom">
|
||||
{{ t('CAPTAIN_REPORTS.FILTER_DATE.CUSTOM') }}
|
||||
</option>
|
||||
</select>
|
||||
|
||||
<div
|
||||
v-if="selectedPeriod === 'custom'"
|
||||
class="flex items-center gap-2"
|
||||
>
|
||||
<input
|
||||
v-model="customStartDate"
|
||||
type="date"
|
||||
class="rounded-lg border border-n-weak bg-n-alpha-1 px-3 py-2 text-sm text-n-slate-12 focus:outline-none focus:ring-2 focus:ring-n-brand"
|
||||
:placeholder="t('CAPTAIN_REPORTS.FILTER_DATE.START')"
|
||||
/>
|
||||
<span class="text-n-slate-9 mx-1">
|
||||
{{ t('CAPTAIN_REPORTS.FILTER_DATE.SEPARATOR') }}
|
||||
</span>
|
||||
<input
|
||||
v-model="customEndDate"
|
||||
type="date"
|
||||
class="rounded-lg border border-n-weak bg-n-alpha-1 px-3 py-2 text-sm text-n-slate-12 focus:outline-none focus:ring-2 focus:ring-n-brand"
|
||||
:placeholder="t('CAPTAIN_REPORTS.FILTER_DATE.END')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<select
|
||||
class="rounded-lg border border-n-weak bg-n-alpha-1 px-3 py-2 text-sm text-n-slate-12 focus:outline-none focus:ring-2 focus:ring-n-brand"
|
||||
@change="onFilterChange"
|
||||
|
||||
27
progresso/2026-03-01-correcao-relatorios-ia.md
Normal file
27
progresso/2026-03-01-correcao-relatorios-ia.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Nota de Progresso: Correção Relatórios IA (Captain Reports)
|
||||
|
||||
**Objetivo:** Corrigir as traduções e o comportamento visual/sincronização dos relatórios de IA do Capitão.
|
||||
|
||||
**Contexto:** Os relatórios não exibiam traduções corretas para períodos e inboxes devido a uma duplicação no `settings.json`. Além disso, a data exibia shift de timezone e não havia polling de status.
|
||||
|
||||
**Passos Realizados:**
|
||||
1. Removida a duplicação de `CAPTAIN_REPORTS` no `settings.json` (PT e EN).
|
||||
2. Centralizadas as traduções em `captain.json`.
|
||||
3. Atualizado `InsightsController#index` para carregar todos os relatórios por padrão, permitindo visualizações imediatas.
|
||||
4. Adicionado mecanismo de polling (10s) na UI para relatórios em processamento.
|
||||
5. Corrigida a formatação de data para evitar mudança de dia por fuso horário.
|
||||
|
||||
**Arquivos Alterados:**
|
||||
- `app/controllers/api/v1/accounts/captain/reports/insights_controller.rb`
|
||||
- `app/javascript/dashboard/i18n/locale/en/captain.json`
|
||||
- `app/javascript/dashboard/i18n/locale/en/settings.json`
|
||||
- `app/javascript/dashboard/i18n/locale/pt_BR/captain.json`
|
||||
- `app/javascript/dashboard/i18n/locale/pt_BR/integrations.json`
|
||||
- `app/javascript/dashboard/i18n/locale/pt_BR/settings.json`
|
||||
- `app/javascript/dashboard/routes/dashboard/settings/captain/reports/Index.vue`
|
||||
|
||||
**Como Validar:**
|
||||
- Acesse Relatórios IA.
|
||||
- Verifique se aparecem os relatórios existentes sem precisar selecionar filtros.
|
||||
- Gere um novo relatório e acompanhe o status mudar de "Pendente/Processando" para "Concluído" sem atualizar a página.
|
||||
- Verifique se a data exibida no card é idêntica à selecionada no filtro.
|
||||
Loading…
Reference in New Issue
Block a user