File size: 10,385 Bytes
26e822e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import gradio as gr
import os
from pathlib import Path
from datetime import datetime
import matplotlib.pyplot as plt
import logging

logger = logging.getLogger("jira_assistant_interface")

def launch_interface(app):
    """
    Запуск інтерфейсу користувача Gradio
    
    Args:
        app: Екземпляр JiraAssistantApp
    """
    # Функція для обробки завантаження та аналізу CSV
    def analyze_csv(file_obj, inactive_days, include_ai):
        if file_obj is None:
            return "Помилка: файл не вибрано", None, None, None, None
        
        try:
            logger.info(f"Отримано файл: {file_obj.name}, тип: {type(file_obj)}")
            
            # Створення тимчасового файлу
            temp_file_path = os.path.join("temp", f"temp_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv")
            
            # У Gradio 5.19.0 об'єкт файлу має різну структуру
            # file_obj може бути шляхом до файлу або містити атрибут 'name'
            if hasattr(file_obj, 'name'):
                source_path = file_obj.name
                
                # Копіювання файлу
                import shutil
                shutil.copy2(source_path, temp_file_path)
            else:
                # Якщо це не шлях до файлу, ймовірно це вже самі дані
                with open(temp_file_path, "w", encoding="utf-8") as f:
                    f.write(str(file_obj))
            
            # Аналіз даних
            api_key = os.getenv("OPENAI_API_KEY") if include_ai else None
            result = app.analyze_csv_file(
                temp_file_path, 
                inactive_days=inactive_days, 
                include_ai=include_ai,
                api_key=api_key
            )
            
            # Видалення тимчасового файлу
            try:
                os.remove(temp_file_path)
            except:
                pass
            
            if result.get("error"):
                return result.get("error"), None, None, None, None
                
            return (
                result.get("report", ""),
                result.get("visualizations", {}).get("status"),
                result.get("visualizations", {}).get("priority"),
                result.get("visualizations", {}).get("created_timeline"),
                result.get("ai_analysis", "AI аналіз буде доступний у наступних версіях додатку.")
            )
        
        except Exception as e:
            import traceback
            error_msg = f"Помилка аналізу: {str(e)}\n\n{traceback.format_exc()}"
            logger.error(error_msg)
            return error_msg, None, None, None, None
    
    # Функція для збереження звіту
    def save_report_handler(report_text, format_type, include_visualizations):
        if not report_text:
            return "Помилка: спочатку виконайте аналіз даних"
        
        return app.save_report(
            format_type=format_type,
            include_visualizations=include_visualizations
        )
    
    # Функція для тестування підключення до Jira
    def test_jira_connection_handler(url, username, api_token):
        if not url or not username or not api_token:
            return "Помилка: необхідно заповнити всі поля (URL, користувач, API токен)"
        
        success = app.test_jira_connection(url, username, api_token)
        if success:
            return "✅ Успішне підключення до Jira API"
        else:
            return "❌ Помилка підключення до Jira. Перевірте введені дані."
    
    # Створення інтерфейсу Gradio
    with gr.Blocks(title="Jira AI Assistant") as interface:
        gr.Markdown("# 🔍 Jira AI Assistant")
        
        with gr.Tabs():
            with gr.Tab("CSV Аналіз"):
                with gr.Row():
                    with gr.Column(scale=1):
                        file_input = gr.File(label="Завантажити CSV файл Jira")
                        inactive_days = gr.Slider(minimum=1, maximum=90, value=14, step=1, 
                                                label="Кількість днів для визначення неактивних тікетів")
                        
                        include_ai = gr.Checkbox(label="Включити AI аналіз", value=False)
                        
                        analyze_btn = gr.Button("Аналізувати", variant="primary")
                        
                        with gr.Accordion("Збереження звіту", open=False):
                            format_type = gr.Dropdown(
                                choices=["markdown", "html", "pdf"],
                                value="markdown",
                                label="Формат звіту"
                            )
                            include_visualizations = gr.Checkbox(
                                label="Включити візуалізації", 
                                value=True
                            )
                            save_btn = gr.Button("Зберегти звіт")
                            save_output = gr.Textbox(label="Статус збереження")
                    
                    with gr.Column(scale=2):
                        with gr.Tabs():
                            with gr.Tab("Звіт"):
                                report_output = gr.Markdown()
                            
                            with gr.Tab("Візуалізації"):
                                with gr.Row():
                                    status_plot = gr.Plot(label="Статуси тікетів")
                                    priority_plot = gr.Plot(label="Пріоритети тікетів")
                                
                                timeline_plot = gr.Plot(label="Часова шкала")
                            
                            with gr.Tab("AI Аналіз"):
                                ai_output = gr.Markdown()
                
                # Встановлюємо обробники подій
                analyze_btn.click(
                    analyze_csv,
                    inputs=[file_input, inactive_days, include_ai],
                    outputs=[report_output, status_plot, priority_plot, timeline_plot, ai_output]
                )
                
                save_btn.click(
                    save_report_handler,
                    inputs=[report_output, format_type, include_visualizations],
                    outputs=[save_output]
                )
            
            with gr.Tab("Jira API"):
                gr.Markdown("## Підключення до Jira API")
                
                with gr.Row():
                    jira_url = gr.Textbox(
                        label="Jira URL",
                        placeholder="https://your-company.atlassian.net"
                    )
                    jira_username = gr.Textbox(
                        label="Ім'я користувача Jira",
                        placeholder="[email protected]"
                    )
                    jira_api_token = gr.Textbox(
                        label="Jira API Token",
                        type="password"
                    )
                
                test_connection_btn = gr.Button("Тестувати з'єднання")
                connection_status = gr.Textbox(label="Статус підключення")
                
                test_connection_btn.click(
                    test_jira_connection_handler,
                    inputs=[jira_url, jira_username, jira_api_token],
                    outputs=[connection_status]
                )
                
                gr.Markdown("## ⚠️ Ця функція буде доступна у наступних версіях")
            
            with gr.Tab("AI Асистенти"):
                gr.Markdown("## AI Асистенти для Jira")
                gr.Markdown("⚠️ Ця функція буде доступна у наступних версіях")
                
                with gr.Accordion("Зразок інтерфейсу"):
                    question = gr.Textbox(
                        label="Запитання",
                        placeholder="Наприклад: Які тікети мають найвищий пріоритет?",
                        lines=2
                    )
                    answer = gr.Markdown(label="Відповідь")
            
            with gr.Tab("Інтеграції"):
                gr.Markdown("## Інтеграції з зовнішніми системами")
                gr.Markdown("⚠️ Ця функція буде доступна у наступних версіях")
                
                with gr.Accordion("Slack інтеграція"):
                    slack_channel = gr.Textbox(
                        label="Slack канал",
                        placeholder="#project-updates"
                    )
                    slack_message = gr.Textbox(
                        label="Повідомлення",
                        placeholder="Тижневий звіт по проекту",
                        lines=3
                    )
                    slack_send_btn = gr.Button("Надіслати у Slack", interactive=False)
    
    # Запуск інтерфейсу
    interface.launch()

# Можливість запустити інтерфейс самостійно (для тестування)
if __name__ == "__main__":
    import sys
    sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    
    from app import JiraAssistantApp
    app_instance = JiraAssistantApp()
    launch_interface(app_instance)