Redmind commited on
Commit
026aa93
·
verified ·
1 Parent(s): bbff8d3

Upload 50 files

Browse files
Files changed (50) hide show
  1. README.md +10 -10
  2. __init__.py +0 -0
  3. app.py +1509 -0
  4. config/__pycache__/settings.cpython-310.pyc +0 -0
  5. config/__pycache__/settings.cpython-311.pyc +0 -0
  6. config/__pycache__/settings.cpython-312.pyc +0 -0
  7. config/settings.py +4 -0
  8. logs/redmindgen.log +0 -0
  9. redmindgen.log +236 -0
  10. requirements.txt +78 -0
  11. services/__pycache__/chat_service.cpython-310.pyc +0 -0
  12. services/__pycache__/chat_service.cpython-311.pyc +0 -0
  13. services/__pycache__/chat_service.cpython-312.pyc +0 -0
  14. services/__pycache__/file_upload_service.cpython-310.pyc +0 -0
  15. services/__pycache__/file_upload_service.cpython-312.pyc +0 -0
  16. services/__pycache__/multidoc_files_upload.cpython-310.pyc +0 -0
  17. services/__pycache__/multidoc_files_upload.cpython-311.pyc +0 -0
  18. services/chat_service.py +137 -0
  19. services/file_upload_service.py +141 -0
  20. static/css/dashboard.css +931 -0
  21. static/css/dashboard.css.map +7 -0
  22. static/css/perfect-scrollbar.css +116 -0
  23. static/css/style.css +0 -0
  24. static/css/style.css.map +0 -0
  25. static/img/AI.jpg +0 -0
  26. static/img/redmindlogo3.jpg +0 -0
  27. static/logos/avatar.svg +10 -0
  28. static/logos/calendar-silhouette.svg +4 -0
  29. static/logos/dots.svg +22 -0
  30. static/logos/email.svg +4 -0
  31. templates/API_connectors.html +616 -0
  32. templates/chatbot.html +81 -0
  33. templates/company_profile.html +724 -0
  34. templates/dashboard.html +360 -0
  35. templates/data_connectors.html +624 -0
  36. templates/footer.html +26 -0
  37. templates/index.html +359 -0
  38. templates/knowledgebase.html +710 -0
  39. templates/prompt_template.html +643 -0
  40. templates/redmindlogo2.jpg +0 -0
  41. templates/redmindlogo3.jpg +0 -0
  42. templates/sidepane.html +347 -0
  43. vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.metadata.json +1 -0
  44. vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.vectorstore/index.faiss +0 -0
  45. vectordb/openai_dbstore/Future of Digital Freight Forwarders - BLOG.pdf_a3cfd1d6c83cfcd45146ec7c13b1d98d.metadata.json +1 -0
  46. vectordb/openai_dbstore/Future of Digital Freight Forwarders - BLOG.pdf_a3cfd1d6c83cfcd45146ec7c13b1d98d.vectorstore/index.faiss +0 -0
  47. vectordb/openai_dbstore/documents/Inbound.pdf_1dd51058ba4a11db1c9773ce16dfc175.metadata.json +1 -0
  48. vectordb/openai_dbstore/documents/Inbound.pdf_1dd51058ba4a11db1c9773ce16dfc175.vectorstore/index.faiss +0 -0
  49. vectordb/openai_dbstore/documents/NewAge (1).pdf_e4fb1ef3fb0aed5f99dbf218f2aa62af.metadata.json +1 -0
  50. vectordb/openai_dbstore/documents/NewAge (1).pdf_e4fb1ef3fb0aed5f99dbf218f2aa62af.vectorstore/index.faiss +0 -0
README.md CHANGED
@@ -1,10 +1,10 @@
1
- ---
2
- title: RedMindGPT UI Dev
3
- emoji: 🐠
4
- colorFrom: purple
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: Redmind GPT API
3
+ emoji: 🐨
4
+ colorFrom: green
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: false
8
+ ---
9
+
10
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
__init__.py ADDED
File without changes
app.py ADDED
@@ -0,0 +1,1509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import logging
4
+ import shutil
5
+ import asyncpg
6
+ from fastapi import FastAPI, File, Query,Form, Request, HTTPException, UploadFile
7
+ from fastapi.responses import JSONResponse, RedirectResponse
8
+ from fastapi.staticfiles import StaticFiles
9
+ from fastapi.templating import Jinja2Templates
10
+ from fastapi.middleware.cors import CORSMiddleware
11
+ from dotenv import load_dotenv
12
+ import mysql.connector
13
+ from typing import List
14
+ from pydantic import BaseModel
15
+ import psycopg2
16
+
17
+
18
+
19
+ # Load environment variables
20
+ load_dotenv()
21
+
22
+ # Configure logging
23
+ logging.basicConfig(
24
+ level=logging.INFO,
25
+ format='%(asctime)s - %(levelname)s - %(message)s',
26
+ handlers=[
27
+ logging.FileHandler("redmindgen.log"),
28
+ logging.StreamHandler() # This ensures logging to console
29
+ ]
30
+ )
31
+ logging.info("Application startup")
32
+
33
+ # Create the FastAPI app
34
+ app = FastAPI(title="RedmindGen", description="Chat with your Data", version="1.0.0")
35
+
36
+ # Mount static files
37
+ app.mount("/static", StaticFiles(directory="static"), name="static")
38
+
39
+ # Jinja2 templates
40
+ templates = Jinja2Templates(directory="templates")
41
+
42
+ # Configure CORS
43
+ origins = [
44
+ "http://localhost:8000",
45
+ "http://127.0.0.1:8000",
46
+ "http://167.71.75.10:8003/"
47
+ ]
48
+
49
+ app.add_middleware(
50
+ CORSMiddleware,
51
+ allow_origins=origins,
52
+ allow_credentials=True,
53
+ allow_methods=["*"],
54
+ allow_headers=["*"],
55
+ )
56
+ DB_USER = 'u852023448_redmindgpt'
57
+ DB_PASSWORD = 'redmindGpt@123'
58
+ DB_HOST = '217.21.88.10'
59
+ DB_NAME = 'u852023448_redmindgpt'
60
+ from pydantic import BaseModel
61
+ class DatabaseConnection(BaseModel):
62
+ database_type: str
63
+ server: str
64
+ port: str
65
+ databaseName: str
66
+ username: str
67
+ password: str
68
+ @app.post("/api/connect")
69
+ async def connect_to_database(connection: DatabaseConnection):
70
+ try:
71
+ print(f"Attempting to connect to database: {connection.database_type}")
72
+ if connection.database_type == "Postgres":
73
+ print(f"PostgreSQL connection details - Host: {connection.server}, Port: {connection.port}, Database: {connection.databaseName}, User: {connection.username}")
74
+ conn = psycopg2.connect(
75
+ host=connection.server,
76
+ port=connection.port,
77
+ database=connection.databaseName,
78
+ user=connection.username,
79
+ password=connection.password
80
+ )
81
+ query_schemas = "SELECT schema_name FROM information_schema.schemata"
82
+ query_tables = "SELECT table_name FROM information_schema.tables WHERE table_schema = %s"
83
+ elif connection.database_type == "mysql":
84
+ print(f"inside mysql",connection.server,connection.port,connection.databaseName,connection.username,connection.password)
85
+ conn = mysql.connector.connect(
86
+ host=connection.server,
87
+ port=connection.port,
88
+ database=connection.databaseName,
89
+ user=connection.username,
90
+ password=connection.password
91
+ )
92
+ query_schemas = "SELECT schema_name FROM information_schema.schemata"
93
+ query_tables = "SELECT table_name FROM information_schema.tables WHERE table_schema = %s"
94
+ else:
95
+ raise HTTPException(status_code=400, detail="Unsupported database type")
96
+
97
+ cursor = conn.cursor()
98
+
99
+ # Fetch all schemas
100
+ cursor.execute(query_schemas)
101
+ schemas = cursor.fetchall()
102
+
103
+ # Fetch all tables within each schema
104
+ schema_tables = {}
105
+ for schema in schemas:
106
+ cursor.execute(query_tables, (schema[0],))
107
+ tables = cursor.fetchall()
108
+ schema_tables[schema[0]] = [table[0] for table in tables]
109
+
110
+ cursor.close()
111
+ conn.close()
112
+
113
+ return {"schemas": [schema[0] for schema in schemas], "schema_tables": schema_tables, "success": True}
114
+
115
+ except Exception as e:
116
+ raise HTTPException(status_code=500, detail=str(e))
117
+
118
+ # Function to create a new database connection for MySQL (Example)
119
+ def get_db_connection():
120
+ try:
121
+ cnx = mysql.connector.connect(user=DB_USER, password=DB_PASSWORD, host=DB_HOST, database=DB_NAME)
122
+ return cnx
123
+ except mysql.connector.Error as err:
124
+ logging.error(f"Database connection error: {err}")
125
+ return None
126
+ # Function to create a new database connection for MySQL (Example)
127
+ def get_db_connection():
128
+ try:
129
+ cnx = mysql.connector.connect(user=DB_USER, password=DB_PASSWORD, host=DB_HOST, database=DB_NAME)
130
+ return cnx
131
+ except mysql.connector.Error as err:
132
+ logging.error(f"Database connection error: {err}")
133
+ return None
134
+
135
+ @app.get("/")
136
+ async def read_root(request: Request):
137
+ return templates.TemplateResponse("index.html", {"request": request})
138
+
139
+ def verify_user(username: str, password: str):
140
+ try:
141
+ cnx = get_db_connection()
142
+ cursor = cnx.cursor()
143
+ query = "SELECT role,company_id FROM user_detail WHERE username = %s AND password = %s"
144
+ values = (username, password)
145
+ cursor.execute(query, values)
146
+ result = cursor.fetchone()
147
+ cursor.close()
148
+ cnx.close()
149
+ if result is not None:
150
+ logging.info(f"User {username}{result[1]} logged in successfully")
151
+ return "success",result[0],result[1]
152
+ else:
153
+ logging.info(f"User {username} login failed")
154
+ return "failure"
155
+ except mysql.connector.Error as err:
156
+ logging.error(f"Database error: {err}")
157
+ return "failure"
158
+
159
+ @app.post("/validate-user")
160
+ async def validate_user(request: Request, username: str = Form(...), password: str = Form(...)):
161
+ status, role ,company_id= verify_user(username, password)
162
+ if status == 'success' and role and company_id:
163
+ logging.info(f"user role {role} is returned")
164
+
165
+ # Set cookies and redirect to the dashboard
166
+ response = RedirectResponse(url="/dashboard", status_code=302)
167
+ response.set_cookie(key="role", value=role)
168
+ response.set_cookie(key="username", value=username)
169
+ response.set_cookie(key="company_id",value=company_id)
170
+ return response
171
+ else:
172
+ # If login fails, redirect back to the index page with an error message
173
+ return templates.TemplateResponse("index.html", {
174
+ "request": request,
175
+ "error": "Invalid username or password"
176
+ })
177
+
178
+ @app.post("/submit_company_profile")
179
+ async def submit_company_profile(request: Request,
180
+ company_name: str = Form(...),
181
+ company_code: str = Form(...),
182
+ domain: str = Form(...),
183
+ llm_tools: List[str] = Form(...),
184
+ username:str=Form(...),
185
+ password:str=Form(...),
186
+ role:str=Form(...)):
187
+ logging.info("Received form submission for company profile")
188
+ logging.info(f"Form data - company_name: {company_name}, company_code: {company_code}, domain: {domain}, llm_tools: {llm_tools}")
189
+
190
+ try:
191
+ cnx = get_db_connection()
192
+ cursor = cnx.cursor()
193
+ query = "INSERT INTO company_detail (company_name, company_code, domain, llm_tools) VALUES (%s, %s, %s, %s)"
194
+ values = (company_name, company_code, domain, ",".join(llm_tools))
195
+ logging.info(f"Executing query: {query} with values: {values}")
196
+ cursor.execute(query, values)
197
+ # Retrieve the inserted company_id
198
+ company_id = cursor.lastrowid
199
+ logging.info(f"Company profile for {company_name} inserted successfully with company_id: {company_id}")
200
+
201
+ # Insert user details with the retrieved company_id
202
+ user_query = "INSERT INTO user_detail (company_id, username, password,role) VALUES (%s, %s, %s, %s)"
203
+ user_values = (company_id, username, password, role)
204
+ logging.info(f"Executing user detail query: {user_query} with values: {user_values}")
205
+ cursor.execute(user_query, user_values)
206
+ cnx.commit()
207
+ logging.info(f"Query executed successfully, {cursor.rowcount} row(s) affected")
208
+ cursor.close()
209
+ cnx.close()
210
+ logging.info(f"Company profile for {company_name} inserted successfully")
211
+ RedirectResponse(url="/company_profile?message=Data saved successfully", status_code=302)
212
+ except mysql.connector.Error as err:
213
+ logging.error(f"Database error: {err}")
214
+ raise HTTPException(status_code=500, detail="Internal Server Error")
215
+
216
+
217
+ @app.get("/api/companies")
218
+ async def get_companies():
219
+ try:
220
+ cnx = get_db_connection()
221
+ cursor = cnx.cursor()
222
+ query = "SELECT company_name FROM company_detail "
223
+ cursor.execute(query)
224
+ companies = cursor.fetchall()
225
+ cursor.close()
226
+ cnx.close()
227
+ return {"companies": [{"name": company[0]} for company in companies]}
228
+ except mysql.connector.Error as err:
229
+ logging.error(f"Database error: {err}")
230
+ raise HTTPException(status_code=500, detail="Internal Server Error")
231
+
232
+ @app.get("/dashboard")
233
+ async def dashboard(request: Request):
234
+ try:
235
+ # Retrieve cookies
236
+ role = request.cookies.get("role")
237
+ username = request.cookies.get("username")
238
+ company_id=request._cookies.get("company_id")
239
+
240
+ # Establish database connection
241
+ cnx = get_db_connection()
242
+ cursor = cnx.cursor()
243
+
244
+ # Fetch all table names
245
+ cursor.execute("SHOW TABLES")
246
+ all_tables = cursor.fetchall()
247
+
248
+ # Dictionary to hold the count of records for each table
249
+ table_count_of_each_table = {}
250
+
251
+ # Fetch count of records for each table
252
+ for table in all_tables:
253
+ table_name = table[0]
254
+ query = f"SELECT COUNT(*) FROM {table_name} WHERE company_id = %s"
255
+ cursor.execute(query, (company_id,))
256
+
257
+ count = cursor.fetchone()[0]
258
+ table_count_of_each_table[table_name] = count
259
+ query1=f"select company_name from company_detail where company_id = %s"
260
+ cursor.execute(query1,(company_id,))
261
+ company_name_result = cursor.fetchone()
262
+
263
+ # Check if company_name_result is not None
264
+ if company_name_result:
265
+ company_name = company_name_result[0]
266
+ else:
267
+ company_name = "Unknown" # Default
268
+ # Close cursor and connection
269
+ cursor.close()
270
+ cnx.close()
271
+
272
+ # Log the counts for debugging purposes
273
+ logging.info(table_count_of_each_table)
274
+
275
+ # Render the template with the data, role, and username
276
+ return templates.TemplateResponse("dashboard.html", {
277
+ "request": request,
278
+ "title": "Dashboard",
279
+ "table_count_of_each_table": table_count_of_each_table,
280
+ "role": role,
281
+ "username": username,
282
+ "company_id":company_id,
283
+ "company_name":company_name
284
+ })
285
+ except mysql.connector.Error as err:
286
+ # Log the error and raise an HTTPException
287
+ logging.error(f"Database error: {err}")
288
+ raise HTTPException(status_code=500, detail="Internal Server Error")
289
+
290
+ @app.get("/api/company_record_count/{company_id}")
291
+ async def get_company_record_count(company_id: int):
292
+ try:
293
+ # Establish database connection
294
+ cnx = get_db_connection()
295
+ cursor = cnx.cursor()
296
+
297
+ # List of tables to count records in
298
+ tables = ["knowledge_base", "data_connectors", "api_connectors", "prompt_templates"]
299
+
300
+ # Dictionary to hold the count of records for each table
301
+ table_counts = {}
302
+
303
+ # Fetch count of records for the selected company in each table
304
+ for table in tables:
305
+ query = f"SELECT COUNT(*) FROM {table} WHERE company_id = %s"
306
+ cursor.execute(query, (company_id,))
307
+ count = cursor.fetchone()[0]
308
+ table_counts[table] = count
309
+
310
+ # Close cursor and connection
311
+ cursor.close()
312
+ cnx.close()
313
+
314
+ return {"table_counts": table_counts}
315
+
316
+ except mysql.connector.Error as err:
317
+ logging.error(f"Database error: {err}")
318
+ raise HTTPException(status_code=500, detail="Internal Server Error")
319
+
320
+
321
+ @app.get("/company_profile")
322
+ async def company_profile(request: Request):
323
+ try:
324
+ # Retrieve cookies
325
+ role = request.cookies.get("role")
326
+ company_id = request.cookies.get("company_id")
327
+
328
+ # Render the template with the role and company_id
329
+ return templates.TemplateResponse("company_profile.html", {
330
+ "request": request,
331
+ "role": role,
332
+ "company_id": company_id,
333
+ "title":"Company Profile"
334
+ })
335
+ except Exception as e:
336
+ # Handle exceptions
337
+ logging.error(f"Error: {e}")
338
+ raise HTTPException(status_code=500, detail="Internal Server Error")
339
+ #return templates.TemplateResponse("company_profile.html", {"request": request,"title":"Company Profile"})
340
+ @app.get("/api/company_id")
341
+ async def get_company_id(company_name: str):
342
+ print(f"Received company_name: {company_name}") # Debug statement
343
+ logging.info(f"Received request for company name: {company_name}")
344
+ try:
345
+ cnx = get_db_connection()
346
+ cursor = cnx.cursor()
347
+ query = "SELECT * FROM company_detail WHERE company_name = %s"
348
+ cursor.execute(query, (company_name,))
349
+ result = cursor.fetchone()
350
+ cursor.close()
351
+ cnx.close()
352
+
353
+ if result:
354
+ llm_tools = result[4].split(',') if result[4] else []
355
+ return {"company_id": result[0],
356
+ "company_name":result[1],
357
+ "company_code":result[2],
358
+ "domain":result[3],
359
+ "llm_tools":llm_tools
360
+ }
361
+ else:
362
+ logging.error(f"Company not found for name: {company_name}")
363
+ raise HTTPException(status_code=404, detail="Company not found")
364
+ except mysql.connector.Error as err:
365
+ logging.error(f"Database error: {err}")
366
+ raise HTTPException(status_code=500, detail="Internal Server Error")
367
+
368
+ @app.get("/api/companydetails")
369
+ async def get_companies():
370
+ print(f"Received company_name") # Debug statement
371
+ logging.info(f"Received request for company name")
372
+
373
+ try:
374
+ cnx = get_db_connection()
375
+ cursor = cnx.cursor()
376
+ query = "SELECT * FROM company_detail"
377
+ cursor.execute(query)
378
+ result = cursor.fetchall()
379
+ logging.info(f"Query result: {result}")
380
+ cursor.close()
381
+ cnx.close()
382
+
383
+ companies = []
384
+ for row in result:
385
+ llm_tools = row[4].split(',') if row[4] else []
386
+ logging.info(row[4])
387
+ companies.append({
388
+ "company_id": row[0],
389
+ "company_name": row[1],
390
+ "company_code": row[2],
391
+ "domain": row[3],
392
+ "llm_tools": row[4]
393
+ })
394
+
395
+ if companies:
396
+ return companies
397
+ else:
398
+ logging.error(f"Company not found for name: {result[1]}")
399
+ raise HTTPException(status_code=404, detail="Company not found")
400
+ except mysql.connector.Error as err:
401
+ logging.error(f"Database error: {err}")
402
+ raise HTTPException(status_code=500, detail="Internal Server Error")
403
+
404
+ #to view the details
405
+ @app.get("/api/getcompanydetails/{company_id}")
406
+ async def get_company_details(company_id: int):
407
+ company = await get_company_from_db(company_id)
408
+ if not company:
409
+ raise HTTPException(status_code=404, detail="Company not found")
410
+ return company
411
+
412
+ async def get_company_from_db(company_id: int):
413
+ try:
414
+ # Establish a connection to the database
415
+ cnx = get_db_connection()
416
+ if cnx is None:
417
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
418
+ cursor = cnx.cursor(dictionary=True)
419
+ query = "SELECT * FROM company_detail WHERE company_id = %s"
420
+ cursor.execute(query, (company_id,))
421
+ company = cursor.fetchone()
422
+ cursor.close()
423
+ cnx.close()
424
+ return company
425
+ except mysql.connector.Error as err:
426
+ logging.error(f"Error fetching company: {err}")
427
+ raise HTTPException(status_code=500, detail="Failed to fetch company")
428
+ # to edit the details
429
+ @app.put("/api/putcompanydetails/{company_id}")
430
+ async def update_company_details(company_id: int,
431
+ company_name: str = Form(...),
432
+ company_code: str = Form(...),
433
+ domain: str = Form(...),
434
+ llm_tools: List[str] = Form(...)):
435
+ print(f"Received company_id",company_id) # Debug statement
436
+ logging.info(f"Received request for company data")
437
+ company_data = {
438
+ 'company_name': company_name,
439
+ 'company_code': company_code,
440
+ 'domain': domain,
441
+ 'llm_tools': ','.join(llm_tools)
442
+ }
443
+ updated_company = await update_company_in_db(company_id, company_data)
444
+ if not updated_company:
445
+ raise HTTPException(status_code=500, detail="Failed to update company")
446
+ return updated_company
447
+
448
+ async def update_company_in_db(company_id: int, company_data: dict):
449
+ try:
450
+ print(f"Received company_nid inside function",company_id) # Debug statement
451
+ logging.info(f"Received request for company name")
452
+ cnx = get_db_connection()
453
+ if cnx is None:
454
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
455
+ cursor = cnx.cursor()
456
+ update_query = """
457
+ UPDATE u852023448_redmind.gptcompany_detail cd
458
+ SET cd.company_name = %s, cd.company_code = %s, cd.domain = %s, cd.llm_tools = %s
459
+ WHERE cd.company_id = %s;
460
+ """
461
+ logging.info(f"Executing query: {update_query} with company_id: {company_id}")
462
+ params = (company_id,company_data)
463
+ logging.info(f"Query parameters: {params}")
464
+ print(f"Query parameters: {params}")
465
+
466
+
467
+ cursor.execute(update_query, (
468
+ company_data['company_name'],
469
+ company_data['company_code'],
470
+ company_data['domain'],
471
+ company_data['llm_tools'],
472
+ company_id
473
+ ))
474
+
475
+ cnx.commit()
476
+ success = cursor.rowcount > 0
477
+ cursor.close()
478
+ cnx.close()
479
+ if not success:
480
+ return None
481
+ return company_data
482
+ except mysql.connector.Error as err:
483
+ logging.error(f"Error updating company: {err}")
484
+ raise HTTPException(status_code=500, detail="Failed to update company")
485
+
486
+
487
+ def delete_company_from_db(company_id: int) -> bool:
488
+ print(f"Received company_name: {company_id}") # Debug statement
489
+ logging.info(f"Received request for company name: {company_id}")
490
+ try:
491
+ # Establish a connection to the database
492
+ cnx = get_db_connection()
493
+ if cnx is None:
494
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
495
+ cursor = cnx.cursor()
496
+ delete_query = "DELETE FROM company_detail WHERE company_id = %s"
497
+ cursor.execute(delete_query, (company_id,))
498
+ cnx.commit()
499
+ success = cursor.rowcount > 0
500
+ cursor.close()
501
+ cnx.close()
502
+ return success
503
+ except mysql.connector.Error as err:
504
+ logging.error(f"Error deleting company: {err}")
505
+ raise HTTPException(status_code=500, detail="Failed to delete company")
506
+ @app.delete("/api/delcompanydetails/{company_id}")
507
+ async def delete_company(company_id: int):
508
+ deletion_success = delete_company_from_db(company_id)
509
+ if not deletion_success:
510
+ raise HTTPException(status_code=404, detail="Company not found or failed to delete")
511
+ return {"message": "Company deleted successfully"}
512
+
513
+ @app.get("/knowledgebase")
514
+ async def knowledgebase(request: Request):
515
+ try:
516
+ # Retrieve cookies
517
+ role = request.cookies.get("role")
518
+ company_id = request.cookies.get("company_id")
519
+
520
+ # Render the template with the role and company_id
521
+ return templates.TemplateResponse("knowledgebase.html", {
522
+ "request": request,
523
+ "role": role,
524
+ "company_id": company_id,
525
+ "title":"KnowledgeBase"
526
+ })
527
+ except Exception as e:
528
+ # Handle exceptions
529
+ logging.error(f"Error: {e}")
530
+ raise HTTPException(status_code=500, detail="Internal Server Error")
531
+
532
+
533
+ #to insert into knowledgebase
534
+ @app.post("/upload_document")
535
+ async def upload_document(
536
+ request: Request,
537
+ company_id:str=Form(...),
538
+ uploadFile: UploadFile = File(...),
539
+ documentName: str = Form(...),
540
+ documentDescription: str = Form(...),
541
+ department: str = Form(...),
542
+ vectorDBflag:str=Form(...),
543
+ version: str = Form(...),
544
+ lastUpdated: str = Form(...)
545
+ ):
546
+ try:
547
+ # Save the uploaded file
548
+ upload_folder = "uploads/"
549
+ os.makedirs(upload_folder, exist_ok=True)
550
+ file_path = os.path.join(upload_folder, uploadFile.filename)
551
+
552
+ with open(file_path, "wb") as buffer:
553
+ shutil.copyfileobj(uploadFile.file, buffer)
554
+
555
+ # Save the details to the database
556
+ cnx = get_db_connection()
557
+ cursor = cnx.cursor()
558
+ query = """
559
+ INSERT INTO knowledge_base (company_id,file_path, document_name, document_desc, department, version,vectorDBflag, last_updated)
560
+ VALUES (%s,%s, %s, %s, %s, %s,%s, %s)
561
+ """
562
+ values = (company_id,file_path, documentName, documentDescription, department, version,vectorDBflag, lastUpdated)
563
+ cursor.execute(query, values)
564
+ cnx.commit()
565
+ row_id=cursor.lastrowid
566
+ cursor.close()
567
+ cnx.close()
568
+
569
+ logging.info(f"Document {documentName} uploaded successfully")
570
+ return JSONResponse(status_code=200, content={"message": "Data saved successfully", "row_id": row_id})
571
+ #return RedirectResponse(url="/knowledgebase", status_code=302)
572
+ except mysql.connector.Error as err:
573
+ logging.error(f"Database error: {err}")
574
+ raise HTTPException(status_code=500, detail="Internal Server Error")
575
+
576
+ #to retrieve from knowledgebase
577
+ @app.get("/api/document_upload")
578
+ async def get_document(company_id: str = Query(...)):
579
+ print(f"Received companyId and name: {company_id}") # Log rec
580
+ #async def get_data_connectors(company_id: str, company_name: str):
581
+ logging.info(f"Received request for company_id and company_id: {company_id}")
582
+ try:
583
+ cnx = get_db_connection()
584
+ cursor = cnx.cursor()
585
+ query = """
586
+ SELECT kb.kid,kb.company_id, kb.file_path, kb.document_name, kb.document_desc,kb.department,kb.version,kb.vectorDBflag,kb.last_updated
587
+ FROM u852023448_redmindgpt.knowledge_base kb
588
+ JOIN u852023448_redmindgpt.company_detail cd ON kb.company_id = cd.company_id
589
+ WHERE kb.company_id = %s
590
+ """
591
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
592
+ params = (company_id,)
593
+ logging.info(f"Query parameters: {params}")
594
+ print(f"Query parameters: {params}")
595
+
596
+ cursor.execute(query, params) # Pa
597
+ result = cursor.fetchall()
598
+ logging.info(f"Query result: {result}")
599
+ cursor.close
600
+ cnx.close()
601
+ companies=[]
602
+ for row in result:
603
+
604
+ companies.append({
605
+ "row_id":row[0],
606
+ "company_id": row[1],
607
+ "file_path":row[2],
608
+ "document_name": row[3],
609
+ "document_desc": row[4],
610
+ "department": row[5],
611
+ "version": row[6],
612
+ "vectorDBflag":row[7],
613
+ "last_updated": row[8]
614
+ })
615
+ if companies:
616
+ return companies
617
+ else:
618
+ logging.warning(f"No document found for company_id: {company_id}")
619
+ raise HTTPException(status_code=404, detail="Data document not found")
620
+ except mysql.connector.Error as err:
621
+ logging.error(f"Database error: {err}")
622
+ raise HTTPException(status_code=500, detail="Internal Server Error")
623
+
624
+ #on update of modal form the data table is refresh the value in datatable
625
+ @app.get("/api/document_update")
626
+ async def get_document(company_id: str = Query(...)):
627
+ print(f"Received companyId and name: {company_id},{company_id}") # Log rec
628
+ #async def get_data_connectors(company_id: str, company_name: str):
629
+ logging.info(f"Received request for company_id and company_id: {company_id},{company_id}")
630
+ try:
631
+ cnx = get_db_connection()
632
+ cursor = cnx.cursor()
633
+ query = """
634
+ SELECT kb.kid,kb.company_id, kb.file_path, kb.document_name, kb.document_desc,kb.department,kb.version,kb.vectorDBflag,kb.last_updated
635
+ FROM u852023448_redmindgpt.knowledge_base kb
636
+ JOIN u852023448_redmindgpt.company_detail cd ON kb.company_id = cd.company_id
637
+ WHERE kb.company_id = %s
638
+ """
639
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
640
+ values= (company_id,)
641
+ # logging.info(f"Query parameters: {params}")
642
+ print(f"Query parameters: {values}")
643
+
644
+ cursor.execute(query, values) # Pa
645
+ result = cursor.fetchall()
646
+ logging.info(f"Query result: {r.esult}")
647
+ cursor.close
648
+ cnx.close()
649
+ companies=[]
650
+ for row in result:
651
+
652
+ companies.append({
653
+ "kid":row[0],
654
+ "company_id": row[1],
655
+ "file_path":row[2],
656
+ "document_name": row[3],
657
+ "document_desc": row[4],
658
+ "department": row[5],
659
+ "version": row[6],
660
+ "vectorDBflag":row[7],
661
+ "last_updated": row[8]
662
+ })
663
+ if companies:
664
+ return companies
665
+ else:
666
+ logging.warning(f"No document found for company_id: {company_id}")
667
+ raise HTTPException(status_code=404, detail="Data document not found")
668
+ except mysql.connector.Error as err:
669
+ logging.error(f"Database error: {err}")
670
+ raise HTTPException(status_code=500, detail="Internal Server Error")
671
+
672
+ #to get data for view in knowledgebase
673
+ @app.get("/api/getknowledgebase/{company_id}")
674
+ async def get_company_details(company_id: int):
675
+ company = await get_knowledge_from_db(company_id)
676
+ if not company:
677
+ raise HTTPException(status_code=404, detail="Company not found")
678
+ return company
679
+
680
+ async def get_knowledge_from_db(company_id: int):
681
+ try:
682
+ # Establish a connection to the database
683
+ cnx = get_db_connection()
684
+ if cnx is None:
685
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
686
+ cursor = cnx.cursor(dictionary=True)
687
+ query = "SELECT * FROM knowledge_base WHERE kid = %s"
688
+ cursor.execute(query, (company_id,))
689
+ company = cursor.fetchone()
690
+ cursor.close()
691
+ cnx.close()
692
+ if company:
693
+ logging.debug(f"Extracted filename")
694
+ if company.get('file_path'):
695
+ company['file_path'] = os.path.basename(company['file_path'])
696
+ logging.debug(f"Extracted filename: {company['file_path']}")
697
+ return company
698
+ else:
699
+ raise HTTPException(status_code=404, detail="Company not found or file not found for the company")
700
+ except mysql.connector.Error as err:
701
+ logging.error(f"Error fetching company: {err}")
702
+ raise HTTPException(status_code=500, detail="Failed to fetch company")
703
+
704
+ # to edit the knowledgebase details
705
+ @app.put("/api/putknowledgebase/{companyId}")
706
+ async def update_company_details(
707
+ request: Request,
708
+ companyId: int,
709
+ company_id: str = Form(...),
710
+ file_path: UploadFile = File(...),
711
+ documentName: str = Form(...),
712
+ documentDescription: str = Form(...),
713
+ department: str = Form(...),
714
+ version: str = Form(...),
715
+ vectorDBFlag: str = Form(...),
716
+ lastUpdated: str = Form(...)
717
+ ):
718
+ logging.info(f"Received request for company data with ID inside edit/update knowledgebase: {companyId}")
719
+ print(f"Received request for company data with ID inside edit/update knowledgebase file name: {file_path.filename}")
720
+
721
+ # Create the upload folder if it doesn't exist
722
+ upload_folder = "uploads/"
723
+ os.makedirs(upload_folder, exist_ok=True)
724
+
725
+ # Construct the file path for saving
726
+ saved_file_path = os.path.join(upload_folder, file_path.filename)
727
+
728
+ try:
729
+ # Save the uploaded file to the server
730
+ with open(saved_file_path, "wb") as buffer:
731
+ shutil.copyfileobj(file_path.file, buffer)
732
+ except Exception as e:
733
+ logging.error(f"Error saving file: {e}")
734
+ raise HTTPException(status_code=500, detail="Failed to save file")
735
+
736
+ # Prepare the company data dictionary
737
+ company_data = {
738
+ 'kid': companyId,
739
+ 'company_id': company_id,
740
+ 'file_path': saved_file_path, # Use the path where the file was saved
741
+ 'document_name': documentName,
742
+ 'document_desc': documentDescription,
743
+ 'department': department,
744
+ 'version': version,
745
+ 'vectorDBflag': vectorDBFlag,
746
+ 'last_updated': lastUpdated
747
+ }
748
+
749
+ # Update the knowledge base in the database
750
+ updated_company = await update_knowledge_in_db(companyId, company_data)
751
+ if not updated_company:
752
+ raise HTTPException(status_code=500, detail="Failed to update company")
753
+ return updated_company
754
+
755
+ async def update_knowledge_in_db(kid: int, company_data: dict):
756
+ try:
757
+ logging.info(f"Updating knowledge base for ID: {kid}")
758
+ cnx = get_db_connection()
759
+ if cnx is None:
760
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
761
+
762
+ cursor = cnx.cursor()
763
+ update_query = """
764
+ UPDATE u852023448_redmindgpt.knowledge_base kb
765
+ SET kb.company_id = %s, kb.document_name = %s, kb.document_desc = %s,
766
+ kb.department = %s, kb.version = %s, kb.vectorDBflag = %s, kb.last_updated = %s
767
+ WHERE kb.kid = %s;
768
+ """
769
+ logging.info(f"Executing update query: {update_query}")
770
+
771
+ cursor.execute(update_query, (
772
+ company_data['company_id'],
773
+ company_data['document_name'],
774
+ company_data['document_desc'],
775
+ company_data['department'],
776
+ company_data['version'],
777
+ company_data['vectorDBflag'],
778
+ company_data['last_updated'],
779
+ kid
780
+ ))
781
+
782
+ cnx.commit()
783
+ success = cursor.rowcount > 0
784
+ cursor.close()
785
+ cnx.close()
786
+
787
+ if not success:
788
+ logging.info("No rows updated")
789
+ return None
790
+ logging.info("Update successful")
791
+ return company_data
792
+ except mysql.connector.Error as err:
793
+ logging.error(f"Database error: {err}")
794
+ raise HTTPException(status_code=500, detail="Failed to update company")
795
+ except Exception as e:
796
+ logging.error(f"Unexpected error: {e}")
797
+ raise HTTPException(status_code=500, detail="Unexpected error occurred")
798
+
799
+
800
+ def delete_knowledge_from_db(company_id: int) -> bool:
801
+ print(f"Received knowledge base company_id: {company_id}") # Debug statement
802
+ logging.info(f"Received request for knowledgebase company id: {company_id}")
803
+ try:
804
+ # Establish a connection to the database
805
+ cnx = get_db_connection()
806
+ if cnx is None:
807
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
808
+ cursor = cnx.cursor()
809
+ delete_query = "DELETE FROM knowledge_base WHERE kid = %s"
810
+ cursor.execute(delete_query, (company_id,))
811
+ cnx.commit()
812
+ success = cursor.rowcount > 0
813
+ cursor.close()
814
+ cnx.close()
815
+ return success
816
+ except mysql.connector.Error as err:
817
+ logging.error(f"Error deleting company: {err}")
818
+ raise HTTPException(status_code=500, detail="Failed to delete company")
819
+
820
+ #to perform delete operation in knowlegebase
821
+ @app.delete("/api/delknowledgebase/{company_id}")
822
+ async def delete_company(company_id: int):
823
+ deletion_success = delete_knowledge_from_db(company_id)
824
+ if not deletion_success:
825
+ raise HTTPException(status_code=404, detail="Company not found or failed to delete")
826
+ return {"message": "Company deleted successfully"}
827
+
828
+
829
+ @app.get("/data_connectors")
830
+ async def data_connectors(request: Request):
831
+ try:
832
+ # Retrieve cookies
833
+ role = request.cookies.get("role")
834
+ company_id = request.cookies.get("company_id")
835
+
836
+ # Render the template with the role and company_id
837
+ return templates.TemplateResponse("data_connectors.html", {
838
+ "request": request,
839
+ "role": role,
840
+ "company_id": company_id,
841
+ "title": "Data Connectors"
842
+ })
843
+ except Exception as e:
844
+ # Handle exceptions
845
+ logging.error(f"Error: {e}")
846
+ raise HTTPException(status_code=500, detail="Internal Server Error")
847
+
848
+ #to insert into data_connectors
849
+ @app.post("/save_data_connectors")
850
+ async def save_data_connectors( request: Request,
851
+ company_id: int = Form(...),
852
+ database: List[str] = Form(...),
853
+ server: str = Form(...),
854
+ port: str = Form(...),
855
+ databaseName:List[str]= Form(...),
856
+ username: str=Form(...),
857
+ password: str=Form(...),
858
+ selectedTables: List[str] = Form(...)):
859
+ logging.info(f"Received form submission for database_connectors")
860
+ print(f"Received form submission for database_connectors")
861
+ try:
862
+ cnx = get_db_connection()
863
+ cursor = cnx.cursor()
864
+ # Check if the company_id already exists in the data_connectors table
865
+ check_query = "SELECT COUNT(*) FROM data_connectors WHERE company_id = %s"
866
+ cursor.execute(check_query, (company_id,))
867
+ exists = cursor.fetchone()[0] > 0
868
+
869
+ if exists:
870
+ # Update the existing record
871
+ query = """
872
+ UPDATE data_connectors
873
+ SET databasetype = %s, serverip = %s, port = %s, database_name = %s, username = %s, password = %s, dbtablename = %s
874
+ WHERE company_id = %s
875
+ """
876
+ values = (",".join(database), server, port, ",".join(databaseName), username, password or '', ",".join(selectedTables), company_id)
877
+ logging.info(f"Executing update query: {query} with values: {values}")
878
+ cursor.execute(query, values)
879
+ cnx.commit()
880
+ logging.info(f"Query executed successfully, {cursor.rowcount} row(s) updated")
881
+ else:
882
+ # Insert a new record
883
+ query = """
884
+ INSERT INTO data_connectors(company_id, databasetype, serverip, port, database_name, username, password, dbtablename)
885
+ VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
886
+ """
887
+ values = (company_id, ",".join(database), server, port, ",".join(databaseName), username, password or '', ",".join(selectedTables))
888
+ logging.info(f"Executing insert query: {query} with values: {values}")
889
+ cursor.execute(query, values)
890
+ cnx.commit()
891
+ logging.info(f"Query executed successfully, {cursor.rowcount} row(s) inserted")
892
+
893
+ cursor.close()
894
+ cnx.close()
895
+
896
+ # logging.info(f"Data_connectors for {database} processed successfully")
897
+ # return JSONResponse(content={"status": "success", "message": "Data saved successfully"}, status_code=200)
898
+ response = {
899
+ "msg": "Data saved successfully",
900
+ "url": "/save_data_connectors", # The URL you want to redirect to
901
+ "created": True
902
+ }
903
+ return JSONResponse(content=response)
904
+
905
+
906
+ except mysql.connector.Error as err:
907
+ logging.error(f"Database error: {err}")
908
+ return JSONResponse(content={"status": "error", "message": "Internal Server Error"}, status_code=500)
909
+ except Exception as e:
910
+ logging.error(f"Unexpected error: {e}")
911
+ return JSONResponse(content={"status": "error", "message": "Unexpected Server Error"}, status_code=500)
912
+
913
+ @app.get("/api/check_data_connectors")
914
+ async def get_data_connectors(company_id: str = Query(...), company_name: str = Query(...)):
915
+ print(f"Received companyId and name: {company_id},{company_name}") # Log rec
916
+ #async def get_data_connectors(company_id: str, company_name: str):
917
+ logging.info(f"Received request for company_id and company_id: {company_id},{company_name}")
918
+ try:
919
+ cnx = get_db_connection()
920
+ cursor = cnx.cursor()
921
+ query = """
922
+ SELECT dc.company_id, dc.databasetype, dc.serverip, dc.port,dc.database_name, dc.username, dc.password ,dc.dbtablename
923
+ FROM u852023448_redmindgpt.data_connectors dc
924
+ JOIN u852023448_redmindgpt.company_detail cd ON dc.company_id = cd.company_id
925
+ WHERE dc.company_id = %s and cd.company_name=%s
926
+ """
927
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
928
+ params = (company_id,company_name)
929
+ logging.info(f"Query parameters: {params}")
930
+ print(f"Query parameters: {params}")
931
+
932
+ cursor.execute(query, params) # Pa
933
+ result = cursor.fetchone()
934
+ logging.info(f"Query result: {result}")
935
+ cursor.close()
936
+ cnx.close()
937
+
938
+ if result:
939
+ databasetype = result[1]
940
+ dbtablename = result[7].split(',') if result[7] else []
941
+ logging.info(f"Data found for company_id: {company_id}")
942
+ return {
943
+ "company_id": result[0],
944
+ "databasetype":databasetype,
945
+ "serverip": result[2],
946
+ "port": result[3],
947
+ "database_name": result[4],
948
+ "username": result[5],
949
+ "password": result[6],
950
+ "dbtablename": dbtablename
951
+ }
952
+ else:
953
+ logging.warning(f"No data found for company_id: {company_id}")
954
+ raise HTTPException(status_code=404, detail="Data connector not found")
955
+ except mysql.connector.Error as err:
956
+ logging.error(f"Database error: {err}")
957
+ raise HTTPException(status_code=500, detail="Internal Server Error")
958
+
959
+ @app.get("/API_connectors")
960
+ async def API_connectors(request: Request):
961
+ try:
962
+ # Retrieve cookies
963
+ role = request.cookies.get("role")
964
+ company_id = request.cookies.get("company_id")
965
+
966
+ # Render the template with the role and company_id
967
+ return templates.TemplateResponse("API_connectors.html", {
968
+ "request": request,
969
+ "role": role,
970
+ "company_id": company_id,
971
+ "title":"API Connectors"
972
+ })
973
+ except Exception as e:
974
+ # Handle exceptions
975
+ logging.error(f"Error: {e}")
976
+ raise HTTPException(status_code=500, detail="Internal Server Error")
977
+
978
+ #save api connectors
979
+ @app.post("/api/save_api_details")
980
+ async def API_saveconnectors(request: Request,
981
+ company_id:int=Form(...),
982
+ APIName:str=Form(...),
983
+ APIEndpoint:str=Form(...),
984
+ Auth_Bearer:str=Form(...),
985
+ Inputjson:str=Form(...),
986
+ OutputJson:str=Form(...),
987
+ Description:str=Form(...)):
988
+ logging.info(f"Received form submission for database_connectors")
989
+ try:
990
+ cnx =get_db_connection()
991
+ cursor = cnx.cursor()
992
+ #databasetype_json=json.dumps(database)
993
+ query = "INSERT INTO api_connectors(company_id,api_name, api_endpoint, auth_token, input_param,output_json,description) VALUES (%s,%s, %s, %s, %s,%s,%s)"
994
+ values = (company_id, APIName, APIEndpoint, Auth_Bearer, Inputjson,OutputJson,Description)
995
+ logging.info(f"Executing query: {query} with values: {values}")
996
+ cursor.execute(query, values)
997
+ cnx.commit()
998
+ logging.info(f"Query executed successfully, {cursor.rowcount} row(s) affected")
999
+ row_id = cursor.lastrowid
1000
+ cursor.close()
1001
+ cnx.close()
1002
+ logging.info(f"Data_connectors for {APIName} inserted successfully")
1003
+ return JSONResponse(status_code=200, content={"message": "Data saved successfully", "row_id": row_id})
1004
+ #return RedirectResponse(url="/data_connectors", status_code=302)
1005
+ except mysql.connector.Error as err:
1006
+ logging.error(f"Database error: {err}")
1007
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1008
+ # retrieve api connectors
1009
+ @app.get("/api/get_api_connectors")
1010
+ async def get_api_connectors(company_id: str = Query(...)):
1011
+ print(f"Received companyId and name: {company_id}") # Log rec
1012
+ #async def get_data_connectors(company_id: str, company_name: str):
1013
+ logging.info(f"Received request for company_id and company_id: {company_id}")
1014
+ try:
1015
+ cnx =get_db_connection()
1016
+ cursor = cnx.cursor()
1017
+ query = """
1018
+ SELECT ac.id, ac.company_id, ac.api_name, ac.api_endpoint,ac.auth_token,ac.input_param, ac.output_json, ac.description
1019
+ FROM u852023448_redmindgpt.api_connectors ac
1020
+ JOIN u852023448_redmindgpt.company_detail cd ON ac.company_id = cd.company_id
1021
+ WHERE ac.company_id = %s
1022
+ """
1023
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
1024
+ params = (company_id,)
1025
+ logging.info(f"Query parameters: {params}")
1026
+ print(f"Query parameters: {params}")
1027
+
1028
+ cursor.execute(query, params) # Pa
1029
+ result = cursor.fetchall()
1030
+ logging.info(f"Query result: {result}")
1031
+ cursor.close()
1032
+ cnx.close()
1033
+ companies=[]
1034
+ for row in result:
1035
+ companies.append({
1036
+ "row_id":row[0],
1037
+ "company_id": row[1],
1038
+ "APIName":row[2],
1039
+ "APIEndpoint": row[3]
1040
+ # "Auth_Bearer": result[3],
1041
+ # "Inputjson": result[4],
1042
+ #"OutputJson": result[5],
1043
+ #"description": result[6]
1044
+
1045
+ })
1046
+ if companies:
1047
+ return companies
1048
+ else:
1049
+ logging.warning(f"No data found for company_id: {company_id}")
1050
+ raise HTTPException(status_code=404, detail="Data connector not found")
1051
+ except mysql.connector.Error as err:
1052
+ logging.error(f"Database error: {err}")
1053
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1054
+ #to view the table details in modal
1055
+ @app.get("/api/viewapiconnectors/{company_id}")
1056
+ async def get_company_details(company_id: int):
1057
+
1058
+ company = await get_api_from_db(company_id)
1059
+ if not company:
1060
+ raise HTTPException(status_code=404, detail="Company not found")
1061
+ return company
1062
+
1063
+ async def get_api_from_db(company_id: int):
1064
+ try:
1065
+ # Establish a connection to the database
1066
+ cnx = get_db_connection()
1067
+ if cnx is None:
1068
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
1069
+ cursor = cnx.cursor(dictionary=True)
1070
+ query = "SELECT * FROM api_connectors WHERE id = %s"
1071
+ cursor.execute(query, (company_id,))
1072
+ company = cursor.fetchone()
1073
+ cursor.close()
1074
+ cnx.close()
1075
+ if company:
1076
+ logging.info(f"api details:{company}")
1077
+ return company
1078
+ else:
1079
+ raise HTTPException(status_code=404, detail="Company not found or file not found for the company")
1080
+ except mysql.connector.Error as err:
1081
+ logging.error(f"Error fetching company: {err}")
1082
+ raise HTTPException(status_code=500, detail="Failed to fetch company")
1083
+ #to edit the api details in modal form
1084
+ @app.put("/api/editapiconnectors/{companyId}")
1085
+ async def update_company_details(
1086
+ request: Request,
1087
+ companyId: int,
1088
+ company_id:str=Form(...),
1089
+ APIName:str=Form(...),
1090
+ APIEndpoint:str=Form(...),
1091
+ Auth_Bearer:str=Form(...),
1092
+ Inputjson:str=Form(...),
1093
+ OutputJson:str=Form(...),
1094
+ Description:str=Form(...)):
1095
+ logging.info(f"Received form submission for database_connectors")
1096
+ logging.info(f"Received request for company data with ID inside edit/update knowledgebase: {companyId}")
1097
+
1098
+ # Prepare the company data dictionary
1099
+ company_data = {
1100
+ 'kid': companyId,
1101
+ 'company_id': company_id,
1102
+ 'api_name': APIName,
1103
+ 'api_endpoint': APIEndpoint,
1104
+ 'auth_token': Auth_Bearer,
1105
+ 'input_param': Inputjson,
1106
+ 'output_json': OutputJson,
1107
+ 'description': Description
1108
+ }
1109
+
1110
+ # Update the knowledge base in the database
1111
+ updated_company = await update_api_in_db(companyId, company_data)
1112
+ if not updated_company:
1113
+ raise HTTPException(status_code=500, detail="Failed to update company")
1114
+ return updated_company
1115
+
1116
+ async def update_api_in_db(id: int, company_data: dict):
1117
+ try:
1118
+ logging.info(f"Updating api for ID: {id}")
1119
+ cnx = get_db_connection()
1120
+ if cnx is None:
1121
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
1122
+
1123
+ cursor = cnx.cursor()
1124
+ update_query = """
1125
+ UPDATE u852023448_redmindgpt.api_connectors ac
1126
+ SET ac.company_id = %s, ac.api_name = %s, ac.api_endpoint= %s,
1127
+ ac.auth_token= %s, ac.input_param= %s,ac.output_json = %s, ac.description= %s
1128
+ WHERE ac.id = %s;
1129
+ """
1130
+ logging.info(f"Executing update query: {update_query}")
1131
+
1132
+ cursor.execute(update_query, (
1133
+ company_data['company_id'],
1134
+ company_data['api_name'],
1135
+ company_data['api_endpoint'],
1136
+ company_data['auth_token'],
1137
+ company_data['input_param'],
1138
+ company_data['output_json'],
1139
+ company_data['description'],
1140
+ id
1141
+ ))
1142
+
1143
+ cnx.commit()
1144
+ success = cursor.rowcount > 0
1145
+ cursor.close()
1146
+ cnx.close()
1147
+
1148
+ if not success:
1149
+ logging.info("No rows updated")
1150
+ return None
1151
+ logging.info("Update successful")
1152
+ return company_data
1153
+ except mysql.connector.Error as err:
1154
+ logging.error(f"Database error: {err}")
1155
+ raise HTTPException(status_code=500, detail="Failed to update company")
1156
+ except Exception as e:
1157
+ logging.error(f"Unexpected error: {e}")
1158
+ raise HTTPException(status_code=500, detail="Unexpected error occurred")
1159
+
1160
+ #on update of modal form the data table is refreshed to dispalyupdated value in datatable
1161
+ @app.get("/api/api_updatetable")
1162
+ async def get_document(company_id: str = Query(...)):
1163
+ print(f"Received companyId and name for api datatable update: {company_id},{company_id}") # Log rec
1164
+ #async def get_data_connectors(company_id: str, company_name: str):
1165
+ logging.info(f"Received request for company_id and company_id: {company_id},{company_id}")
1166
+ try:
1167
+ cnx = get_db_connection()
1168
+ cursor = cnx.cursor()
1169
+ query=""" SELECT ac.id,ac.company_id, ac.api_name, ac.api_endpoint,ac.auth_token,ac.input_param, ac.output_json, ac.description
1170
+ FROM u852023448_redmindgpt.api_connectors ac
1171
+ JOIN u852023448_redmindgpt.company_detail cd ON ac.company_id = cd.company_id
1172
+ WHERE ac.company_id = %s
1173
+ """
1174
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
1175
+ values= (company_id,)
1176
+ # logging.info(f"Query parameters: {params}")
1177
+ print(f"Query parameters: {values}")
1178
+
1179
+ cursor.execute(query, values) # Pa
1180
+ result = cursor.fetchall()
1181
+ logging.info(f"Query result for update table: {result}")
1182
+ cursor.close
1183
+ cnx.close()
1184
+ companies=[]
1185
+ for row in result:
1186
+
1187
+ companies.append({
1188
+ "row_id":row[0],
1189
+ "company_id": row[1],
1190
+ "api_name":row[2],
1191
+ "api_endpoint": row[3],
1192
+ # "Auth_Bearer": row[4],
1193
+ # "Inputjson": row[5],
1194
+ # "OutputJson": row[6],
1195
+ # "description": row[7]
1196
+
1197
+ })
1198
+ if companies:
1199
+ return companies
1200
+ else:
1201
+ logging.warning(f"No document found for company_id: {company_id}")
1202
+ raise HTTPException(status_code=404, detail="Data document not found")
1203
+ except mysql.connector.Error as err:
1204
+ logging.error(f"Database error: {err}")
1205
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1206
+
1207
+ #to delete api details from db
1208
+ @app.delete("/api/deleteapi/{company_id}")
1209
+ async def delete_company(company_id: int):
1210
+ deletion_success = delete_api_from_db(company_id)
1211
+ if not deletion_success:
1212
+ raise HTTPException(status_code=404, detail="Company not found or failed to delete")
1213
+ return {"message": "Company deleted successfully"}
1214
+
1215
+ def delete_api_from_db(company_id: int) -> bool:
1216
+ print(f"Received api for company_id: {company_id}") # Debug statement
1217
+ logging.info(f"Received request for api for company id: {company_id}")
1218
+ try:
1219
+ # Establish a connection to the database
1220
+ cnx = get_db_connection()
1221
+ if cnx is None:
1222
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
1223
+ cursor = cnx.cursor()
1224
+ delete_query = "DELETE FROM api_connectors WHERE id = %s"
1225
+ cursor.execute(delete_query, (company_id,))
1226
+ cnx.commit()
1227
+ success = cursor.rowcount > 0
1228
+ cursor.close()
1229
+ cnx.close()
1230
+ return success
1231
+ except mysql.connector.Error as err:
1232
+ logging.error(f"Error deleting company: {err}")
1233
+ raise HTTPException(status_code=500, detail="Failed to delete company")
1234
+
1235
+
1236
+ @app.get("/prompt_template")
1237
+ async def prompt_template(request: Request):
1238
+ try:
1239
+ # Retrieve cookies
1240
+ role = request.cookies.get("role")
1241
+ company_id = request.cookies.get("company_id")
1242
+
1243
+ # Render the template with the role and company_id
1244
+ return templates.TemplateResponse("prompt_template.html", {
1245
+ "request": request,
1246
+ "role": role,
1247
+ "company_id": company_id,
1248
+ "title":"Prompt Templates"
1249
+ })
1250
+ except Exception as e:
1251
+ # Handle exceptions
1252
+ logging.error(f"Error: {e}")
1253
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1254
+ # to insert into prompt templates
1255
+ @app.post("/api/save_prompt_details")
1256
+ async def prompt_saveconnectors(request: Request,
1257
+ company_id:int=Form(...),
1258
+ scenario:str=Form(...),
1259
+ sampleprompt:str=Form(...),
1260
+ comments:str=Form(...),
1261
+ ):
1262
+ logging.info(f"Received form submission for database_connectors")
1263
+ try:
1264
+ cnx =get_db_connection()
1265
+ cursor = cnx.cursor()
1266
+ #databasetype_json=json.dumps(database)
1267
+ query = "INSERT INTO prompt_templates(company_id,scenario, prompts, comments) VALUES (%s,%s, %s, %s)"
1268
+ values = (company_id, scenario, sampleprompt, comments)
1269
+ logging.info(f"Executing query: {query} with values: {values}")
1270
+ cursor.execute(query, values)
1271
+ cnx.commit()
1272
+ logging.info(f"Query executed successfully, {cursor.rowcount} row(s) affected")
1273
+ row_id = cursor.lastrowid # Get the last inserted row_id
1274
+ cursor.close()
1275
+ cnx.close()
1276
+ logging.info(f"Data_connectors for {scenario} inserted successfully")
1277
+ return JSONResponse(status_code=200, content={"message": "Data saved successfully", "row_id": row_id})
1278
+ #return RedirectResponse(url="/prompt_template", status_code=302)
1279
+ except mysql.connector.Error as err:
1280
+ logging.error(f"Database error: {err}")
1281
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1282
+ # retrieve api connectors
1283
+ @app.get("/api/get_prompt_templates")
1284
+ async def get_prompt_connectors(company_id: str = Query(...)):
1285
+ print(f"Received companyId and name: {company_id}") # Log rec
1286
+ #async def get_data_connectors(company_id: str, company_name: str):
1287
+ logging.info(f"Received request for company_id and company_id: {company_id}")
1288
+ try:
1289
+ cnx =get_db_connection()
1290
+ cursor = cnx.cursor()
1291
+ query = """
1292
+ SELECT pt.id,pt.company_id,pt.scenario,pt.prompts,pt.comments
1293
+ FROM u852023448_redmindgpt.prompt_templates pt
1294
+ JOIN u852023448_redmindgpt.company_detail cd ON pt.company_id = cd.company_id
1295
+ WHERE pt.company_id = %s
1296
+ """
1297
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
1298
+ params = (company_id,)
1299
+ logging.info(f"Query parameters: {params}")
1300
+ print(f"Query parameters: {params}")
1301
+
1302
+ cursor.execute(query, params) # Pa
1303
+ result = cursor.fetchall()
1304
+ logging.info(f"Query result: {result}")
1305
+ cursor.close()
1306
+ cnx.close()
1307
+ companies=[]
1308
+ for row in result:
1309
+ companies.append({
1310
+ "row_id":row[0],
1311
+ "company_id": row[1],
1312
+ "scenario":row[2],
1313
+ "prompt": row[3]
1314
+ # "Auth_Bearer": result[3],
1315
+ # "Inputjson": result[4],
1316
+ #"OutputJson": result[5],
1317
+ #"description": result[6]
1318
+
1319
+ })
1320
+ if companies:
1321
+ return companies
1322
+ else:
1323
+ logging.warning(f"No data found for company_id: {company_id}")
1324
+ raise HTTPException(status_code=404, detail="Data connector not found")
1325
+ except mysql.connector.Error as err:
1326
+ logging.error(f"Database error: {err}")
1327
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1328
+
1329
+ def delete_prompt_template_from_db(row_id: int) -> bool:
1330
+ logging.info(f"Received request for prompt_template company id: {row_id}")
1331
+ logging.info(f"Received request for prompt_template row id: {row_id}")
1332
+
1333
+ try:
1334
+ # Establish a connection to the database
1335
+ cnx = get_db_connection()
1336
+ if cnx is None:
1337
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
1338
+ cursor = cnx.cursor()
1339
+ delete_query = "DELETE FROM prompt_templates WHERE id = %s"
1340
+
1341
+ logging.info(f"sql delete query for prompt template ===> {delete_query}")
1342
+
1343
+ cursor.execute(delete_query, (row_id,))
1344
+ cnx.commit()
1345
+ success = cursor.rowcount > 0
1346
+ logging.info (f"deleted succesfully ! ===> {success}")
1347
+
1348
+ cursor.close()
1349
+ cnx.close()
1350
+ return success
1351
+ except mysql.connector.Error as err:
1352
+ print('python')
1353
+ logging.error(f"Error deleting company: {err}")
1354
+ raise HTTPException(status_code=500, detail="Failed to delete company")
1355
+
1356
+ @app.delete("/api/prompt_template_for_del/{row_id}")
1357
+ async def delete_company(row_id: int):
1358
+ deletion_success = delete_prompt_template_from_db(row_id)
1359
+ logging.info(f"company row_id +++> {row_id}")
1360
+
1361
+ if not deletion_success:
1362
+ raise HTTPException(status_code=404, detail="Company not found or failed to delete")
1363
+ return {"message": "Company deleted successfully"}
1364
+
1365
+ # promt_template view function ! ............
1366
+
1367
+ #to get data for view in promt_templae by id
1368
+ @app.get("/api/getpromttemplate/{company_id}")
1369
+ async def get_promt_company_details(company_id: int):
1370
+ company = await get_promt_from_db(company_id)
1371
+ if not company:
1372
+ raise HTTPException(status_code=404, detail="Company not found")
1373
+ return company
1374
+
1375
+ async def get_promt_from_db(company_id: int):
1376
+ try:
1377
+ # Establish a connection to the database
1378
+ cnx = get_db_connection()
1379
+ if cnx is None:
1380
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
1381
+ cursor = cnx.cursor(dictionary=True)
1382
+ query = "SELECT * FROM prompt_templates WHERE id = %s"
1383
+ logging.info(f"row_id in db addresss ========> {company_id}")
1384
+
1385
+ cursor.execute(query, (company_id,))
1386
+ company = cursor.fetchone()
1387
+ cursor.close()
1388
+ cnx.close()
1389
+ if company:
1390
+ logging.info(f"row_id in db addresss ========> {company}")
1391
+ return company
1392
+
1393
+ else:
1394
+ raise HTTPException(status_code=404, detail="Company not found or file not found for the company")
1395
+ except mysql.connector.Error as err:
1396
+ logging.error(f"Error fetching company: {err}")
1397
+ raise HTTPException(status_code=500, detail="Failed to fetch company")
1398
+
1399
+ # Function to update company details
1400
+ @app.put("/api/putprompttemplates/{kid}")
1401
+ async def update_company_details(
1402
+ kid: int,
1403
+ scenario: str = Form(...),
1404
+ prompt: str = Form(...),
1405
+ comments: str = Form(...)
1406
+ ):
1407
+ logging.info(f"Received request for company data with ID: {kid}")
1408
+ company_data = {
1409
+ 'scenario': scenario,
1410
+ 'prompts': prompt,
1411
+ 'comments': comments,
1412
+ }
1413
+ updated_company = await update_prompt_in_db(kid, company_data)
1414
+ if not updated_company:
1415
+ raise HTTPException(status_code=500, detail="Failed to update company")
1416
+ return updated_company
1417
+
1418
+ # Database query function to update company data
1419
+ async def update_prompt_in_db(kid: int, company_data: dict):
1420
+ try:
1421
+ logging.info(f"Updating prompt for ID: {kid}")
1422
+ cnx = get_db_connection()
1423
+ if cnx is None:
1424
+ raise HTTPException(status_code=500, detail="Failed to connect to the database")
1425
+
1426
+ cursor = cnx.cursor()
1427
+ update_query = """
1428
+ UPDATE u852023448_redmindgpt.prompt_templates pt
1429
+ SET pt.scenario=%s, pt.prompts=%s, pt.comments=%s
1430
+ WHERE pt.id = %s;
1431
+ """
1432
+ logging.info(f"row_id in prompt db address ========> {kid}")
1433
+ logging.info(f"SQL update query for company ===> {update_query}")
1434
+
1435
+ cursor.execute(update_query, (
1436
+ company_data['scenario'],
1437
+ company_data['prompts'],
1438
+ company_data['comments'],
1439
+ kid
1440
+ ))
1441
+
1442
+ cnx.commit()
1443
+ success = cursor.rowcount > 0
1444
+ cursor.close()
1445
+ cnx.close()
1446
+
1447
+ if not success:
1448
+ return None
1449
+ return company_data
1450
+
1451
+ except mysql.connector.Error as err:
1452
+ logging.error(f"Error updating company: {err}")
1453
+ raise HTTPException(status_code=500, detail="Failed to update company")
1454
+
1455
+ # to refresh prompt data table
1456
+ @app.get("/api/prompt_update")
1457
+ async def get_document(company_id: str = Query(...)):
1458
+ print(f"Received companyId and name: {company_id},{company_id}") # Log rec
1459
+ #async def get_data_connectors(company_id: str, company_name: str):
1460
+ logging.info(f"Received request for company_id and company_id: {company_id},{company_id}")
1461
+ try:
1462
+ cnx = get_db_connection()
1463
+ cursor = cnx.cursor()
1464
+ query = """
1465
+ SELECT pt.id,pt.company_id,pt.scenario,pt.prompts,pt.comments
1466
+ FROM u852023448_redmindgpt.prompt_templates pt
1467
+ JOIN u852023448_redmindgpt.company_detail cd ON pt.company_id = cd.company_id
1468
+ WHERE pt.company_id = %s
1469
+ """
1470
+ logging.info(f"Executing query: {query} with company_id: {company_id}")
1471
+ values= (company_id,)
1472
+ # logging.info(f"Query parameters: {params}")
1473
+ print(f"Query parameters: {values}")
1474
+
1475
+ cursor.execute(query, values) # Pa
1476
+ result = cursor.fetchall()
1477
+ logging.info(f"Query result: {result}")
1478
+ cursor.close
1479
+ cnx.close()
1480
+ companies=[]
1481
+ for row in result:
1482
+ companies.append({
1483
+ 'id':row[0],
1484
+ "company_id": row[1],
1485
+ "scenario":row[2],
1486
+ "prompts": row[3]
1487
+ # "Auth_Bearer": result[3],
1488
+ # "Inputjson": result[4],
1489
+ #"OutputJson": result[5],
1490
+ #"description": result[6]
1491
+
1492
+ })
1493
+ if companies:
1494
+ logging.info(f"the primary key id is {companies}")
1495
+ return companies
1496
+ else:
1497
+ logging.warning(f"No document found for company_id: {company_id}")
1498
+ raise HTTPException(status_code=404, detail="Data document not found")
1499
+ except mysql.connector.Error as err:
1500
+ logging.error(f"Database error: {err}")
1501
+ raise HTTPException(status_code=500, detail="Internal Server Error")
1502
+
1503
+ @app.get("/chatbot")
1504
+ async def chatbot(request: Request):
1505
+ return templates.TemplateResponse("chatbot.html", {"request": request,"title":"Chatbot"})
1506
+
1507
+ if __name__ == "__main__":
1508
+ import uvicorn
1509
+ uvicorn.run(app, host="127.0.0.1", port=8000)
config/__pycache__/settings.cpython-310.pyc ADDED
Binary file (424 Bytes). View file
 
config/__pycache__/settings.cpython-311.pyc ADDED
Binary file (511 Bytes). View file
 
config/__pycache__/settings.cpython-312.pyc ADDED
Binary file (444 Bytes). View file
 
config/settings.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ import os
2
+
3
+ class Settings:
4
+ DB_URI = "mysql+mysqlconnector://redmindgen:51([email protected]:3306/collegedb"
logs/redmindgen.log ADDED
The diff for this file is too large to render. See raw diff
 
redmindgen.log ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 2024-06-26 15:05:45,671 - INFO - File upload start
2
+ 2024-06-26 15:06:10,308 - INFO - File upload start
3
+ 2024-06-26 20:56:57,535 - INFO - File upload start
4
+ 2024-06-27 10:23:14,083 - INFO - File upload start
5
+ 2024-06-27 10:25:33,473 - INFO - File upload start
6
+ 2024-06-27 19:46:45,688 - INFO - File upload start
7
+ 2024-06-28 11:30:27,909 - INFO - File upload start
8
+ 2024-06-28 11:31:34,367 - INFO - File upload start
9
+ 2024-06-28 11:45:59,119 - INFO - File upload start
10
+ 2024-06-28 12:03:18,147 - INFO - File upload start
11
+ 2024-06-28 12:23:09,794 - INFO - File upload start
12
+ 2024-06-28 12:40:34,867 - INFO - File upload start
13
+ 2024-06-28 12:50:31,907 - INFO - File upload start
14
+ 2024-06-28 12:52:50,973 - INFO - File upload start
15
+ 2024-06-28 14:13:58,362 - INFO - File upload start
16
+ 2024-06-28 14:15:39,003 - INFO - File upload start
17
+ 2024-06-28 14:16:38,501 - INFO - File upload start
18
+ 2024-06-28 14:30:55,406 - INFO - File upload start
19
+ 2024-06-28 14:31:33,800 - INFO - File upload start
20
+ 2024-06-28 14:32:14,903 - INFO - File upload start
21
+ 2024-06-28 14:33:13,832 - INFO - File upload start
22
+ 2024-06-28 14:37:37,770 - INFO - File upload start
23
+ 2024-06-28 14:38:27,848 - INFO - File upload start
24
+ 2024-06-28 14:38:45,450 - INFO - File upload start
25
+ 2024-06-28 14:39:22,595 - INFO - File upload start
26
+ 2024-06-28 14:41:45,804 - INFO - File upload start
27
+ 2024-06-28 14:42:28,047 - INFO - File upload start
28
+ 2024-06-28 14:42:52,537 - INFO - File upload start
29
+ 2024-06-28 14:42:55,555 - INFO - File upload start
30
+ 2024-06-28 14:43:43,017 - INFO - File upload start
31
+ 2024-06-28 14:46:42,645 - INFO - File upload start
32
+ 2024-06-28 14:47:57,404 - INFO - File upload start
33
+ 2024-06-28 14:51:18,761 - INFO - File upload start
34
+ 2024-06-28 14:51:45,278 - INFO - File upload start
35
+ 2024-06-28 14:52:18,757 - INFO - File upload start
36
+ 2024-06-28 14:54:31,946 - INFO - File upload start
37
+ 2024-06-28 14:54:43,198 - INFO - File upload start
38
+ 2024-07-05 14:37:16,254 - INFO - File upload start
39
+ 2024-07-09 10:24:45,033 - INFO - File upload start
40
+ 2024-07-09 10:27:12,902 - INFO - File upload start
41
+ 2024-07-09 10:28:05,599 - INFO - File upload start
42
+ 2024-07-09 10:28:32,249 - INFO - File upload start
43
+ 2024-07-09 10:30:40,884 - INFO - File upload start
44
+ 2024-07-09 10:32:49,297 - INFO - File upload start
45
+ 2024-07-09 10:33:52,842 - INFO - File upload start
46
+ 2024-07-09 10:36:09,099 - INFO - File upload start
47
+ 2024-07-09 10:41:58,156 - INFO - File upload start
48
+ 2024-07-09 10:44:11,534 - INFO - File upload start
49
+ 2024-07-09 13:48:26,883 - INFO - File upload start
50
+ 2024-07-09 13:51:02,458 - INFO - File upload start
51
+ 2024-07-09 13:52:43,802 - INFO - File upload start
52
+ 2024-07-09 13:53:24,800 - INFO - File upload start
53
+ 2024-07-09 14:13:09,374 - INFO - File upload start
54
+ 2024-07-09 14:15:08,118 - INFO - File upload start
55
+ 2024-07-09 14:20:15,337 - INFO - File upload start
56
+ 2024-07-09 15:18:47,858 - INFO - File upload start
57
+ 2024-07-09 15:20:43,515 - INFO - File upload start
58
+ 2024-07-09 15:22:10,977 - INFO - File upload start
59
+ 2024-07-09 15:23:11,741 - INFO - File upload start
60
+ 2024-07-09 15:24:02,811 - INFO - File upload start
61
+ 2024-07-09 15:24:51,644 - INFO - File upload start
62
+ 2024-07-09 15:26:57,307 - INFO - File upload start
63
+ 2024-07-09 15:27:47,890 - INFO - File upload start
64
+ 2024-07-09 15:28:54,605 - INFO - File upload start
65
+ 2024-07-09 15:32:04,124 - INFO - File upload start
66
+ 2024-07-10 10:48:52,249 - INFO - File upload start
67
+ 2024-07-18 12:33:01,569 - INFO - File upload start
68
+ 2024-07-18 12:43:49,151 - INFO - File upload start
69
+ 2024-07-18 12:50:59,304 - INFO - File upload start
70
+ 2024-07-18 12:51:05,343 - INFO - File upload start
71
+ 2024-07-18 13:46:12,984 - INFO - File upload start
72
+ 2024-07-18 13:47:27,113 - INFO - File upload start
73
+ 2024-07-18 13:53:14,622 - INFO - File upload start
74
+ 2024-07-18 13:55:23,502 - INFO - File upload start
75
+ 2024-07-18 14:08:29,239 - INFO - File upload start
76
+ 2024-07-18 14:16:55,475 - INFO - File upload start
77
+ 2024-07-18 14:25:44,967 - INFO - File upload start
78
+ 2024-07-18 14:36:46,313 - INFO - File upload start
79
+ 2024-07-18 14:40:11,808 - INFO - File upload start
80
+ 2024-07-18 14:40:42,615 - INFO - Received question: what is the weather in chennai
81
+ 2024-07-18 14:40:43,629 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
82
+ 2024-07-18 14:40:55,968 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
83
+ 2024-07-18 14:40:55,984 - INFO - Executing SQL query: This question is not related to the provided database schema, as it is about the weather in a specific location (Chennai) and cannot be answered using the data in the tables. You would need to use a weather API or service to get the current weather information for Chennai.
84
+ 2024-07-18 14:40:56,620 - ERROR - Error executing query: This question is not related to the provided database schema, as it is about the weather in a specific location (Chennai) and cannot be answered using the data in the tables. You would need to use a weather API or service to get the current weather information for Chennai., Error: (mysql.connector.errors.ProgrammingError) 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'This question is not related to the provided database schema, as it is about the' at line 1
85
+ [SQL: This question is not related to the provided database schema, as it is about the weather in a specific location (Chennai) and cannot be answered using the data in the tables. You would need to use a weather API or service to get the current weather information for Chennai.]
86
+ (Background on this error at: https://sqlalche.me/e/20/f405)
87
+ 2024-07-18 14:40:57,382 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
88
+ 2024-07-18 14:41:08,706 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
89
+ 2024-07-18 14:41:08,720 - INFO - Executing SQL query: This question is not related to the provided database schema and cannot be answered using SQL queries. You may need to use a weather API or service to get the current weather information for Chennai.
90
+ 2024-07-18 14:41:09,363 - ERROR - Error executing query: This question is not related to the provided database schema and cannot be answered using SQL queries. You may need to use a weather API or service to get the current weather information for Chennai., Error: (mysql.connector.errors.ProgrammingError) 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'This question is not related to the provided database schema and cannot be answe' at line 1
91
+ [SQL: This question is not related to the provided database schema and cannot be answered using SQL queries. You may need to use a weather API or service to get the current weather information for Chennai.]
92
+ (Background on this error at: https://sqlalche.me/e/20/f405)
93
+ 2024-07-18 14:41:10,032 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
94
+ 2024-07-18 14:41:21,325 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
95
+ 2024-07-18 14:41:21,335 - INFO - Executing SQL query: This question is not related to the provided database schema and cannot be answered using SQL queries. You may need to use a weather API or service to get the current weather information for Chennai.
96
+ 2024-07-18 14:41:43,996 - INFO - File upload start
97
+ 2024-07-18 14:42:14,242 - INFO - Received question: what is the college name
98
+ 2024-07-18 14:42:15,023 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
99
+ 2024-07-18 14:42:27,078 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
100
+ 2024-07-18 14:42:27,094 - INFO - Executing SQL query: SELECT CollegeName
101
+ FROM buildings;
102
+ 2024-07-18 14:42:27,843 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
103
+ 2024-07-18 14:42:28,479 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
104
+ 2024-07-18 14:42:29,471 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
105
+ 2024-07-18 14:42:29,476 - INFO - Response generated: The college name is SCCC.
106
+ 2024-07-18 14:44:53,957 - INFO - File upload start
107
+ 2024-07-18 14:54:50,464 - INFO - File upload start
108
+ 2024-07-18 14:55:14,833 - INFO - File upload start
109
+ 2024-07-18 14:55:40,011 - INFO - Received question: what is the college name
110
+ 2024-07-18 14:55:40,909 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
111
+ 2024-07-18 14:55:51,399 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
112
+ 2024-07-18 14:55:51,415 - INFO - Executing SQL query: SELECT CollegeName
113
+ FROM buildings;
114
+ 2024-07-18 14:55:52,048 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
115
+ 2024-07-18 14:55:52,599 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
116
+ 2024-07-18 14:55:53,523 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
117
+ 2024-07-18 14:55:53,526 - INFO - Response generated: The college name is SCCC (retrieved from the database).
118
+ 2024-07-18 14:59:35,543 - INFO - Received question: what is the college name
119
+ 2024-07-18 14:59:36,526 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
120
+ 2024-07-18 14:59:48,046 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
121
+ 2024-07-18 14:59:48,046 - INFO - Executing SQL query: SELECT CollegeName
122
+ FROM buildings;
123
+ 2024-07-18 14:59:48,723 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
124
+ 2024-07-18 14:59:49,583 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
125
+ 2024-07-18 14:59:50,459 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
126
+ 2024-07-18 14:59:50,461 - INFO - Response generated: The college name is "SCCC".
127
+ 2024-07-19 10:58:51,724 - INFO - File upload start
128
+ 2024-07-19 11:25:35,546 - WARNING - Did not find CR at end of boundary (40)
129
+ 2024-07-19 11:26:36,567 - WARNING - Did not find CR at end of boundary (40)
130
+ 2024-07-19 11:29:24,545 - INFO - File upload start
131
+ 2024-07-19 11:29:46,970 - INFO - Received question: what is the college name
132
+ 2024-07-19 11:29:47,868 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
133
+ 2024-07-19 11:29:59,588 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
134
+ 2024-07-19 11:29:59,602 - INFO - Executing SQL query: SELECTSELECT CollegeName
135
+ FROM buildings;
136
+ 2024-07-19 11:30:00,235 - ERROR - Error executing query: SELECTSELECT CollegeName
137
+ FROM buildings;, Error: (mysql.connector.errors.ProgrammingError) 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECTSELECT CollegeName
138
+ FROM buildings' at line 1
139
+ [SQL: SELECTSELECT CollegeName
140
+ FROM buildings;]
141
+ (Background on this error at: https://sqlalche.me/e/20/f405)
142
+ 2024-07-19 11:30:00,856 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
143
+ 2024-07-19 11:30:11,376 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
144
+ 2024-07-19 11:30:11,378 - INFO - Executing SQL query: SELECT CollegeName
145
+ FROM buildings;
146
+ 2024-07-19 11:30:12,379 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
147
+ 2024-07-19 11:30:13,039 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
148
+ 2024-07-19 11:30:14,129 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
149
+ 2024-07-19 11:30:14,130 - INFO - Response generated: The college name is SCCC (appears multiple times in the data).
150
+ 2024-07-19 11:31:25,438 - INFO - Received question: what is the college name
151
+ 2024-07-19 11:31:26,456 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
152
+ 2024-07-19 11:31:36,647 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
153
+ 2024-07-19 11:31:36,649 - INFO - Executing SQL query: SELECT CollegeName
154
+ FROM buildings;
155
+ 2024-07-19 11:31:37,289 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
156
+ 2024-07-19 11:31:38,107 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
157
+ 2024-07-19 11:31:39,172 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
158
+ 2024-07-19 11:31:39,173 - INFO - Response generated: The college name is SCCC (repeated multiple times in the data).
159
+ 2024-07-19 11:32:01,191 - INFO - Received question: what is the college name
160
+ 2024-07-19 11:32:01,981 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
161
+ 2024-07-19 11:32:13,386 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
162
+ 2024-07-19 11:32:13,388 - INFO - Executing SQL query: SELECT CollegeName
163
+ FROM buildings;
164
+ 2024-07-19 11:32:14,108 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
165
+ 2024-07-19 11:32:14,872 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
166
+ 2024-07-19 11:32:15,784 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
167
+ 2024-07-19 11:32:15,786 - INFO - Response generated: The college name is SCCC.
168
+ 2024-07-19 12:32:42,687 - INFO - File upload start
169
+ 2024-07-19 12:33:09,641 - INFO - File upload start
170
+ 2024-07-19 12:33:47,562 - INFO - File upload start
171
+ 2024-07-19 12:34:08,515 - INFO - Received question: what are the faculty names
172
+ 2024-07-19 12:34:09,305 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
173
+ 2024-07-19 12:34:21,872 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
174
+ 2024-07-19 12:34:21,884 - INFO - Executing SQL query: SELECT FacultyName AS name FROM faculty;
175
+ 2024-07-19 12:34:22,691 - INFO - Query successful: [('Tanya Ferguson',), ("Guy O'Neill",), ('Dennis Wilks',), ('Kenneth Mason',), ('Mike Briley',), ('Mary George',), ('June Walkters',), ('Angela Mendez',), ('John Leak',), ('Carey Cochran',)]
176
+ 2024-07-19 12:34:23,315 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
177
+ 2024-07-19 12:34:25,037 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
178
+ 2024-07-19 12:34:25,037 - INFO - Response generated: The faculty names are as follows:
179
+ 1. Tanya Ferguson
180
+ 2. Guy O'Neill
181
+ 3. Dennis Wilks
182
+ 4. Kenneth Mason
183
+ 5. Mike Briley
184
+ 6. Mary George
185
+ 7. June Walkters
186
+ 8. Angela Mendez
187
+ 9. John Leak
188
+ 10. Carey Cochran
189
+ 2024-07-19 12:35:10,296 - INFO - Received question: what is the college name
190
+ 2024-07-19 12:35:11,275 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
191
+ 2024-07-19 12:35:23,826 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
192
+ 2024-07-19 12:35:23,826 - INFO - Executing SQL query: SELECT CollegeName
193
+ FROM buildings;
194
+ 2024-07-19 12:35:24,533 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
195
+ 2024-07-19 12:35:25,144 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
196
+ 2024-07-19 12:35:26,577 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
197
+ 2024-07-19 12:35:26,577 - INFO - Response generated: The college name is SCCC (repeated multiple times in the database).
198
+ 2024-07-19 13:17:17,036 - INFO - File upload start
199
+ 2024-07-19 13:19:33,261 - INFO - File upload start
200
+ 2024-07-19 13:21:21,623 - INFO - Received question: what is the college name
201
+ 2024-07-19 13:21:22,303 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
202
+ 2024-07-19 13:21:33,883 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
203
+ 2024-07-19 13:21:33,890 - INFO - Executing SQL query: SELECT CollegeName
204
+ FROM buildings;
205
+ 2024-07-19 13:21:34,550 - INFO - Query successful: [('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',), ('SCCC',)]
206
+ 2024-07-19 13:21:35,158 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
207
+ 2024-07-19 13:21:35,946 - INFO - HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
208
+ 2024-07-19 13:21:35,949 - INFO - Response generated: The college name is SCCC.
209
+ 2024-07-19 14:53:48,407 - INFO - File upload start
210
+ 2024-07-22 10:12:26,425 - INFO - File upload start
211
+ 2024-07-22 10:12:43,516 - INFO - File upload start
212
+ 2024-07-22 10:29:30,854 - INFO - File upload start
213
+ 2024-07-22 10:34:39,763 - INFO - File upload start
214
+ 2024-07-22 10:45:52,996 - INFO - File upload start
215
+ 2024-07-22 10:54:35,696 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
216
+ 2024-07-22 11:03:11,588 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
217
+ 2024-07-22 11:32:50,544 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
218
+ 2024-07-22 11:34:11,514 - INFO - File upload start
219
+ 2024-07-22 11:35:17,929 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
220
+ 2024-07-22 11:35:51,872 - INFO - File upload start
221
+ 2024-07-22 11:35:55,811 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
222
+ 2024-07-22 11:47:11,227 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
223
+ 2024-07-22 11:57:15,569 - INFO - File upload start
224
+ 2024-07-22 12:08:32,603 - INFO - File upload start
225
+ 2024-07-22 12:09:31,581 - INFO - File upload start
226
+ 2024-07-22 12:10:00,231 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
227
+ 2024-07-22 12:11:49,767 - INFO - File upload start
228
+ 2024-07-22 12:12:11,229 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
229
+ 2024-07-22 12:12:33,191 - INFO - File upload start
230
+ 2024-07-22 12:12:42,069 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
231
+ 2024-07-22 12:14:01,202 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
232
+ 2024-07-22 12:30:49,041 - INFO - File upload start
233
+ 2024-07-22 12:31:09,887 - INFO - File upload start
234
+ 2024-07-22 12:32:09,656 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
235
+ 2024-07-22 12:32:39,727 - INFO - File upload start
236
+ 2024-07-22 12:33:21,572 - ERROR - Error handling file uploads: expected str, bytes or os.PathLike object, not NoneType
requirements.txt ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiohttp==3.9.5
2
+ aiosignal==1.3.1
3
+ annotated-types==0.7.0
4
+ anyio==4.4.0
5
+ attrs==23.2.0
6
+ certifi==2024.6.2
7
+ charset-normalizer==3.3.2
8
+ click==8.1.7
9
+ colorama==0.4.6
10
+ dataclasses-json==0.6.7
11
+ distro==1.9.0
12
+ dnspython==2.6.1
13
+ email_validator==2.1.1
14
+ faiss-cpu==1.8.0
15
+ fastapi==0.111.0
16
+ fastapi-cli==0.0.4
17
+ frozenlist==1.4.1
18
+ greenlet==3.0.3
19
+ h11==0.14.0
20
+ httpcore==1.0.5
21
+ httptools==0.6.1
22
+ httpx==0.27.0
23
+ idna==3.7
24
+ itsdangerous==2.2.0
25
+ Jinja2==3.1.4
26
+ jsonpatch==1.33
27
+ jsonpointer==3.0.0
28
+ langchain==0.2.5
29
+ langchain-community==0.2.5
30
+ langchain-core==0.2.7
31
+ langchain-openai==0.1.8
32
+ langchain-text-splitters==0.2.1
33
+ langsmith==0.1.77
34
+ lxml==5.2.2
35
+ markdown-it-py==3.0.0
36
+ MarkupSafe==2.1.5
37
+ marshmallow==3.21.3
38
+ mdurl==0.1.2
39
+ multidict==6.0.5
40
+ mypy-extensions==1.0.0
41
+ mysql-connector-python==8.4.0
42
+ numpy==1.26.4
43
+ openai==1.34.0
44
+ openpyxl==3.1.4
45
+ orjson==3.10.5
46
+ packaging==24.1
47
+ pydantic==2.7.4
48
+ pydantic-extra-types==2.8.2
49
+ pydantic-settings==2.3.3
50
+ pydantic_core==2.18.4
51
+ Pygments==2.18.0
52
+ PyPDF2==3.0.1
53
+ python-docx==1.1.2
54
+ python-dotenv==1.0.1
55
+ python-multipart==0.0.9
56
+ PyYAML==6.0.1
57
+ pandas==2.2.2
58
+ regex==2024.5.15
59
+ requests==2.32.3
60
+ rich==13.7.1
61
+ shellingham==1.5.4
62
+ sniffio==1.3.1
63
+ SQLAlchemy==2.0.30
64
+ starlette==0.37.2
65
+ tenacity==8.3.0
66
+ tiktoken==0.7.0
67
+ tqdm==4.66.4
68
+ typer==0.12.3
69
+ typing-inspect==0.9.0
70
+ typing_extensions==4.12.2
71
+ ujson==5.10.0
72
+ urllib3==2.2.1
73
+ uvicorn==0.30.1
74
+ watchfiles==0.22.0
75
+ websockets==12.0
76
+ yarl==1.9.4
77
+ asyncpg
78
+ psycopg2
services/__pycache__/chat_service.cpython-310.pyc ADDED
Binary file (6.05 kB). View file
 
services/__pycache__/chat_service.cpython-311.pyc ADDED
Binary file (9.56 kB). View file
 
services/__pycache__/chat_service.cpython-312.pyc ADDED
Binary file (8.75 kB). View file
 
services/__pycache__/file_upload_service.cpython-310.pyc ADDED
Binary file (5.25 kB). View file
 
services/__pycache__/file_upload_service.cpython-312.pyc ADDED
Binary file (8.64 kB). View file
 
services/__pycache__/multidoc_files_upload.cpython-310.pyc ADDED
Binary file (4.42 kB). View file
 
services/__pycache__/multidoc_files_upload.cpython-311.pyc ADDED
Binary file (8.14 kB). View file
 
services/chat_service.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ from dotenv import load_dotenv
4
+ from langchain.memory import ConversationSummaryMemory
5
+ from langchain_core.prompts import ChatPromptTemplate
6
+ from langchain_community.utilities import SQLDatabase
7
+ from langchain_core.output_parsers import StrOutputParser
8
+ from langchain_core.runnables import RunnablePassthrough
9
+ from langchain_openai import ChatOpenAI
10
+ from langchain_openai import OpenAIEmbeddings
11
+ from langchain.agents import create_tool_calling_agent, AgentExecutor, Tool
12
+ from langchain_community.vectorstores import FAISS
13
+ from config.settings import Settings
14
+
15
+ # Load environment variables
16
+ load_dotenv()
17
+ open_api_key_token = os.getenv('OPENAI_API_KEY')
18
+ #db_uri = os.getenv('POST_DB_URI')
19
+ db_uri = Settings.DB_URI
20
+
21
+ class ChatAgentService:
22
+ def __init__(self):
23
+ # Database setup
24
+ self.db = SQLDatabase.from_uri(db_uri)
25
+ self.llm = ChatOpenAI(model="gpt-3.5-turbo-0125", api_key=open_api_key_token,max_tokens=150,temperature=0.2)
26
+ self.memory = ConversationSummaryMemory(llm=self.llm, return_messages=True)
27
+
28
+
29
+ # Tools setup
30
+ self.tools = [
31
+ Tool(
32
+ name="DatabaseQuery",
33
+ func=self.database_tool,
34
+ description="Queries the SQL database using dynamically generated SQL queries based on user questions. Aimed to retrieve structured data like counts, specific records, or summaries from predefined schemas.",
35
+ tool_choice="required"
36
+ ),
37
+ Tool(
38
+ name="DocumentData",
39
+ func=self.document_data_tool,
40
+ description="Searches through indexed documents to find relevant information based on user queries. Handles unstructured data from various document formats like PDF, DOCX, or TXT files.",
41
+ tool_choice="required"
42
+ ),
43
+ ]
44
+
45
+ # Agent setup
46
+ prompt_template = self.setup_prompt()
47
+ self.agent = create_tool_calling_agent(self.llm.bind(memory=self.memory), self.tools, prompt_template)
48
+ self.agent_executor = AgentExecutor(agent=self.agent, tools=self.tools, memory=self.memory, verbose=True)
49
+
50
+ def setup_prompt(self):
51
+ prompt_template = f"""
52
+ You are an assistant that helps with database queries and document retrieval.
53
+ Please base your responses strictly on available data and avoid assumptions.
54
+ If the question pertains to numerical data or structured queries, use the DatabaseQuery tool.
55
+ If the question relates to content within various documents, use the DocumentData tool.
56
+ Question: {{input}}
57
+ {{agent_scratchpad}}
58
+ """
59
+ return ChatPromptTemplate.from_template(prompt_template)
60
+
61
+ def database_tool(self, question):
62
+ sql_query = self.generate_sql_query(question)
63
+ return self.run_query(sql_query)
64
+
65
+ def get_schema(self,_):
66
+ # print(self.db.get_table_info())
67
+ return self.db.get_table_info()
68
+ def generate_sql_query(self, question):
69
+ schema = self.get_schema(None) # Get the schema using the function
70
+ template_query_generation = """Generate a SQL query to answer the user's question based on the available database schema.
71
+ {schema}
72
+ Question: {question}
73
+ SQL Query:"""
74
+
75
+ prompt_query_generation = ChatPromptTemplate.from_template(template_query_generation)
76
+ # Correctly setting up the initial data dictionary for the chain
77
+ input_data = {'question': question}
78
+ # Setup the chain correctly
79
+ sql_chain = (RunnablePassthrough.assign(schema=self.get_schema)
80
+ | prompt_query_generation
81
+ | self.llm.bind(stop="\nSQL Result:")
82
+ | StrOutputParser())
83
+
84
+ # Make sure to invoke with an empty dictionary if all needed data is already assigned
85
+ return sql_chain.invoke(input_data)
86
+
87
+ def run_query(self, query):
88
+ try:
89
+ logging.info(f"Executing SQL query: {query}")
90
+ result = self.db.run(query)
91
+ logging.info(f"Query successful: {result}")
92
+ return result
93
+ except Exception as e:
94
+ logging.error(f"Error executing query: {query}, Error: {str(e)}")
95
+ return None
96
+
97
+ def document_data_tool(self, query):
98
+ try:
99
+ logging.info(f"Searching documents for query: {query}")
100
+ embeddings = OpenAIEmbeddings(api_key=open_api_key_token)
101
+ index_paths = self.find_index_for_document(query)
102
+ responses = []
103
+ for index_path in index_paths:
104
+ vector_store = FAISS.load_local(index_path, embeddings, allow_dangerous_deserialization=True)
105
+ response = self.query_vector_store(vector_store, query)
106
+ responses.append(response)
107
+ logging.info(f"Document search results: {responses}")
108
+ return "\n".join(responses)
109
+ except Exception as e:
110
+ logging.error(f"Error in document data tool for query: {query}, Error: {str(e)}")
111
+ return "Error processing document query."
112
+
113
+ def find_index_for_document(self, query):
114
+ base_path = os.getenv('VECTOR_DB_PATH')
115
+ # document_hint = self.extract_document_hint(query)
116
+ index_paths = []
117
+ for root, dirs, files in os.walk(base_path):
118
+ for dir in dirs:
119
+ if 'index.faiss' in os.listdir(os.path.join(root, dir)):
120
+ index_paths.append(os.path.join(root, dir, ''))
121
+ return index_paths
122
+
123
+ def query_vector_store(self, vector_store, query):
124
+ docs = vector_store.similarity_search(query)
125
+ return '\n\n'.join([doc.page_content for doc in docs])
126
+
127
+ def answer_question(self, user_question):
128
+ try:
129
+ logging.info(f"Received question: {user_question}")
130
+ response = self.agent_executor.invoke({"input": user_question})
131
+ output_response = response.get("output", "No valid response generated.")
132
+ logging.info(f"Response generated: {output_response}")
133
+ return output_response
134
+ except Exception as e:
135
+ logging.error(f"Error processing question: {user_question}, Error: {str(e)}")
136
+ return f"An error occurred: {str(e)}"
137
+
services/file_upload_service.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import os
3
+ import tempfile
4
+ import hashlib
5
+ import json
6
+ import logging
7
+ import pandas as pd
8
+ from datetime import datetime
9
+ from dotenv import load_dotenv
10
+ from langchain_community.vectorstores import FAISS
11
+ from langchain_openai import OpenAIEmbeddings
12
+ from langchain.text_splitter import CharacterTextSplitter
13
+ from PyPDF2 import PdfReader
14
+ from docx import Document
15
+ # from transformers import pipeline
16
+
17
+ # Load environment variables
18
+ load_dotenv()
19
+ open_api_key_token = os.getenv('OPENAI_API_KEY')
20
+
21
+
22
+ class FileHandler:
23
+ def __init__(self, vector_db_path):
24
+ self.vector_db_path = vector_db_path
25
+ self.embeddings = OpenAIEmbeddings(api_key=open_api_key_token)
26
+ # self.summarizer = pipeline("summarization")
27
+
28
+ def prepare_metadata_string(self, document_name, document_description, department, version, last_updated):
29
+ metadata_string = f"\nDocument Name: {document_name}\nDocument Description: {document_description}\nDepartment: {department}\nVersion: {version}\nLast Updated: {last_updated}"
30
+ return metadata_string
31
+
32
+ async def handle_file_upload(self, file, document_name, document_description, department, version, last_updated):
33
+ content = await file.read()
34
+ file_hash = hashlib.md5(content).hexdigest()
35
+ file_key = f"{file.filename}_{file_hash}"
36
+ vector_store_path = os.path.join(self.vector_db_path, f"{file_key}.vectorstore")
37
+ metadata_path = os.path.join(self.vector_db_path, f"{file_key}.metadata.json")
38
+
39
+ metadata_string = self.prepare_metadata_string(document_name, document_description, department, version,
40
+ last_updated)
41
+
42
+ if os.path.exists(vector_store_path) and os.path.exists(metadata_path):
43
+ with open(metadata_path, 'r') as md_file:
44
+ metadata = json.load(md_file)
45
+ return {'path': vector_store_path, 'metadata': metadata, 'status': 'skipped - duplicate'}
46
+
47
+ if file.filename.endswith('.csv') or file.filename.endswith('.xlsx'):
48
+ texts = self.load_and_split_table(content, file.filename,metadata_string)
49
+ else:
50
+ texts = await self.load_and_split_text(content, file.filename,metadata_string)
51
+
52
+ vector_store = self.create_vector_store(texts)
53
+ vector_store.save_local(vector_store_path)
54
+
55
+ metadata = {
56
+ 'filename': file.filename,
57
+ 'document_name': document_name,
58
+ 'document_description': document_description,
59
+ 'department': department,
60
+ 'version': version,
61
+ 'last_updated': last_updated,
62
+ 'hash': file_hash,
63
+ 'upload_date': datetime.now().isoformat(),
64
+ 'file_path': vector_store_path,
65
+ 'file_size': len(content),
66
+ 'content_type': file.content_type
67
+ }
68
+
69
+ with open(metadata_path, 'w') as md_file:
70
+ json.dump(metadata, md_file)
71
+
72
+ return {"message": "File processed and vector store created successfully", "file_metadata": metadata}
73
+
74
+ def summarize_text(self, text):
75
+ try:
76
+ summary = self.summarizer(text, max_length=150, min_length=10, do_sample=False)
77
+ logging.info("Text summarization successful")
78
+ return summary[0]['summary_text']
79
+ except Exception as e:
80
+ logging.error(f"Error in summarization: {str(e)}")
81
+ # Log error or handle exception
82
+ return text # Return original text if summarization is not possible
83
+
84
+ def load_and_split_table(self, content, filename,metadata_string):
85
+ # Handle CSV and Excel file reading
86
+ if filename.endswith('.csv'):
87
+ df = pd.read_csv(io.StringIO(content.decode('utf-8')))
88
+ else: # Excel
89
+ df = pd.read_excel(io.BytesIO(content))
90
+ text = df.to_string(index=False) # Convert DataFrame to string
91
+ text += metadata_string # Append metadata to the text
92
+ return self.split_text(text)
93
+
94
+ async def load_and_split_text(self, content, filename,metadata_string):
95
+ with tempfile.NamedTemporaryFile(delete=False, mode='w+b', suffix=f"_{filename}") as temp_file:
96
+ temp_file.write(content)
97
+ temp_file.flush()
98
+ temp_file_path = temp_file.name
99
+
100
+ # Ensure the temp file is closed before reading from it
101
+ if filename.endswith('.pdf'):
102
+ texts = await self.load_and_split_pdf(temp_file_path,metadata_string)
103
+ elif filename.endswith('.docx'):
104
+ texts = await self.load_and_split_docx(temp_file_path,metadata_string)
105
+ elif filename.endswith('.txt'):
106
+ texts = await self.load_and_split_txt(temp_file_path,metadata_string)
107
+
108
+ # Apply summarization here to each text segment
109
+ # summarized_texts = [self.summarize_text(text) for text in texts]
110
+
111
+ # os.unlink(temp_file_path) # Explicitly remove the temporary file
112
+ # return summarized_texts
113
+ os.unlink(temp_file_path) # Explicitly remove the temporary file
114
+ return texts
115
+
116
+ async def load_and_split_pdf(self, pdf_path,metadata_string):
117
+ reader = PdfReader(pdf_path)
118
+ text = ''
119
+ for page in reader.pages:
120
+ text += page.extract_text() or ""
121
+ text += metadata_string # Append metadata to the text
122
+ return self.split_text(text)
123
+
124
+ async def load_and_split_docx(self, docx_path,metadata_string):
125
+ doc = Document(docx_path)
126
+ text = '\n'.join([paragraph.text for paragraph in doc.paragraphs if paragraph.text])
127
+ text += metadata_string # Append metadata to the text
128
+ return self.split_text(text)
129
+
130
+ async def load_and_split_txt(self, txt_path,metadata_string):
131
+ with open(txt_path, 'r', encoding='utf-8') as file:
132
+ text = file.read()
133
+ text += metadata_string # Append metadata to the text
134
+ return self.split_text(text)
135
+
136
+ def split_text(self, text):
137
+ text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
138
+ return text_splitter.split_text(text)
139
+
140
+ def create_vector_store(self, texts):
141
+ return FAISS.from_texts(texts, self.embeddings)
static/css/dashboard.css ADDED
@@ -0,0 +1,931 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*$primary : #7356f1 !default;*/
2
+ :root {
3
+ --primary: #40189D;
4
+ --secondary: #8BC740;
5
+ --primary-hover: #2e1171;
6
+ --primary-dark: #0a0418;
7
+ --rgba-primary-1: rgba(64, 24, 157, 0.1);
8
+ --rgba-primary-2: rgba(64, 24, 157, 0.2);
9
+ --rgba-primary-3: rgba(64, 24, 157, 0.3);
10
+ --rgba-primary-4: rgba(64, 24, 157, 0.4);
11
+ --rgba-primary-5: rgba(64, 24, 157, 0.5);
12
+ --rgba-primary-6: rgba(64, 24, 157, 0.6);
13
+ --rgba-primary-7: rgba(64, 24, 157, 0.7);
14
+ --rgba-primary-8: rgba(64, 24, 157, 0.8);
15
+ --rgba-primary-9: rgba(64, 24, 157, 0.9);
16
+ --font-family-base: Roboto, sans-serif;
17
+ --font-family-title: Roboto, sans-serif; }
18
+
19
+ /*
20
+ 0 - 600: Phone
21
+ 600 - 900: Tablet portrait
22
+ 900 - 1200: Tablet landscape
23
+ 1200 - 1800: Normal styles
24
+ 1800+ : Big Desktop
25
+ 1em = 16px
26
+ The smaller device rules always should write below the bigger device rules
27
+ Fixing Order => Base + Typography >> General Layout + Grid >> Page Layout + Component
28
+ */
29
+ .event-chart {
30
+ margin: -10px 0px; }
31
+
32
+ .default-select.style-1 {
33
+ border: 0;
34
+ font-size: 12px;
35
+ padding: 5px; }
36
+ .default-select.style-1 option {
37
+ background: #fff;
38
+ box-shadow: 0 10px 40px 0 rgba(32, 28, 69, 0.1); }
39
+
40
+ .event-table {
41
+ border-radius: 1.25rem; }
42
+ .event-table thead th {
43
+ color: #000;
44
+ font-size: 18px;
45
+ white-space: nowrap;
46
+ font-weight: 600;
47
+ padding: 20px 10px; }
48
+ .event-table tbody td {
49
+ font-size: 14px;
50
+ padding: 20px 10px; }
51
+ @media only screen and (max-width: 1400px) {
52
+ .event-table thead th {
53
+ color: #000;
54
+ font-size: 15px;
55
+ white-space: nowrap;
56
+ font-weight: 600; }
57
+ .event-table tbody td {
58
+ padding: 12px 15px; } }
59
+
60
+ .dropdown-no-icon .dropdown-toggle:after {
61
+ content: none; }
62
+
63
+ .detault-daterange .dashboard-select.mat-form-field-appearance-fill .mat-form-field-flex {
64
+ padding: 0em 1em 0 1em; }
65
+ .detault-daterange .mat-form-field-prefix, .detault-daterange .mat-form-field-suffix {
66
+ top: 5px; }
67
+
68
+ .dashboard-select {
69
+ font-size: 16px; }
70
+ .dashboard-select .mat-form-field-wrapper,
71
+ .dashboard-select .mat-form-field-appearance-fill .mat-form-field-flex {
72
+ padding: 0;
73
+ background: transparent; }
74
+ .dashboard-select .mat-form-field-underline {
75
+ display: none; }
76
+ .dashboard-select .mat-form-field-infix {
77
+ border: 0; }
78
+ .dashboard-select.mat-form-field-appearance-fill .mat-select-arrow-wrapper {
79
+ transform: translateY(-10%); }
80
+ .dashboard-select.mat-form-field-appearance-fill .mat-form-field-flex {
81
+ padding: 1em 1em 0 1em;
82
+ background-color: #fff; }
83
+ .dashboard-select.mat-form-field-appearance-fill .mat-form-field-infix {
84
+ padding: .25em 0 1em 0; }
85
+ .dashboard-select .mat-select-arrow, .dashboard-select .mat-select-value {
86
+ color: #40189D; }
87
+ .dashboard-select.style-1 {
88
+ font-size: 16px;
89
+ border: 1px solid #f0f1f5;
90
+ border-radius: 3rem; }
91
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-infix {
92
+ padding: 6px 0 18px 0; }
93
+ .dashboard-select.style-1 .mat-form-field-infix {
94
+ padding: 15px 15px;
95
+ width: auto; }
96
+ .dashboard-select.style-1 .mat-select-value {
97
+ max-width: unset;
98
+ padding-right: 6px; }
99
+ .dashboard-select.style-1 .mat-select-arrow, .dashboard-select.style-1 .mat-select-value {
100
+ color: #000; }
101
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-flex {
102
+ border-radius: 3rem;
103
+ background-color: #fff;
104
+ padding: 12px 20px 0; }
105
+ @media only screen and (max-width: 1400px) {
106
+ .dashboard-select.style-1 {
107
+ font-size: 0.813rem; }
108
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-infix {
109
+ padding: 6px 0 12px 0; }
110
+ .dashboard-select.style-1 .mat-form-field-infix {
111
+ padding: 11px 15px;
112
+ width: auto; }
113
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-flex {
114
+ padding: 8px 15px 0; } }
115
+
116
+ .compose-content .dropzone {
117
+ display: flex;
118
+ align-items: center;
119
+ justify-content: center; }
120
+
121
+ .latest-salebx {
122
+ height: 630px; }
123
+ @media only screen and (max-width: 1199px) {
124
+ .latest-salebx {
125
+ height: 350px; } }
126
+
127
+ .about-company {
128
+ border-top: 1px solid #EEEEEE; }
129
+ @media only screen and (max-width: 1199px) {
130
+ .about-company {
131
+ border-top: 0;
132
+ border-left: 1px solid #EEEEEE; } }
133
+ @media only screen and (max-width: 767px) {
134
+ .about-company {
135
+ border-left: 0;
136
+ border-top: 1px solid #EEEEEE; } }
137
+
138
+ .post-input .btn-social {
139
+ margin-right: 4px; }
140
+
141
+ .rating-widget .ng-star-inserted {
142
+ color: #40189D;
143
+ font-size: 30px; }
144
+
145
+ .default-accordion {
146
+ box-shadow: none;
147
+ margin-bottom: 1.25rem;
148
+ height: unset;
149
+ border-radius: 5px; }
150
+ .default-accordion .card-header {
151
+ padding: 0;
152
+ border: 0; }
153
+ .default-accordion .card-header button {
154
+ border-radius: 5px;
155
+ background: #40189D;
156
+ color: #fff;
157
+ display: block;
158
+ border: 0;
159
+ width: 100%;
160
+ text-align: left;
161
+ padding-right: 40px; }
162
+ .default-accordion .card-header button.collapsed {
163
+ background: rgba(64, 24, 157, 0.15);
164
+ color: #000; }
165
+ .default-accordion .card-header button.collapsed:after {
166
+ content: "\e61a"; }
167
+ .default-accordion .card-header button:focus {
168
+ box-shadow: none; }
169
+ .default-accordion .card-header button:after {
170
+ position: absolute;
171
+ font-family: 'themify';
172
+ top: 50%;
173
+ content: "\e622";
174
+ transform: translateY(-50%);
175
+ right: 20px; }
176
+
177
+ .custom-header-accordion {
178
+ border: 1px solid #EEEEEE;
179
+ box-shadow: none;
180
+ margin-bottom: 0;
181
+ height: unset; }
182
+ .custom-header-accordion .card-header button:focus {
183
+ box-shadow: none; }
184
+
185
+ .prevent-accordion {
186
+ box-shadow: none;
187
+ margin-bottom: 1.25rem;
188
+ height: unset;
189
+ border-radius: 5px; }
190
+ .prevent-accordion .card-header {
191
+ padding: 0;
192
+ border: 0; }
193
+ .prevent-accordion .card-header button {
194
+ background: #40189D;
195
+ border-radius: 5px;
196
+ color: #fff;
197
+ display: block;
198
+ border: 0;
199
+ width: 100%;
200
+ text-align: left;
201
+ padding-right: 40px; }
202
+ .prevent-accordion .card-header button.collapsed {
203
+ background: rgba(64, 24, 157, 0.15);
204
+ color: #000; }
205
+ .prevent-accordion .card-header button.collapsed:after {
206
+ content: "\e61a"; }
207
+ .prevent-accordion .card-header button:focus {
208
+ box-shadow: none; }
209
+ .prevent-accordion .card-header button:after {
210
+ position: absolute;
211
+ font-family: 'themify';
212
+ top: 50%;
213
+ content: "\e622";
214
+ transform: translateY(-50%);
215
+ right: 20px; }
216
+
217
+ .default-nestable {
218
+ /* .nestable-row{
219
+ display:flex;
220
+ }
221
+ .ngx-nestable{
222
+ width:50%;
223
+ }*/ }
224
+ .default-nestable .dd-dragel .ngx-nestable-hidden,
225
+ .default-nestable .dd-dragel button {
226
+ visibility: hidden; }
227
+ .default-nestable .dd-list .dd-item .nestable-item-container {
228
+ background: #e6defa;
229
+ color: #000;
230
+ position: relative;
231
+ display: flex;
232
+ flex-direction: row;
233
+ align-items: center;
234
+ min-height: 32px;
235
+ font-size: 16px;
236
+ font-family: Roboto,sans-serif;
237
+ cursor: pointer;
238
+ outline: 0;
239
+ border-radius: 5px;
240
+ margin-bottom: 3px;
241
+ padding: 10px 10px;
242
+ -webkit-transition: all 0.5s;
243
+ -ms-transition: all 0.5s;
244
+ transition: all 0.5s; }
245
+ .default-nestable .dd-list .dd-item .nestable-item-container:hover {
246
+ background: #40189D;
247
+ color: #fff; }
248
+ .default-nestable .dd-list .dd-item .nestable-item-container:hover button {
249
+ color: #fff; }
250
+ .default-nestable .dd-list .dd-item .nestable-item-container button {
251
+ font-family: 'Material Icons';
252
+ font-weight: normal;
253
+ font-style: normal;
254
+ outline: 0;
255
+ border: 0;
256
+ font-size: 24px;
257
+ line-height: 1;
258
+ letter-spacing: normal;
259
+ text-transform: none;
260
+ margin-right: 10px;
261
+ background: transparent;
262
+ color: #000;
263
+ display: inline-block;
264
+ white-space: nowrap;
265
+ word-wrap: normal;
266
+ direction: ltr;
267
+ -webkit-font-feature-settings: 'liga';
268
+ -webkit-font-smoothing: antialiased; }
269
+ @media only screen and (max-width: 575px) {
270
+ .default-nestable .dd-list .dd-item .nestable-item-container {
271
+ padding: 0; } }
272
+ .default-nestable .result-bx textarea {
273
+ height: 100%;
274
+ width: 100%; }
275
+ @media only screen and (max-width: 991px) {
276
+ .default-nestable .result-bx {
277
+ margin-top: 30px; }
278
+ .default-nestable .result-bx textarea {
279
+ height: 600px;
280
+ width: 100%; } }
281
+
282
+ .alert-dismissible .close {
283
+ height: 100%;
284
+ font-size: 30px; }
285
+ .alert-dismissible .close span {
286
+ font-weight: 400; }
287
+
288
+ .calendar-responsive {
289
+ overflow: auto;
290
+ display: block; }
291
+
292
+ .default-calendar ngb-datepicker {
293
+ border: 0;
294
+ background: #f3f3f3; }
295
+ .default-calendar .form-group .input-group .form-control {
296
+ color: #000; }
297
+ .default-calendar .form-group .input-group .input-group-append button {
298
+ background-image: none !important;
299
+ padding: 0px;
300
+ border-color: #40189D;
301
+ background: #40189D;
302
+ width: 45px;
303
+ text-align: center; }
304
+ .default-calendar .form-group .input-group .input-group-append button:after {
305
+ color: #fff;
306
+ content: "\f133";
307
+ font-family: 'Line Awesome Free';
308
+ padding: 0;
309
+ font-size: 26px; }
310
+ .default-calendar .form-group .input-group .input-group-append button:hover {
311
+ background: #40189D; }
312
+ .default-calendar .form-group .input-group .input-group-append button:hover:after {
313
+ color: #fff; }
314
+ .default-calendar .form-group .input-group .input-group-append button:focus {
315
+ box-shadow: none; }
316
+ .default-calendar .weekend {
317
+ background-color: #40189D; }
318
+ .default-calendar .ngb-dp-header {
319
+ background: #40189D;
320
+ padding: 8px 5px; }
321
+ .default-calendar .ngb-dp-header .ngb-dp-navigation-chevron {
322
+ border-color: #fff; }
323
+ .default-calendar .ngb-dp-header .custom-select {
324
+ color: #fff;
325
+ background: #40189D;
326
+ border-radius: 5px;
327
+ margin: 0 5px;
328
+ padding: 0 20px; }
329
+ .default-calendar .ngb-dp-weekdays {
330
+ border: 1px solid rgba(64, 24, 157, 0.25);
331
+ background: #fff; }
332
+ .default-calendar .ngb-dp-weekdays .ngb-dp-weekday {
333
+ color: #40189D;
334
+ font-weight: 600;
335
+ font-size: 15px;
336
+ font-style: unset; }
337
+ .default-calendar .ngb-dp-day, .default-calendar .ngb-dp-week-number, .default-calendar .ngb-dp-weekday {
338
+ max-height: 40px;
339
+ max-width: 40px;
340
+ height: 40px;
341
+ width: 35px;
342
+ line-height: 40px; }
343
+ .default-calendar [ngbDatepickerDayView] {
344
+ max-height: 40px;
345
+ max-width: 40px;
346
+ width: 35px;
347
+ height: 40px;
348
+ line-height: 40px; }
349
+ .default-calendar [ngbDatepickerDayView]:active {
350
+ background-color: #40189D !important;
351
+ color: white !important; }
352
+ .default-calendar .ngb-dp-navigation-select {
353
+ flex: unset; }
354
+ .default-calendar .custom-day {
355
+ height: 40px !important;
356
+ line-height: 40px;
357
+ padding: 0px !important;
358
+ width: 100% !important; }
359
+ .default-calendar .custom-day.range, .default-calendar .custom-day:hover {
360
+ height: 40px;
361
+ background-color: #40189D !important; }
362
+ .default-calendar .ngb-dp-month-name {
363
+ padding: 8px 0px;
364
+ height: auto; }
365
+
366
+ .dashboard-full-calendar.fc .fc-button-primary {
367
+ background-color: #40189D;
368
+ color: #fff;
369
+ border: 0; }
370
+ .dashboard-full-calendar.fc .fc-button-primary:hover, .dashboard-full-calendar.fc .fc-button-primary.fc-button-active, .dashboard-full-calendar.fc .fc-button-primary:active {
371
+ background-color: #1c0a45 !important; }
372
+ .dashboard-full-calendar.fc .fc-button-primary:focus {
373
+ box-shadow: none !important; }
374
+ .dashboard-full-calendar.fc-theme-standard td, .dashboard-full-calendar.fc-theme-standard th, .dashboard-full-calendar.fc-theme-standard .fc-scrollgrid, .dashboard-full-calendar.fc-theme-standard .fc-list {
375
+ border-color: #ECF0F3; }
376
+ .dashboard-full-calendar .fc-daygrid-day.fc-day-today {
377
+ background-color: #e6defa !important; }
378
+ .dashboard-full-calendar .fc-daygrid-dot-event {
379
+ background: #fff;
380
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.1); }
381
+ .dashboard-full-calendar.fc-theme-standard th {
382
+ padding: 0.75rem 0.5rem;
383
+ font-size: 1rem;
384
+ font-weight: 500; }
385
+ .dashboard-full-calendar.fc-theme-standard th a {
386
+ color: #B5B5C3; }
387
+ .dashboard-full-calendar .fc-h-event, .dashboard-full-calendar .fc-v-event {
388
+ background-color: #40189D;
389
+ border-color: #40189D; }
390
+ .dashboard-full-calendar .fc-daygrid-event-dot, .dashboard-full-calendar .fc-list-event-dot {
391
+ border-color: #40189D !important; }
392
+ @media only screen and (max-width: 767px) {
393
+ .dashboard-full-calendar.fc .fc-toolbar {
394
+ display: block;
395
+ text-align: center; }
396
+ .dashboard-full-calendar.fc .fc-toolbar .fc-toolbar-title {
397
+ margin: 10px; } }
398
+
399
+ .calendar-list {
400
+ margin-bottom: 10px; }
401
+ .calendar-list .list-group-item {
402
+ background: #f4f6fa;
403
+ color: #40189D;
404
+ border: 0;
405
+ margin-bottom: 5px;
406
+ border-radius: 6px;
407
+ position: relative;
408
+ border-left: 4px solid #40189D; }
409
+
410
+ .calendar-checkbox {
411
+ border-radius: 6px;
412
+ background: #e6defa;
413
+ padding: 10px 15px;
414
+ margin-bottom: 5px;
415
+ color: #000; }
416
+ .calendar-checkbox label {
417
+ margin-bottom: 0; }
418
+ .calendar-checkbox input[type=checkbox], .calendar-checkbox input[type=radio] {
419
+ margin-right: 6px; }
420
+
421
+ .calendar-description h2 {
422
+ margin-top: 30px;
423
+ font-size: 25px;
424
+ font-weight: 600;
425
+ color: #000; }
426
+ .calendar-description ul li {
427
+ font-size: 15px;
428
+ color: #000; }
429
+
430
+ .default-carousel .carousel-caption {
431
+ background: rgba(0, 0, 0, 0.5);
432
+ bottom: 45px;
433
+ padding: 15px 15px; }
434
+ .default-carousel .carousel-caption h3 {
435
+ color: #fff; }
436
+ @media only screen and (max-width: 575px) {
437
+ .default-carousel .carousel-caption {
438
+ width: 90%;
439
+ left: 50%;
440
+ transform: translatex(-50%); } }
441
+ .default-carousel .carousel-indicators li {
442
+ -webkit-transition: all 0.5s;
443
+ -ms-transition: all 0.5s;
444
+ transition: all 0.5s;
445
+ height: 13px;
446
+ width: 13px;
447
+ border: 0;
448
+ border-radius: 13px;
449
+ background: #40189D; }
450
+ .default-carousel .carousel-indicators li.active {
451
+ width: 30px; }
452
+ @media only screen and (max-width: 575px) {
453
+ .default-carousel .carousel-item img {
454
+ height: 280px; } }
455
+
456
+ .default-rating span {
457
+ font-size: 35px; }
458
+
459
+ .pagination-responsive {
460
+ overflow: auto; }
461
+
462
+ .pagination .page-item .page-link span {
463
+ color: #B1B1B1; }
464
+
465
+ .pagination .page-item .page-link:hover span {
466
+ color: #fff; }
467
+
468
+ .progress {
469
+ height: 16px; }
470
+
471
+ .form-select.mat-form-field {
472
+ display: block; }
473
+ .form-select .mat-form-field-infix {
474
+ border-top: 0; }
475
+ .form-select .mat-form-field-underline {
476
+ display: none; }
477
+ .form-select.mat-form-field-appearance-fill .mat-form-field-flex {
478
+ border-radius: 1.25rem;
479
+ padding: 15px 15px 8px;
480
+ background: transparent;
481
+ border: 1px solid #EEEEEE; }
482
+ .form-select.mat-form-field-appearance-fill .mat-select-arrow-wrapper {
483
+ transform: translateY(0%); }
484
+
485
+ /** Material Scsss start**/
486
+ /* auto compelete */
487
+ .default-autocomplete {
488
+ /* .mat-autocomplete-trigger{
489
+ margin: 1px;
490
+ border:1px solid $border-color;
491
+ border-radius:5px;
492
+ width:100%;
493
+ padding: 15px 20px;
494
+ } */
495
+ /* .mat-form-field-appearance-legacy .mat-form-field-infix{
496
+ padding:0;
497
+ .mat-input-element{
498
+ margin: 1px;
499
+ border:1px solid $border-color;
500
+ border-radius:5px;
501
+ padding: 15px 20px;
502
+ }
503
+ } */
504
+ /* .mat-form-field-appearance-legacy .mat-form-field-label{
505
+ color:rgba($black,0.5);
506
+ left: 15px;
507
+ top: 30px;
508
+ } */ }
509
+ .default-autocomplete .mat-form-field {
510
+ width: 100%; }
511
+ .default-autocomplete .mat-form-field-appearance-legacy.mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill + .mat-form-field-label-wrapper .mat-form-field-label,
512
+ .default-autocomplete .mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label, .default-autocomplete .mat-form-field-appearance-legacy.mat-form-field-can-float .mat-input-server:focus + .mat-form-field-label-wrapper .mat-form-field-label {
513
+ /* transform: translateY(-2rem) scale(0.85) perspective(100px) translateZ(0.001px);
514
+ -ms-transform: translateY(-2rem) scale(0.85); */
515
+ color: #40189D; }
516
+ .default-autocomplete .mat-form-field.mat-focused .mat-form-field-ripple {
517
+ background-color: #40189D; }
518
+
519
+ /* badge */
520
+ .mat-flat-button.mat-primary,
521
+ .mat-raised-button.mat-primary,
522
+ .mat-fab.mat-primary,
523
+ .mat-mini-fab.mat-primary,
524
+ .mat-badge-content {
525
+ background-color: #40189D; }
526
+
527
+ .mat-badge-accent .mat-badge-content {
528
+ background: #8BC740;
529
+ color: #fff; }
530
+
531
+ /* Bottom Sheet */
532
+ .mat-bottom-sheet-container {
533
+ max-height: 80vh;
534
+ overflow: auto; }
535
+ .mat-bottom-sheet-container ul li a {
536
+ padding: 15px 15px;
537
+ display: block; }
538
+ .mat-bottom-sheet-container ul li a:hover, .mat-bottom-sheet-container ul li a:focus {
539
+ background: rgba(0, 0, 0, 0.04); }
540
+ .mat-bottom-sheet-container ul li a span {
541
+ color: #000;
542
+ display: block;
543
+ font-size: 16px; }
544
+ .mat-bottom-sheet-container ul li a span:last-child {
545
+ font-size: 14px; }
546
+
547
+ /* button */
548
+ .default-mt-btn .mat-button.mat-primary,
549
+ .default-mt-btn .mat-icon-button.mat-primary,
550
+ .default-mt-btn .mat-stroked-button.mat-primary {
551
+ color: #40189D; }
552
+ .default-mt-btn .example-label {
553
+ font-size: 1rem !important;
554
+ color: #000; }
555
+ .default-mt-btn .example-button-row {
556
+ width: auto !important; }
557
+ .default-mt-btn .example-button-row .mat-button-base {
558
+ margin: 15px 15px 15px 0 !important; }
559
+ .default-mt-btn .mat-flat-button.mat-accent,
560
+ .default-mt-btn .mat-raised-button.mat-accent,
561
+ .default-mt-btn .mat-fab.mat-accent,
562
+ .default-mt-btn .mat-mini-fab.mat-accent {
563
+ background-color: #8BC740; }
564
+ .default-mt-btn .mat-flat-button.mat-accent,
565
+ .default-mt-btn .mat-raised-button.mat-accent,
566
+ .default-mt-btn .mat-fab.mat-accent,
567
+ .default-mt-btn .mat-mini-fab.mat-accent {
568
+ color: #fff; }
569
+ .default-mt-btn .mat-button.mat-accent,
570
+ .default-mt-btn .mat-icon-button.mat-accent,
571
+ .default-mt-btn .mat-stroked-button.mat-accent {
572
+ color: #8BC740; }
573
+ .default-mt-btn .mat-button.mat-accent .mat-button-focus-overlay,
574
+ .default-mt-btn .mat-icon-button.mat-accent .mat-button-focus-overlay,
575
+ .default-mt-btn .mat-stroked-button.mat-accent .mat-button-focus-overlay {
576
+ background-color: #8BC740; }
577
+ .default-mt-btn .mat-button,
578
+ .default-mt-btn .mat-raised-button,
579
+ .default-mt-btn .mat-stroked-button,
580
+ .default-mt-btn .mat-flat-button {
581
+ padding: 0 25px;
582
+ line-height: 55px;
583
+ border-radius: 1.25rem;
584
+ font-size: 1rem; }
585
+ @media only screen and (max-width: 1400px) {
586
+ .default-mt-btn .example-button-row {
587
+ width: auto !important; }
588
+ .default-mt-btn .example-button-row .mat-button-base {
589
+ margin: 10px 10px 10px 0 !important; }
590
+ .default-mt-btn .mat-button,
591
+ .default-mt-btn .mat-raised-button,
592
+ .default-mt-btn .mat-stroked-button,
593
+ .default-mt-btn .mat-flat-button {
594
+ padding: 0 15px;
595
+ line-height: 40px;
596
+ font-size: 14px; } }
597
+ @media only screen and (max-width: 575px) {
598
+ .default-mt-btn .btn-list-group {
599
+ display: block !important;
600
+ padding: 10px 0px; }
601
+ .default-mt-btn .btn-list-group .example-label {
602
+ display: block !important; }
603
+ .default-mt-btn .example-button-row {
604
+ width: auto !important; }
605
+ .default-mt-btn .example-button-row .mat-button-base {
606
+ margin: 5px 10px 5px 0 !important; }
607
+ .default-mt-btn .example-button-container {
608
+ width: 80px !important; } }
609
+
610
+ /* card */
611
+ .default-mt-card .mat-card {
612
+ border-radius: 1.25rem; }
613
+
614
+ /* checkbox */
615
+ .default-mt-checkbox .example-section {
616
+ margin: 0 !important; }
617
+
618
+ .mat-checkbox-checked:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element,
619
+ .mat-checkbox:active:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element {
620
+ background: #40189D; }
621
+
622
+ .mat-checkbox-indeterminate.mat-primary .mat-checkbox-background,
623
+ .mat-checkbox-checked.mat-primary .mat-checkbox-background {
624
+ background-color: #40189D; }
625
+
626
+ .mat-primary .mat-pseudo-checkbox-checked, .mat-primary .mat-pseudo-checkbox-indeterminate {
627
+ background: #40189D; }
628
+
629
+ .mat-primary .mat-option.mat-selected:not(.mat-option-disabled) {
630
+ color: #40189D; }
631
+
632
+ .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,
633
+ .mat-checkbox-checked.mat-accent .mat-checkbox-background {
634
+ background-color: #8BC740; }
635
+
636
+ .mat-checkbox-checked:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element,
637
+ .mat-checkbox:active:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element {
638
+ background: #8BC740; }
639
+
640
+ .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle {
641
+ border-color: #8BC740; }
642
+
643
+ .mat-radio-button.mat-accent .mat-radio-inner-circle,
644
+ .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),
645
+ .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,
646
+ .mat-radio-button.mat-accent:active .mat-radio-persistent-ripple,
647
+ .mat-radio-button.mat-accent .mat-radio-inner-circle,
648
+ .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),
649
+ .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,
650
+ .mat-radio-button.mat-accent:active .mat-radio-persistent-ripple {
651
+ background-color: #8BC740; }
652
+
653
+ .mat-pseudo-checkbox-checked,
654
+ .mat-pseudo-checkbox-indeterminate,
655
+ .mat-accent .mat-pseudo-checkbox-checked,
656
+ .mat-accent .mat-pseudo-checkbox-indeterminate {
657
+ background: #8BC740; }
658
+
659
+ /* chips */
660
+ .default-mt-chips .mat-input-element {
661
+ color: rgba(0, 0, 0, 0.6); }
662
+ .default-mt-chips .mat-chip.mat-standard-chip,
663
+ .default-mt-chips .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
664
+ background-color: #40189D;
665
+ color: #fff; }
666
+ .default-mt-chips .mat-form-field-appearance-legacy .mat-form-field-label,
667
+ .default-mt-chips .mat-form-field-appearance-legacy .mat-hint,
668
+ .default-mt-chips input.mat-chip-input::placeholder {
669
+ color: rgba(0, 0, 0, 0.54); }
670
+ .default-mt-chips .mat-form-field.mat-focused .mat-form-field-label {
671
+ color: #40189D; }
672
+ .default-mt-chips .mat-form-field.mat-focused .mat-form-field-ripple {
673
+ background-color: #40189D; }
674
+ .default-mt-chips .mat-chip.mat-standard-chip .mat-chip-remove {
675
+ opacity: 1;
676
+ color: rgba(255, 255, 255, 0.8); }
677
+ .default-mt-chips .mat-form-field-appearance-legacy .mat-form-field-underline {
678
+ background-color: rgba(0, 0, 0, 0.42); }
679
+ .default-mt-chips .mat-form-field-infix {
680
+ width: 100%;
681
+ color: #fff; }
682
+ .default-mt-chips .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent {
683
+ background-color: #8BC740;
684
+ color: #fff; }
685
+
686
+ /* datepicker */
687
+ .default-mt-datepicker .mat-form-field-appearance-fill .mat-form-field-flex {
688
+ background-color: rgba(64, 24, 157, 0.1); }
689
+ .default-mt-datepicker .mat-form-field-label {
690
+ color: rgba(0, 0, 0, 0.6); }
691
+ .default-mt-datepicker .mat-date-range-input-inner,
692
+ .default-mt-datepicker .mat-calendar-body-cell-content,
693
+ .default-mt-datepicker .mat-date-range-input-separator {
694
+ color: #000; }
695
+ .default-mt-datepicker .mat-icon-button svg path {
696
+ fill: rgba(0, 0, 0, 0.7); }
697
+ .default-mt-datepicker .mat-form-field.mat-focused .mat-form-field-ripple {
698
+ background: #40189D; }
699
+ .default-mt-datepicker .mat-form-field.mat-focused .mat-form-field-label {
700
+ color: #40189D; }
701
+ .default-mt-datepicker .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label {
702
+ color: rgba(0, 0, 0, 0.5); }
703
+ .default-mt-datepicker .mat-form-field-appearance-fill .mat-form-field-underline:before {
704
+ background-color: rgba(0, 0, 0, 0.42); }
705
+ .default-mt-datepicker .mat-input-element:disabled,
706
+ .default-mt-datepicker .mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after {
707
+ color: #000; }
708
+
709
+ .mat-calendar-body-comparison-identical, .mat-calendar-body-in-comparison-range::before {
710
+ background: rgba(139, 199, 64, 0.2); }
711
+
712
+ .mat-calendar-body-selected {
713
+ background-color: #40189D; }
714
+
715
+ .mat-calendar-body-in-range::before {
716
+ background: rgba(64, 24, 157, 0.1); }
717
+
718
+ .mat-calendar-body-cell:not(.mat-calendar-body-disabled):hover > .mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical),
719
+ .cdk-keyboard-focused .mat-calendar-body-active > .mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical), .cdk-program-focused .mat-calendar-body-active > .mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical) {
720
+ background-color: rgba(64, 24, 157, 0.3); }
721
+
722
+ .mat-datepicker-content-container .example-header button {
723
+ height: 35px;
724
+ width: 35px;
725
+ outline: none;
726
+ border: 0;
727
+ border-radius: 35px;
728
+ font-size: 18px;
729
+ margin: 0 2px; }
730
+
731
+ /* dialog */
732
+ /* divider */
733
+ /* expansion */
734
+ .default-mt-expansion .mat-expansion-panel-header-description {
735
+ justify-content: space-between;
736
+ align-items: center; }
737
+ .default-mt-expansion .mat-accordion .mat-expansion-panel:first-of-type {
738
+ border-top-right-radius: 1.25rem;
739
+ border-top-left-radius: 1.25rem; }
740
+ .default-mt-expansion .mat-accordion .mat-expansion-panel:last-of-type {
741
+ border-bottom-right-radius: 1.25rem;
742
+ border-bottom-left-radius: 1.25rem; }
743
+ .default-mt-expansion .mat-expansion-panel-header {
744
+ height: auto;
745
+ padding: 15px 20px !important; }
746
+
747
+ /* form-field */
748
+ .default-mt-formfield .mat-form-field {
749
+ width: 100%; }
750
+ .default-mt-formfield .mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick {
751
+ color: #40189D; }
752
+ .default-mt-formfield .example-container .mat-form-field + .mat-form-field {
753
+ margin-left: 0 !important; }
754
+
755
+ /* input */
756
+ .default-mt-input .example-form {
757
+ width: 100% !important;
758
+ min-width: 150px;
759
+ max-width: 100% !important; }
760
+
761
+ /* progress */
762
+ .default-mt-progress .mat-progress-bar-buffer {
763
+ background-color: #e6defa; }
764
+ .default-mt-progress .mat-progress-bar-fill::after {
765
+ background-color: #40189D; }
766
+ .default-mt-progress .mat-progress-bar {
767
+ height: 8px;
768
+ border-radius: 8px; }
769
+ .default-mt-progress .mat-progress-bar pattern circle {
770
+ fill: #e6defa; }
771
+ .default-mt-progress .example-section {
772
+ height: auto !important; }
773
+ .default-mt-progress .mat-progress-bar.mat-accent .mat-progress-bar-fill::after {
774
+ background-color: #8BC740; }
775
+ .default-mt-progress .mat-progress-bar.mat-accent .mat-progress-bar-background {
776
+ fill: #8BC740; }
777
+ .default-mt-progress .mat-progress-bar.mat-accent .mat-progress-bar-buffer {
778
+ background-color: #8BC740; }
779
+
780
+ .mat-accent .mat-slider-track-fill, .mat-accent .mat-slider-thumb, .mat-accent .mat-slider-thumb-label {
781
+ background-color: #8BC740; }
782
+
783
+ /* spinner */
784
+ .mat-progress-spinner.mat-accent circle, .mat-spinner.mat-accent circle {
785
+ stroke: #8BC740; }
786
+
787
+ .mat-progress-spinner circle, .mat-spinner circle {
788
+ stroke: #40189D; }
789
+
790
+ .default-mt-spinner .example-margin {
791
+ margin: 0 10px; }
792
+
793
+ /* select */
794
+ .default-mt-select .mat-form-field.mat-focused .mat-form-field-label {
795
+ color: #40189D; }
796
+
797
+ /* sidenav */
798
+ .default-mt-sidenav .example-container {
799
+ margin: 0 !important;
800
+ width: 100% !important;
801
+ height: 350px !important;
802
+ box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
803
+ border: 0 !important; }
804
+ .default-mt-sidenav .mat-drawer-content {
805
+ padding: 25px !important; }
806
+
807
+ /* slidetoggle */
808
+ .default-mt-slidetoggle .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar {
809
+ background-color: #e6defa; }
810
+ .default-mt-slidetoggle .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb {
811
+ background-color: #40189D; }
812
+ .default-mt-slidetoggle .example-section {
813
+ height: auto !important; }
814
+
815
+ .mat-slide-toggle.mat-checked .mat-slide-toggle-bar {
816
+ background-color: rgba(139, 199, 64, 0.5); }
817
+
818
+ .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb {
819
+ background-color: #8BC740; }
820
+
821
+ .mat-slide-toggle.mat-checked .mat-ripple-element {
822
+ background-color: #8BC740; }
823
+
824
+ /* slider */
825
+ .default-mt-slider .example-section {
826
+ display: block !important;
827
+ height: auto !important; }
828
+
829
+ /* sort */
830
+ /* stepper */
831
+ .default-mt-stepper .mat-step-header .mat-step-icon-selected,
832
+ .default-mt-stepper .mat-step-header .mat-step-icon-state-done,
833
+ .default-mt-stepper .mat-step-header .mat-step-icon-state-edit {
834
+ background-color: #40189D; }
835
+ @media only screen and (max-width: 575px) {
836
+ .default-mt-stepper .mat-horizontal-stepper-header-container {
837
+ display: block; }
838
+ .default-mt-stepper .mat-horizontal-stepper-header-container .mat-horizontal-stepper-header {
839
+ padding: 0;
840
+ height: 60px;
841
+ margin-bottom: 10px;
842
+ margin-top: 10px; }
843
+ .default-mt-stepper .mat-horizontal-content-container {
844
+ padding: 0; }
845
+ .default-mt-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child)::before, .default-mt-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child)::before, .default-mt-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child)::after, .default-mt-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child)::after {
846
+ content: none; }
847
+ .default-mt-stepper .mat-stepper-label-position-bottom .mat-stepper-horizontal-line {
848
+ top: 0; } }
849
+
850
+ /* table */
851
+ .default-mt-table .mat-elevation-z8 {
852
+ box-shadow: none; }
853
+ .default-mt-table .table-responsive {
854
+ border-radius: 1.25rem;
855
+ position: relative;
856
+ z-index: 1; }
857
+ .default-mt-table .mat-header-cell {
858
+ color: #000;
859
+ padding: 0 10px;
860
+ font-size: 16px;
861
+ font-weight: 500; }
862
+ .default-mt-table .mat-footer-cell {
863
+ padding: 0 10px; }
864
+ .default-mt-table .mat-cell {
865
+ padding: 0 10px; }
866
+ .default-mt-table .example-element-diagram {
867
+ min-width: 100px !important;
868
+ font-weight: 400 !important;
869
+ height: 130px !important; }
870
+ .default-mt-table mat-row,
871
+ .default-mt-table mat-header-row,
872
+ .default-mt-table mat-footer-row,
873
+ .default-mt-table th.mat-header-cell,
874
+ .default-mt-table td.mat-cell,
875
+ .default-mt-table td.mat-footer-cell {
876
+ border-color: #EEEEEE; }
877
+ .default-mt-table .stickyColumns-table .mat-table-sticky {
878
+ background: #40189D !important; }
879
+ .default-mt-table .stickyColumns-table .mat-table-sticky .mat-header-cell {
880
+ color: #fff; }
881
+ .default-mt-table .stickyColumns-table .mat-table-sticky .mat-cell {
882
+ color: #fff; }
883
+ .default-mt-table .stickyColumns-table .mat-table-sticky .mat-footer-cell {
884
+ color: #fff; }
885
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-left,
886
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-right,
887
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-bottom,
888
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-top {
889
+ border-color: #fff;
890
+ color: #fff; }
891
+ .default-mt-table .stickyColumns-table .mat-column-filler {
892
+ font-size: 12px; }
893
+ .default-mt-table .stickyColumns-table mat-cell:first-of-type, .default-mt-table .stickyColumns-table mat-header-cell:first-of-type, .default-mt-table .stickyColumns-table mat-footer-cell:first-of-type {
894
+ padding-right: 10px; }
895
+ .default-mt-table .stickyColumns-table mat-cell:last-of-type, .default-mt-table .stickyColumns-table mat-header-cell:last-of-type, .default-mt-table .stickyColumns-table mat-footer-cell:last-of-type {
896
+ padding-left: 10px; }
897
+ .default-mt-table .stickyColumns-table .mat-header-cell,
898
+ .default-mt-table .stickyColumns-table .mat-footer-cell,
899
+ .default-mt-table .stickyColumns-table .mat-cell {
900
+ min-width: 100px !important; }
901
+ .default-mt-table .stickyColumns-table .mat-header-row,
902
+ .default-mt-table .stickyColumns-table .mat-footer-row,
903
+ .default-mt-table .stickyColumns-table .mat-row {
904
+ min-width: 2300px !important; }
905
+
906
+ /* tabs */
907
+ .default-mt-tabs .mat-tab-group.mat-primary .mat-ink-bar, .default-mt-tabs .mat-tab-nav-bar.mat-primary .mat-ink-bar {
908
+ background-color: #40189D; }
909
+ .default-mt-tabs .mat-tab-body-content {
910
+ padding: 10px 15px; }
911
+ .default-mt-tabs .mat-tab-group.mat-background-primary > .mat-tab-header, .default-mt-tabs .mat-tab-group.mat-background-primary > .mat-tab-link-container, .default-mt-tabs .mat-tab-group.mat-background-primary > .mat-tab-header-pagination, .default-mt-tabs .mat-tab-nav-bar.mat-background-primary > .mat-tab-header, .default-mt-tabs .mat-tab-nav-bar.mat-background-primary > .mat-tab-link-container, .default-mt-tabs .mat-tab-nav-bar.mat-background-primary > .mat-tab-header-pagination {
912
+ background-color: #40189D; }
913
+ .default-mt-tabs .mat-tab-group.mat-background-accent > .mat-tab-header, .default-mt-tabs .mat-tab-group.mat-background-accent > .mat-tab-link-container, .default-mt-tabs .mat-tab-group.mat-background-accent > .mat-tab-header-pagination, .default-mt-tabs .mat-tab-nav-bar.mat-background-accent > .mat-tab-header, .default-mt-tabs .mat-tab-nav-bar.mat-background-accent > .mat-tab-link-container, .default-mt-tabs .mat-tab-nav-bar.mat-background-accent > .mat-tab-header-pagination {
914
+ background-color: #8BC740; }
915
+ .default-mt-tabs .mat-tab-group.mat-accent.mat-background-accent > .mat-tab-header .mat-ink-bar, .default-mt-tabs .mat-tab-group.mat-accent.mat-background-accent > .mat-tab-link-container .mat-ink-bar, .default-mt-tabs .mat-tab-nav-bar.mat-accent.mat-background-accent > .mat-tab-header .mat-ink-bar, .default-mt-tabs .mat-tab-nav-bar.mat-accent.mat-background-accent > .mat-tab-link-container .mat-ink-bar {
916
+ background-color: #fff; }
917
+ .default-mt-tabs .mat-tab-group.mat-background-accent > .mat-tab-header .mat-tab-label, .default-mt-tabs .mat-tab-group.mat-background-accent > .mat-tab-link-container .mat-tab-link, .default-mt-tabs .mat-tab-nav-bar.mat-background-accent > .mat-tab-header .mat-tab-label, .default-mt-tabs .mat-tab-nav-bar.mat-background-accent > .mat-tab-link-container .mat-tab-link {
918
+ color: rgba(255, 255, 255, 0.8); }
919
+
920
+ /* tree */
921
+ .default-mt-tree .mat-checkbox-layout {
922
+ margin: 0; }
923
+ .default-mt-tree .mat-tree {
924
+ background: rgba(0, 0, 0, 0.05);
925
+ overflow: auto; }
926
+
927
+ /* toolbar */
928
+ .default-mt-toolbar .mat-toolbar.mat-primary {
929
+ background: #40189D; }
930
+
931
+ /*# sourceMappingURL=dashboard.css.map */
static/css/dashboard.css.map ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": 3,
3
+ "mappings": "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",
4
+ "sources": ["../scss/abstracts/_bs-custom.scss","../scss/abstracts/_mixin.scss","../scss/dashboard.scss","../scss/abstracts/_variable.scss"],
5
+ "names": [],
6
+ "file": "dashboard.css"
7
+ }
static/css/perfect-scrollbar.css ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Container style
3
+ */
4
+ .ps {
5
+ overflow: hidden !important;
6
+ overflow-anchor: none;
7
+ -ms-overflow-style: none;
8
+ touch-action: auto;
9
+ -ms-touch-action: auto;
10
+ }
11
+
12
+ /*
13
+ * Scrollbar rail styles
14
+ */
15
+ .ps__rail-x {
16
+ display: none;
17
+ opacity: 0;
18
+ transition: background-color .2s linear, opacity .2s linear;
19
+ -webkit-transition: background-color .2s linear, opacity .2s linear;
20
+ height: 15px;
21
+ /* there must be 'bottom' or 'top' for ps__rail-x */
22
+ bottom: 0px;
23
+ /* please don't change 'position' */
24
+ position: absolute;
25
+ }
26
+
27
+ .ps__rail-y {
28
+ display: none;
29
+ opacity: 0;
30
+ transition: background-color .2s linear, opacity .2s linear;
31
+ -webkit-transition: background-color .2s linear, opacity .2s linear;
32
+ width: 15px;
33
+ /* there must be 'right' or 'left' for ps__rail-y */
34
+ right: 0;
35
+ /* please don't change 'position' */
36
+ position: absolute;
37
+ }
38
+
39
+ .ps--active-x > .ps__rail-x,
40
+ .ps--active-y > .ps__rail-y {
41
+ display: block;
42
+ background-color: transparent;
43
+ }
44
+
45
+ .ps:hover > .ps__rail-x,
46
+ .ps:hover > .ps__rail-y,
47
+ .ps--focus > .ps__rail-x,
48
+ .ps--focus > .ps__rail-y,
49
+ .ps--scrolling-x > .ps__rail-x,
50
+ .ps--scrolling-y > .ps__rail-y {
51
+ opacity: 0.6;
52
+ }
53
+
54
+ .ps .ps__rail-x:hover,
55
+ .ps .ps__rail-y:hover,
56
+ .ps .ps__rail-x:focus,
57
+ .ps .ps__rail-y:focus,
58
+ .ps .ps__rail-x.ps--clicking,
59
+ .ps .ps__rail-y.ps--clicking {
60
+ background-color: #eee;
61
+ opacity: 0.9;
62
+ }
63
+
64
+ /*
65
+ * Scrollbar thumb styles
66
+ */
67
+ .ps__thumb-x {
68
+ background-color: #aaa;
69
+ border-radius: 6px;
70
+ transition: background-color .2s linear, height .2s ease-in-out;
71
+ -webkit-transition: background-color .2s linear, height .2s ease-in-out;
72
+ height: 6px;
73
+ /* there must be 'bottom' for ps__thumb-x */
74
+ bottom: 2px;
75
+ /* please don't change 'position' */
76
+ position: absolute;
77
+ }
78
+
79
+ .ps__thumb-y {
80
+ background-color: #aaa;
81
+ border-radius: 6px;
82
+ transition: background-color .2s linear, width .2s ease-in-out;
83
+ -webkit-transition: background-color .2s linear, width .2s ease-in-out;
84
+ width: 6px;
85
+ /* there must be 'right' for ps__thumb-y */
86
+ right: 2px;
87
+ /* please don't change 'position' */
88
+ position: absolute;
89
+ }
90
+
91
+ .ps__rail-x:hover > .ps__thumb-x,
92
+ .ps__rail-x:focus > .ps__thumb-x,
93
+ .ps__rail-x.ps--clicking .ps__thumb-x {
94
+ background-color: #999;
95
+ height: 11px;
96
+ }
97
+
98
+ .ps__rail-y:hover > .ps__thumb-y,
99
+ .ps__rail-y:focus > .ps__thumb-y,
100
+ .ps__rail-y.ps--clicking .ps__thumb-y {
101
+ background-color: #999;
102
+ width: 11px;
103
+ }
104
+
105
+ /* MS supports */
106
+ @supports (-ms-overflow-style: none) {
107
+ .ps {
108
+ overflow: auto !important;
109
+ }
110
+ }
111
+
112
+ @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
113
+ .ps {
114
+ overflow: auto !important;
115
+ }
116
+ }
static/css/style.css ADDED
The diff for this file is too large to render. See raw diff
 
static/css/style.css.map ADDED
The diff for this file is too large to render. See raw diff
 
static/img/AI.jpg ADDED
static/img/redmindlogo3.jpg ADDED
static/logos/avatar.svg ADDED
static/logos/calendar-silhouette.svg ADDED
static/logos/dots.svg ADDED
static/logos/email.svg ADDED
templates/API_connectors.html ADDED
@@ -0,0 +1,616 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <title>API Connectors</title>
6
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
8
+ <!-- Include AdminLTE CSS -->
9
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/adminlte.min.css">
10
+ <!-- Include DataTables CSS -->
11
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css">
12
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
13
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
14
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
15
+ <style>
16
+ .form-group {
17
+ margin-top: -10px;
18
+ }
19
+
20
+ .card {
21
+ padding: 0;
22
+ margin-top: -15px;
23
+ margin-left: -40px;
24
+ }
25
+
26
+ .header-row {
27
+ display: flex;
28
+ justify-content: space-between;
29
+ align-items: center;
30
+ }
31
+
32
+
33
+ .table-container {
34
+ width: 100%;
35
+ overflow-x: auto;
36
+ }
37
+
38
+ .wrapper {
39
+ display: flex;
40
+ flex-direction: column;
41
+ height: 100vh;
42
+ }
43
+
44
+ .content-wrapper {
45
+ flex: 1;
46
+ overflow-y: auto;
47
+ }
48
+
49
+ .content-header {
50
+ padding: 5px;
51
+ }
52
+
53
+ th,
54
+ td {
55
+ white-space: nowrap;
56
+ }
57
+
58
+ th:nth-child(1),
59
+ td:nth-child(1) {
60
+ /* Sno column */
61
+ width: 5%;
62
+ }
63
+
64
+ div.dataTables_wrapper div.dataTables_length select {
65
+ width: 60px;
66
+ display: inline-block;
67
+ }
68
+
69
+ th:nth-child(2),
70
+ td:nth-child(2) {
71
+ /* API Name column */
72
+ width: 20%;
73
+ }
74
+
75
+ th:nth-child(3),
76
+ td:nth-child(3) {
77
+ /* API Endpoint column */
78
+ width: 40%;
79
+ }
80
+
81
+ th:nth-child(4),
82
+ td:nth-child(4) {
83
+ /* Auth/Bearer token column */
84
+ width: 5%;
85
+ }
86
+
87
+ th:nth-child(5),
88
+ td:nth-child(5) {
89
+ /* View column */
90
+ width: 5%;
91
+ }
92
+
93
+ th:nth-child(6),
94
+ td:nth-child(6) {
95
+ /* View column */
96
+ width: 5%;
97
+ }
98
+
99
+ .reduced-width {
100
+ width: 25%;
101
+ }
102
+
103
+ div.dataTables_wrapper div.dataTables_length select {
104
+ width: 60px;
105
+ display: inline-block;
106
+ }
107
+ </style>
108
+ </head>
109
+
110
+ <body>
111
+ {% include 'sidepane.html' %}
112
+
113
+ <div class="wrapper">
114
+ <div class="main-header" style="border-bottom: none;">
115
+ <!-- Content Header (Page header) -->
116
+ <div class="content-header">
117
+ <div class="container-fluid">
118
+ <div class="container mt-2">
119
+ <div class="form-group left-align"id="company-select">
120
+ <h4 id="selectedCompany" style="margin-left: 300px;"></h4>
121
+
122
+ <!-- <div class="col-12 d-flex justify-content-end mb-3">
123
+ <button class="btn btn-primary"
124
+ style="margin-top: -40px;margin-right: -25px;position: fixed;" id="add">Add</button>
125
+ </div> -->
126
+ </div>
127
+ <div class="row">
128
+ <div id="message-container" style="margin-left: 200px; width:500px;"></div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ <h3 id="company_name" style="margin-left: 400px;">{{company_name}}</h3>
134
+ <section class="content" id="contentSection" style="display: none;">
135
+ <div class="container-fluid">
136
+ <div class="form-group">
137
+ <!-- <label for="company_id">company_id</label>--->
138
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
139
+ </div>
140
+ </div>
141
+
142
+
143
+ <!-- Main content -->
144
+ <section class="content">
145
+ <div class="container-fluid">
146
+ <div class="row">
147
+ <div class="col-12">
148
+ <div class="card">
149
+ <div class="card-body table-container">
150
+ <table id="apiTable" class="table table-bordered table-striped">
151
+ <thead>
152
+ <tr>
153
+ <th>Sno</th>
154
+ <th>API Name</th>
155
+ <th>API Endpoint</th>
156
+ <th>View</th>
157
+ <th>Edit</th>
158
+ <th>Delete</th>
159
+ </tr>
160
+ </thead>
161
+ <tbody>
162
+ <!-- <tr>
163
+ <td>1</td>
164
+ <td>Warehouse</td>
165
+ <td>http://193.203.162.39:9090/nxt-wms/userWarehouse/fetchWarehouseForUserId
166
+ </td>
167
+ <td><button class="btn btn-primary viewButton">View</button></td>
168
+ </tr>
169
+ <tr>
170
+ <td>2</td>
171
+ <td>customer</td>
172
+ <td>http://193.203.162.39:9090/nxt-wms/userCustomer/fetchCustomerForUserId
173
+ </td>
174
+ <td><button class="btn btn-primary viewButton">View</button></td>
175
+ </tr>
176
+ <tr>
177
+ <td>3</td>
178
+ <td>SKU</td>
179
+ <td>http://193.203.162.39:9090/nxt-wms/sku/autoComplete?</td>
180
+ <td><button class="btn btn-primary viewButton">View</button></td>
181
+ </tr>
182
+ <tr>
183
+ <td>4</td>
184
+ <td>ASN</td>
185
+ <td>http://193.203.162.39:9090/nxt-wms/trnHeader</td>
186
+ <td><button class="btn btn-primary viewButton">View</button></td>
187
+ </tr> -->
188
+ </tbody>
189
+ </table>
190
+ </div>
191
+ </div>
192
+ </div>
193
+ </div>
194
+ </div>
195
+ </section>
196
+ </div>
197
+
198
+ </div>
199
+
200
+ <!-- Modal -->
201
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
202
+ aria-hidden="true">
203
+ <div class="modal-dialog" style="margin-top: -10px;" role="document">
204
+ <div class="modal-content">
205
+ <div class="modal-header">
206
+ <h5 class="modal-title" id="addModalLabel">Add API Details</h5>
207
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
208
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false">&times;</span>
209
+ </button>
210
+ </div>
211
+ <div class="modal-body">
212
+ <div class="form-group">
213
+ <!-- <label for="company_id">company_id</label>--->
214
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
215
+ </div>
216
+ <form id="documentForm">
217
+ <div class="form-group">
218
+ <label for="APIName">API Name <span class="text-danger">*</span></label>
219
+ <input type="text" class="form-control" id="APIName" name="APIName" required>
220
+ </div>
221
+ <div class="form-group">
222
+ <label for="APIEndpoint">API Endpoint <span class="text-danger">*</span></label>
223
+ <input type="text" class="form-control" id="APIEndpoint" name="APIEndpoint" required>
224
+ </div>
225
+ <div class="form-group">
226
+ <label for="Auth_Bearer">Auth/Bearer token <span class="text-danger">*</span></label>
227
+ <input type="text" class="form-control" id="Auth_Bearer" name="Auth_Bearer" required>
228
+ </div>
229
+ <div class="form-group">
230
+ <label for="Inputjson">Input parameter <span class="text-danger">*</span></label>
231
+ <input type="text" class="form-control" id="Inputjson" name="Inputjson" required>
232
+ </div>
233
+ <div class="form-group">
234
+ <label for="OutputJson">Output Json <span class="text-danger">*</span></label>
235
+ <input type="text" class="form-control" id="OutputJson" name="OutputJson" required>
236
+ </div>
237
+ <div class="form-group">
238
+ <label for="Description">Description <span class="text-danger">*</span></label>
239
+ <textarea class="form-control" id="Description" name="Description" rows="3"
240
+ required></textarea>
241
+ </div>
242
+ </form>
243
+ </div>
244
+ <div class="modal-footer">
245
+ <!-- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> -->
246
+ <button type="button" id="saveupdate" class="btn btn-primary" style="display: none;">Update</button>
247
+ <button type="button" id="save" onclick="save_file()" class="btn btn-primary">Save</button>
248
+ </div>
249
+ </div>
250
+ </div>
251
+ </div>
252
+
253
+ {%include 'footer.html'%}
254
+
255
+ <!-- Include DataTables JS and your custom script -->
256
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
257
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
258
+
259
+
260
+ <script>
261
+ $(document).ready(function () {
262
+ // Show modal function
263
+ $('#add').on('click', function () {
264
+ const modalTitle = document.getElementById('addModalLabel');
265
+ modalTitle.textContent = 'Add API Details';
266
+ clearFormFields();
267
+ $('#save').show();
268
+ $('#saveupdate').hide();
269
+ $('#message-container').empty(); // Clear the message container
270
+ $('#addModal').modal('show');
271
+ });
272
+ $('.modal-footer .btn-secondary, .modal-header .close').on('click', function () {
273
+ $('#addModal').modal('hide');
274
+ });
275
+ // $('#apiTable').DataTable({
276
+ // autoWidth: false
277
+ // });
278
+
279
+ });
280
+ var table = $('#apiTable').DataTable();
281
+ const role = sessionStorage.getItem('userRole');
282
+ console.log('Current role:', role); // Debug statement to check the role
283
+ const company_name=sessionStorage.getItem('company_name');
284
+ console.log("company_name",company_name);
285
+ // document.getElementById('company_name').textContent = company_name;
286
+ const passedCompanyName = sessionStorage.getItem('company_name')
287
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
288
+ const company_id = sessionStorage.getItem('company_id');
289
+ document.getElementById("company_id").value = company_id;
290
+
291
+ data_get_from_db(company_id);
292
+
293
+
294
+ const companySelect = document.getElementById('company');
295
+ const documentForm = document.getElementById('documentForm');
296
+
297
+
298
+ function moveToNextInput(inputs, currentIndex) {
299
+ const nextInput = inputs[currentIndex + 1];
300
+ if (nextInput) {
301
+ nextInput.focus();
302
+ } else {
303
+ // Optionally, submit the form or trigger the save button
304
+ document.getElementById("save").focus();
305
+ }
306
+ }
307
+
308
+
309
+ function displayErrorMessage(message) {
310
+ const messageContainer = document.getElementById('message-container');
311
+ if (messageContainer) {
312
+ messageContainer.innerHTML = `<div class='alert alert-danger'>${message}</div>`;
313
+ }
314
+ }
315
+
316
+
317
+
318
+
319
+ async function data_get_from_db(companyId) {
320
+ if (companyId) {
321
+ try {
322
+ console.log('comp_id',companyId)
323
+ const Response = await fetch(`/api/get_api_connectors?company_id=${companyId}`);
324
+ console.log("responce from api :==> ", Response)
325
+ const connectorsResponse = await Response.json();
326
+ console.log("knowledge data table after connecting to table", connectorsResponse);
327
+ console.log("api connector data table after connecting to table", connectorsResponse);
328
+ const table = $('#apiTable').DataTable(); // Initialize DataTable at the start
329
+ table.clear();
330
+ if (!Array.isArray(connectorsResponse)) {
331
+ throw new TypeError('Expected an array of companies');
332
+
333
+ displayErrorMessage("Data do not exist for this company. Please fill in the details by clicking add button.");
334
+ contentSection.style.display = 'none';
335
+ } else {
336
+
337
+ connectorsResponse.forEach((company, index) => {
338
+ table.row.add([
339
+ index + 1,
340
+ company.APIName,
341
+ company.APIEndpoint,
342
+ `<a href='#' class='btn btn-info btn-sm'data-kid-id='${company.row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`,
343
+ `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${company.row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`,
344
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
345
+ ]).draw(false);
346
+ });
347
+ contentSection.style.display = 'block';
348
+ }
349
+
350
+ } catch (error) {
351
+ console.error('Error fetching company documents:', error);
352
+ //displayEmptyTable();
353
+
354
+ displayErrorMessage("Data do not exist for this company. Please fill in the details by clicking add button.");
355
+ contentSection.style.display = 'none';
356
+ }
357
+ }
358
+ else {
359
+ // displayEmptyTable();
360
+
361
+ displayErrorMessage("Document details2 for knowledge do not exist for this company. Please fill in the details.");
362
+ }
363
+ }
364
+
365
+ function viewCompany(button) {
366
+ var companyId = $(button).data('kid-id');
367
+ const modalTitle = document.getElementById('addModalLabel');
368
+ modalTitle.textContent = 'View API Details';
369
+ if(companyId)
370
+ {
371
+ $.getJSON(`/api/viewapiconnectors/${companyId}`, function (company) {
372
+
373
+ $('#APIName').val(company.api_name).attr('readonly', 'readonly');
374
+ $('#APIEndpoint').val(company.api_endpoint).attr('readonly', 'readonly');
375
+ $('#Auth_Bearer').val(company.auth_token).attr('readonly', 'readonly');
376
+ $('#Inputjson').val(company.input_param).attr('readonly', 'readonly');
377
+ $('#OutputJson').val(company.output_json).attr('readonly', 'readonly');
378
+ $('#Description').val(company.description).attr('readonly', 'readonly');
379
+ $('#save').hide();
380
+ $('#saveupdate').hide();
381
+ $('#addModal').modal('show');
382
+ }).fail(function () {
383
+ alert("Error retrieving API details.");
384
+ });
385
+ }
386
+ }
387
+ // Edit knowledge base details
388
+ function editCompany(button) {
389
+ var companyId = $(button).data('kid-id');
390
+ const modalTitle = document.getElementById('addModalLabel');
391
+ modalTitle.textContent = 'Edit API Details';
392
+ if(companyId)
393
+ {
394
+ // Fetch company details by ID
395
+ $.getJSON(`/api/viewapiconnectors/${companyId}`, function (company) {
396
+
397
+ $('#APIName').val(company.api_name);
398
+ $('#APIEndpoint').val(company.api_endpoint);
399
+ $('#Auth_Bearer').val(company.auth_token);
400
+ $('#Inputjson').val(company.input_param);
401
+ $('#OutputJson').val(company.output_json);
402
+ $('#Description').val(company.description);
403
+
404
+ // Show/hide appropriate elements
405
+ $('#uploadFile').show(); // Hide the file upload field
406
+ $('#save').hide(); // Hide the default save button
407
+ $('#saveupdate').show(); // Show the update button
408
+
409
+ // Ensure fields are editable
410
+ $('#APIName').removeAttr('readonly');
411
+ $('#APIEndpoint').removeAttr('readonly');
412
+ $('#Auth_Bearer').removeAttr('readonly');
413
+ $('#Inputjson').removeAttr('readonly');
414
+ $('#OutputJson').removeAttr('readonly');
415
+ $('#Description').removeAttr('readonly');
416
+
417
+
418
+ // Show the modal
419
+ $('#addModal').modal('show');
420
+
421
+ // Set up the click event for the update button
422
+ $('#saveupdate').off('click').on('click', function () {
423
+ saveupdate(companyId); // Pass the company ID for updating
424
+ });
425
+ }).fail(function () {
426
+ alert("Error in retrieving API details.");
427
+ });
428
+ }
429
+ }
430
+
431
+ function saveupdate(companyId, filename) {
432
+ const formData = new FormData();
433
+
434
+ const company_id = document.getElementById("company_id").value;
435
+ formData.append("company_id", $('#company_id').val());
436
+ formData.append("APIName", $('#APIName').val());
437
+ formData.append("APIEndpoint", $('#APIEndpoint').val());
438
+ formData.append("Auth_Bearer", $('#Auth_Bearer').val());
439
+ formData.append("Inputjson", $('#Inputjson').val());
440
+ formData.append("OutputJson", $('#OutputJson').val());
441
+ formData.append("Description", $('#Description').val());
442
+ console.log("company_id to table refresh", company_id)
443
+ const messageContainer = document.getElementById('message-container');
444
+ $.ajax({
445
+ url: `/api/editapiconnectors/${companyId}`,
446
+ type: 'PUT',
447
+ data: formData,
448
+ processData: false, // Required for FormData
449
+ contentType: false, // Required for FormData
450
+ success: function (response) {
451
+ // alert('Knowledgebase details updated successfully.');
452
+
453
+ if (messageContainer)
454
+ messageContainer.innerHTML = `
455
+ <div class='alert alert-success'>
456
+ API Data Updated successfully
457
+ <button class='close' onclick='dismissMessage()'>OK</button>
458
+ </div>`;
459
+ $('#addModal').modal('hide'); // Close the modal after saving
460
+ fetchUpdatedDocuments(company_id);
461
+ },
462
+ error: function () {
463
+ alert('Form has no changes to update knowledge base details.');
464
+ }
465
+ });
466
+ }
467
+ function dismissMessage() {
468
+ const messageContainer = document.getElementById('message-container');
469
+ if (messageContainer) {
470
+ messageContainer.innerHTML = '';
471
+ }
472
+ }
473
+ async function fetchUpdatedDocuments(company_id) {
474
+ console.log("company_id:", company_id);
475
+
476
+ var table = $('#apiTable').DataTable();
477
+ try {
478
+ const response = await fetch(`/api/api_updatetable?company_id=${company_id}`);
479
+ const connectorsResponse = await response.json();
480
+
481
+ console.log("Fetched connectorsResponse:", connectorsResponse);
482
+
483
+ table.clear(); // Clear existing data in the table
484
+
485
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
486
+ displayErrorMessage("Knowledgebase details do not exist for this company. Please fill in the details.");
487
+ contentSection.style.display = 'none';
488
+ } else {
489
+ connectorsResponse.forEach((company, index) => {
490
+ table.row.add([
491
+ index + 1,
492
+ company.api_name,
493
+ company.api_endpoint,
494
+ `<a href='#' class='btn btn-info btn-sm' data-kid-id='${company.row_id}' data-action="view" onclick='viewCompany(this)'><i class='fas fa-eye'></i></a>`,
495
+ `<a href='#' class='btn btn-warning btn-sm' data-kid-id='${company.row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`,
496
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
497
+ company.row_id
498
+ ]);
499
+ });
500
+ table.draw(false); // Draw the table with the new data
501
+ contentSection.style.display = 'block';
502
+ }
503
+ } catch (error) {
504
+ console.error("Error fetching updated documents:", error);
505
+ displayErrorMessage("There was an error fetching the updated documents.");
506
+ }
507
+ }
508
+
509
+ // Delete company
510
+ function deleteCompany(button) {
511
+ var companyId = $(button).data('kid-id');
512
+ console.log("k_id deleted", companyId);
513
+ $.ajax({
514
+ type: "DELETE",
515
+ url: `/api/deleteapi/${companyId}`,
516
+ success: function () {
517
+ var table = $('#apiTable').DataTable();
518
+ table.row($(button).closest('tr')).remove().draw();
519
+ const messageContainer = document.getElementById('message-container');
520
+ if (messageContainer)
521
+ messageContainer.innerHTML = `
522
+ <div class='alert alert-danger'>
523
+ API Data Deleted successfully
524
+ <button class='close' onclick='dismissMessage()'>OK</button>
525
+ </div>`;
526
+ //alert("Company deleted successfully.");
527
+ fetchCompanies(); // Refresh the table
528
+ },
529
+ error: function (xhr) {
530
+ alert("Error deleting company: " + xhr.responseJSON.detail);
531
+ }
532
+ });
533
+ }
534
+
535
+ function save_file() {
536
+ const form = document.getElementById('documentForm');
537
+ const messageContainer = document.getElementById('message-container');
538
+ // Check if the form is valid
539
+ if (!form.checkValidity()) {
540
+ // If the form is invalid, show validation messages and stop the submission
541
+ form.reportValidity();
542
+ return;
543
+ }
544
+ const company_id = $('#company_id').val();
545
+ const APIName = $('#APIName').val();
546
+ const APIEndpoint = $('#APIEndpoint').val();
547
+ const Auth_Bearer = $('#Auth_Bearer').val();
548
+ const Inputjson = $('#Inputjson').val();
549
+ const OutputJson = $('#OutputJson').val();
550
+ const Description = $('#Description').val();
551
+
552
+ var formData = new FormData($('#documentForm')[0]);
553
+
554
+ formData.append("company_id", company_id),
555
+ formData.append("api_name", APIName),
556
+ formData.append("api_endpoint", APIEndpoint),
557
+ formData.append("auth_bearer", Auth_Bearer),
558
+ formData.append("input_json", Inputjson),
559
+ formData.append("output_json", OutputJson),
560
+ formData.append("description", Description)
561
+
562
+ //const formData = new FormData();
563
+ fetch('/api/save_api_details', {
564
+ method: 'POST',
565
+ body: formData
566
+ })
567
+ .then(response => {
568
+ if (!response.ok) {
569
+ throw new Error('Network response was not ok');
570
+ }
571
+ return response.json();
572
+ })
573
+ .then(data => {
574
+ row_id = data.row_id;
575
+ var table = $('#apiTable').DataTable();
576
+ var rowCount = table.rows().count();
577
+ const view = `<a href='#' class='btn btn-info btn-sm'data-kid-id='${row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`;
578
+ const edit = `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`;
579
+ const dele = `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`;
580
+ table.row.add([
581
+ rowCount + 1,
582
+ APIName,
583
+ APIEndpoint,
584
+ view,
585
+ edit,
586
+ dele
587
+ ]).draw(false);
588
+
589
+ // alert('Document saved successfully');
590
+ if (messageContainer)
591
+ messageContainer.innerHTML = `
592
+ <div class='alert alert-success'>
593
+ API Data saved successfully
594
+ <button class='close' onclick='dismissMessage()'>OK</button>
595
+ </div>`;
596
+ $('#addModal').modal('hide');
597
+ document.getElementById('contentSection').style.display = 'block'; // Show the table section
598
+ })
599
+ .catch(error => console.error('Error:', error));
600
+ }
601
+
602
+
603
+ function clearFormFields() {
604
+ document.getElementById('APIName').value = "";
605
+ document.getElementById('APIEndpoint').value = "";
606
+ document.getElementById('Auth_Bearer').value = "";
607
+ document.getElementById('Inputjson').value = "";
608
+ document.getElementById('OutputJson').value = "";
609
+ document.getElementById('Description').value = "";
610
+ }
611
+
612
+
613
+ </script>
614
+ </body>
615
+
616
+ </html>
templates/chatbot.html ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # jinja2 html page with chatbot functionality using adminlte3 theme
2
+ <html>
3
+ <body>
4
+ <form id="myform">
5
+ <div class="content-wrapper">
6
+ <section class="content-header">
7
+ <div class="container-fluid">
8
+ <div class="row mb-2">
9
+ <div class="col-sm-6">
10
+ <h1>Chatbot</h1>
11
+ </div>
12
+ <div class="col-sm-6">
13
+ <ol class="breadcrumb float-sm-right">
14
+ <li class="breadcrumb-item"><a href="#">Home</a></li>
15
+ <li class="breadcrumb-item active">Chatbot</li>
16
+ </ol>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </section>
21
+
22
+ <section class="content">
23
+ <div class="container-fluid">
24
+ <div class="row">
25
+ <div class="col-md-8 offset-md-2">
26
+ <div class="card card-primary">
27
+ <div class="card-header">
28
+ <h3 class="card-title">Chat with our AI</h3>
29
+ </div>
30
+ <div class="card-body">
31
+ <div id="chat-container">
32
+ <div class="chat-messages">
33
+ <!-- Chat messages will be dynamically added here -->
34
+ </div>
35
+ <div class="chat-input">
36
+ <input type="text" id="user_question" placeholder="Type your message...">
37
+ <button id="send-button" onclick="clickform()">Send</button>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </section>
46
+ </div>
47
+ </form>
48
+ <script>
49
+ const chatContainer = document.getElementById('chat-container');
50
+ const userInput = document.getElementById('user_question');
51
+ const sendButton = document.getElementById('send-button');
52
+
53
+ function clickform() {
54
+ alert('Please enter');
55
+ var formElement = document.getElementById('myForm');
56
+ var user_question = document.getElementById('user_question').value;
57
+ alert(user_question);
58
+ //var data = new FormData(formElement);
59
+ //alert(data);
60
+ fetch('/chat_with_agent', {
61
+ method: 'POST',
62
+ //body: data,
63
+ })
64
+ .then(resp => resp.text()) // or, resp.json(), etc.
65
+ .then(data => {
66
+ //document.getElementById("responseArea").innerHTML = data;
67
+ alert(data);
68
+ const chatMessage = document.createElement('div');
69
+ chatMessage.classList.add('chat-message');
70
+ chatMessage.innerHTML = '<strong>You:</strong> ${user_question}<br><strong>AI:</strong> ${data}';
71
+ chatContainer.appendChild(chatMessage);
72
+
73
+ userInput.value = '';
74
+ userInput.focus();
75
+ })
76
+ .catch(error => {
77
+ console.error(error);
78
+ });
79
+ }
80
+ </script>
81
+ </body></html>
templates/company_profile.html ADDED
@@ -0,0 +1,724 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Company Profile</title>
8
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
10
+ <!-- Include AdminLTE CSS -->
11
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/adminlte.min.css">
12
+ <!-- Include DataTables CSS -->
13
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css">
14
+ <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css" rel="stylesheet" />
15
+ <link href="https://cdn.jsdelivr.net/npm/@ttskch/[email protected]/dist/select2-bootstrap4.min.css"
16
+ rel="stylesheet" />
17
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
18
+ <style>
19
+
20
+ #add {
21
+ display: inline-block ;
22
+ margin-right: 15px !important; /* Optional: Adjust margin if needed */
23
+ }
24
+
25
+ body {
26
+ background-color: transparent !important;
27
+ }
28
+
29
+ .card {
30
+ padding: 0;
31
+ margin-top: 10px;
32
+ margin-left: -50px;
33
+ }
34
+ /* Ensure the DataTable wrapper takes the full width */
35
+ .dataTables_wrapper {
36
+ width: 100%;
37
+ }
38
+ /* Ensure the DataTable wrapper takes the full width */
39
+ .dataTables_wrapper {
40
+ width: 100%;
41
+ }
42
+
43
+
44
+
45
+ /* Style for the custom dropdown */
46
+ .custom-dropdown {
47
+ position: relative;
48
+ display: inline-block;
49
+ margin-left: 10px; /* Space between label and dropdown */
50
+ }
51
+
52
+ .dropdown-button {
53
+ background-color: white;
54
+ color: black;
55
+ padding: 5px;
56
+ border: 1px solid black;
57
+ border-radius: 4px;
58
+ cursor: pointer;
59
+ text-align: left;
60
+ width: 60px; /* Adjust width as needed */
61
+ }
62
+
63
+ .dropdown-content {
64
+ display: none;
65
+ position: absolute;
66
+ background-color: #f9f9f9;
67
+ min-width: 80px; /* Adjust width as needed */
68
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
69
+ z-index: 1;
70
+ border: 1px solid #ddd;
71
+ top: 100%; /* Position below the button */
72
+ left: 0;
73
+ }
74
+
75
+ .dropdown-content a {
76
+ padding: 10px;
77
+ text-decoration: none;
78
+ display: block;
79
+ color: #333;
80
+ }
81
+
82
+ .dropdown-content a:hover {
83
+ background-color: #ddd;
84
+ }
85
+
86
+ .content-wrapper {
87
+ background-color: transparent !important;
88
+ text-align: center;
89
+ }
90
+
91
+ .wrapper {
92
+ background-color: transparent !important;
93
+ }
94
+
95
+ .modal-content {
96
+ background-color: #fff;
97
+ }
98
+
99
+ h1 {
100
+ text-align: center;
101
+ margin-bottom: 30px;
102
+ }
103
+
104
+
105
+ .table-responsive {
106
+ width: 95%;
107
+ overflow-x:none;
108
+ }
109
+
110
+ .table {
111
+ width: 100%;
112
+ }
113
+
114
+ .text-wrap {
115
+ white-space: normal !important;
116
+ word-break: break-word;
117
+ }
118
+
119
+ div.dataTables_wrapper div.dataTables_length select {
120
+ width: 60px;
121
+ display: inline-block;
122
+ }
123
+
124
+ .center-align {
125
+ padding-top: 20px;
126
+ display: flex;
127
+ justify-content: center;
128
+ align-items: center;
129
+ width: 100%;
130
+ }
131
+
132
+ .reduced-width {
133
+ width: 50%;
134
+ }
135
+
136
+ th,
137
+ td {
138
+ white-space: nowrap;
139
+ }
140
+
141
+ .select2-container--bootstrap4 {
142
+ z-index: 1050;
143
+ /* Higher than the modal's z-index */
144
+ }
145
+
146
+ .select2-container--open {
147
+ z-index: 1060;
148
+ /* Ensure the dropdown is above the modal */
149
+ }
150
+
151
+ th:nth-child(1),
152
+ td:nth-child(1) {
153
+ width: 5%;
154
+ }
155
+
156
+ th:nth-child(2),
157
+ td:nth-child(2) {
158
+ width: 20%;
159
+ }
160
+
161
+ th:nth-child(3),
162
+ td:nth-child(3) {
163
+ width: 20%;
164
+ }
165
+
166
+ th:nth-child(4),
167
+ td:nth-child(4) {
168
+ width: 20%;
169
+ }
170
+
171
+ th:nth-child(5),
172
+ td:nth-child(5) {
173
+ width: 10%;
174
+ }
175
+
176
+ th:nth-child(6),
177
+ td:nth-child(6) {
178
+ width: 10%;
179
+ }
180
+
181
+ th:nth-child(7),
182
+ td:nth-child(7) {
183
+ width: 10%;
184
+ }
185
+ th:nth-child(8),
186
+ td:nth-child(8) {
187
+ width: 10%;
188
+ }
189
+
190
+ .alert {
191
+ position: relative;
192
+ padding: 15px;
193
+ margin-bottom: 20px;
194
+ border: 1px solid transparent;
195
+ border-radius: 4px;
196
+ }
197
+
198
+ .alert-success {
199
+ color: #3c763d;
200
+ background-color: #dff0d8;
201
+ border-color: #d6e9c6;
202
+ }
203
+
204
+ .alert-danger {
205
+ color: #a94442;
206
+ background-color: #f2dede;
207
+ border-color: #ebccd1;
208
+ }
209
+
210
+ .close2 {
211
+ position: absolute;
212
+ bottom: 10px;
213
+ right: 10px;
214
+ border: none;
215
+ background: none;
216
+ font-size: 16px;
217
+ cursor: pointer;
218
+ }
219
+ </style>
220
+ </head>
221
+
222
+ <body>
223
+ {% include 'sidepane.html' %}
224
+
225
+ <div class="wrapper">
226
+ <div class="content-wrapper">
227
+ <!-- Content Header (Page header) -->
228
+ <div class="content-header">
229
+ <div class="container-fluid">
230
+ <div class="row mb-2">
231
+ <!-- <div class="col-12">
232
+ <div class="col-12 d-flex justify-content-end mb-3">
233
+ <button class="btn btn-primary" style="margin-bottom:-30px;position:fixed" id="add">Add</button>
234
+ </div>
235
+ </div> -->
236
+ <input type="hidden" id="userRole" name="userRole" value={{role}}>
237
+ <div class="row">
238
+ <div id="message-container" style="margin-left: 200px;width:600px;"></div>
239
+ </div>
240
+ </div>
241
+ </div>
242
+ </div>
243
+ <!-- Main content -->
244
+ <section class="content" id="startTable" style="display: none;">
245
+
246
+ <div class="row">
247
+ <div class="col-12">
248
+ <div class="card">
249
+ <div class="card-body table-container">
250
+ <div class="dataTables_wrapper">
251
+ <div class="row">
252
+ <div class="dataTables_length" >
253
+ <label style="display: inline-block;margin-right:800px; margin-bottom: -40px;" >Show entries:
254
+ <div class="custom-dropdown">
255
+ <button class="dropdown-button">5</button>
256
+ <div class="dropdown-content">
257
+ <a href="#" data-length="5">5</a>
258
+ <a href="#" data-length="10">10</a>
259
+ <a href="#" data-length="50">50</a>
260
+ <a href="#" data-length="100">100</a>
261
+ </div>
262
+ </div>
263
+ </label>
264
+ </div>
265
+ <table id="companyTable" class="table display mb-4 dataTablesCard dataTable table-responsive-xl card-table" >
266
+ <thead>
267
+ <tr>
268
+ <th>Sno</th>
269
+ <th>Company Name</th>
270
+ <th>Company code</th>
271
+ <th>Domain</th>
272
+ <th>LLM Tools</th>
273
+ <th>View</th>
274
+ <th>Edit</th>
275
+ <th>Delete</th>
276
+ </tr>
277
+ </thead>
278
+
279
+ </table>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ </div>
284
+ </div>
285
+ </section>
286
+ </div>
287
+ </div>
288
+ <!-- Modal -->
289
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
290
+ aria-hidden="true">
291
+ <div class="modal-dialog" role="document">
292
+ <div class="modal-content">
293
+ <div class="modal-header">
294
+ <h5 class="modal-title" id="addModalLabel">Add Company Profile</h5>
295
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
296
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false">&times;</span>
297
+ </button>
298
+ </div>
299
+ <div class="modal-body">
300
+ <form id="companyForm">
301
+ <div class="form-group">
302
+ <label for="companyName">Company Name<span class="text-danger">*</span></label>
303
+ <input type="text" class="form-control" id="company_name" name="company_name" required>
304
+ </div>
305
+ <div class="form-group">
306
+ <label for="companyCode">Company Code<span class="text-danger">*</span></label>
307
+ <input type="text" class="form-control" id="company_code" name="company_code" required>
308
+ </div>
309
+ <div class="form-group">
310
+ <label for="domain">Domain<span class="text-danger">*</span></label>
311
+ <input type="text" class="form-control" id="domain" name="domain" required>
312
+ </div>
313
+ <div class="form-group" >
314
+ <label for="llm_tools">LLM Tools<span class="text-danger">*</span></label>
315
+ <select class="form-select" id="llm_tools" name="llm_tools[]" multiple required>
316
+ <option value="Database">Database</option>
317
+ <option value="Static Documents">Static Documents</option>
318
+ <option value="API">API</option>
319
+ </select>
320
+
321
+ <div class="invalid-feedback">
322
+ Please select at least one LLM tool.
323
+ </div>
324
+ </div>
325
+
326
+ <div class="form-group">
327
+ <label for="domain">UserName<span class="text-danger">*</span></label>
328
+ <input type="text" class="form-control" id="username" name="username" required>
329
+ </div>
330
+ </form>
331
+ </div>
332
+ <div class="modal-footer">
333
+ <button type="button" id="saveupdate" class="btn btn-primary" style="display: none;">Update</button>
334
+ <button type="button" id="save" onclick="saveProfile()" class="btn btn-primary">Save</button>
335
+ </div>
336
+ </div>
337
+ </div>
338
+ </div>
339
+ {%include 'footer.html'%}
340
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
341
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
342
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js"></script>
343
+ <script>
344
+ document.addEventListener('DOMContentLoaded', function () {
345
+
346
+ const role = sessionStorage.getItem('userRole');
347
+ const company_id=sessionStorage.getItem('company_id');
348
+ console.log('Current role:', role); // Debug statement to check the role
349
+ document.getElementById('userRole').value = role;
350
+ const passedCompanyName = sessionStorage.getItem('company_name')
351
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
352
+ $('#addModal').hide(); // Make sure this is called initially
353
+ function checkForAddButton() {
354
+ const addButton = document.getElementById('add');
355
+
356
+ if (addButton) {
357
+ // Stop checking once the element is found
358
+ clearInterval(checkInterval);
359
+ if (role === 'superadmin') {
360
+ console.log("insidse compamy profile super admin");
361
+
362
+ $('#startTable').show();
363
+ $('#addModal').hide();
364
+ $('#add').show();
365
+
366
+
367
+ } else {
368
+ console.log("insidse company profile admin");
369
+ $('#add').hide();
370
+ const modalTitle = document.getElementById('addModalLabel');
371
+ modalTitle.textContent = 'Company Details';
372
+ viewCompany(company_id);
373
+ }
374
+ }
375
+ }
376
+ const checkInterval = setInterval(checkForAddButton, 100); //
377
+ document.querySelector('.dropdown-button').addEventListener('click', function() {
378
+ const dropdownContent = document.querySelector('.dropdown-content');
379
+ dropdownContent.style.display = dropdownContent.style.display === 'block' ? 'none' : 'block';
380
+ });
381
+ fetchCompanies();
382
+ });
383
+ window.addEventListener('click', function(event) {
384
+ if (!event.target.matches('.dropdown-button')) {
385
+ const dropdownContents = document.querySelectorAll('.dropdown-content');
386
+ dropdownContents.forEach(function(content) {
387
+ content.style.display = 'none';
388
+ });
389
+ }
390
+ });
391
+ window.addEventListener('pageshow', function (event) {
392
+ if (event.persisted || (window.performance && window.performance.navigation.type === 2)) {
393
+ window.location.reload();
394
+ }
395
+ });
396
+
397
+
398
+ $(document).ready(function () {
399
+ // Initialize DataTable
400
+ //$('#companyTable').DataTable();
401
+ $('#companyTable').DataTable({
402
+
403
+ "paging": true,
404
+ "pageLength":5,
405
+ "lengthChange": false,
406
+ "searching": true,
407
+ "ordering": true,
408
+ "info": true,
409
+ "autoWidth": false,
410
+ "responsive": true
411
+ });
412
+
413
+ // Initialize Select2
414
+ $('select').select2({
415
+ theme: 'bootstrap4',
416
+ placeholder: 'Select',
417
+ allowClear: true,
418
+ dropdownParent: $('#addModal')
419
+ });
420
+
421
+ // Show modal function
422
+ $('#add').on('click', function () {
423
+ const modalTitle = document.getElementById('addModalLabel');
424
+ modalTitle.textContent = 'Add Company Details';
425
+ console.log('Modal title after setting:', modalTitle.textContent); // This should log the new title
426
+ $('#company_name').removeAttr('readonly');
427
+ $('#company_code').removeAttr('readonly');
428
+ $('#domain').removeAttr('readonly');
429
+ $('select').prop('disabled', false);
430
+ $('#username').removeAttr('readonly');
431
+ $('#addModal').modal('show');
432
+ $('#save').show();
433
+ $('#saveupdate').hide();
434
+
435
+
436
+ clearmodal();
437
+ $('#save').prop('disabled', false); // Disable the "Save" button when the modal opens
438
+ });
439
+ $('.modal-footer .btn-secondary, .modal-header .close').on('click', function () {
440
+ $('#addModal').modal('hide');
441
+ });
442
+ $('#addModal').on('shown.bs.modal', function() {
443
+ $('#companyTable').DataTable().columns.adjust().draw();
444
+ // Initialize Select2 only if not already initialized
445
+ if (!$('#llm_tools').hasClass('select2-hidden-accessible')) {
446
+ $('select').select2({
447
+ theme: 'bootstrap4',
448
+ placeholder: 'Select LLM Tools',
449
+ allowClear: true,
450
+ dropdownParent: $('#addModal')
451
+ });
452
+ }
453
+ });
454
+
455
+ $(document).on('click', '.btn-view', function () {
456
+ const companyId = $(this).data('id');
457
+ console.log("company_id in view", companyId);
458
+ viewCompany(companyId);
459
+ });
460
+
461
+ // Edit company details
462
+ $(document).on('click', '.btn-edit', function () {
463
+ const companyId = $(this).data('id');
464
+ console.log("company_id in edit", companyId);
465
+ if (companyId)
466
+ {
467
+ const modalTitle = document.getElementById('addModalLabel');
468
+ modalTitle.textContent = 'Edit Company Details';
469
+ console.log('Modal title:', modalTitle.textContent);
470
+
471
+ Editcompany(companyId);
472
+ }
473
+ });
474
+
475
+ // Delete company
476
+ $(document).on('click', '.btn-delete', function () {
477
+ const companyId = $(this).data('id'); // Get the company ID from the da
478
+ console.log("company_id in delete", companyId);
479
+ if (confirm("Are you sure you want to delete this company?")) {
480
+ deleteCompany(companyId); // Call the delete function with the company ID
481
+ }
482
+ });
483
+ });
484
+ // View company details
485
+ function viewCompany(companyId) {
486
+ const username = sessionStorage.getItem('username');
487
+ const modalTitle = document.getElementById('addModalLabel');
488
+ modalTitle.textContent = 'View Company Details';
489
+
490
+ // Fetch company details by ID
491
+ $.getJSON(`/api/getcompanydetails/${companyId}`, function (company) {
492
+ console.log("Fetched company details:", company);
493
+
494
+ // Set the company fields to readonly
495
+ $('#company_name').val(company.company_name).attr('readonly', 'readonly');
496
+ $('#company_code').val(company.company_code).attr('readonly', 'readonly');
497
+ $('#domain').val(company.domain).attr('readonly', 'readonly');
498
+ $('select').val(company.llm_tools.split(',')).trigger('change');
499
+ $('select').prop('disabled', true);
500
+ $('#username').val(username).attr('readonly', 'readonly');
501
+
502
+ // Show the modal
503
+ $('#saveupdate').hide();
504
+ $('#save').hide();
505
+ $('#addModal').modal('show');
506
+ }).fail(function () {
507
+ console.error("Error retrieving company details.");
508
+ });
509
+ }
510
+ // Edit company details
511
+ function Editcompany(companyId) {
512
+
513
+ const username=sessionStorage.getItem('username');
514
+ const modalTitle = document.getElementById('addModalLabel');
515
+ modalTitle.textContent = 'Edit Company Details';
516
+ console.log('Modal title after setting:', modalTitle.textContent); // Should log "Edit Company Details"
517
+ // Fetch company details by ID
518
+ $.getJSON(`/api/getcompanydetails/${companyId}`, function (company) {
519
+ $('#company_name').removeAttr('readonly');
520
+ $('#company_code').removeAttr('readonly');
521
+ $('#domain').removeAttr('readonly');
522
+ $('select').prop('disabled', false);
523
+ $('#save').hide();
524
+ $('#saveupdate').show();
525
+ // Populate the form with the company's details
526
+ $('#company_name').val(company.company_name);
527
+ $('#company_code').val(company.company_code);
528
+ $('#domain').val(company.domain);
529
+ $('select').val(company.llm_tools.split(',')).trigger('change');
530
+ $('#username').val(username).attr('readonly', 'readonly');// Disable the select input
531
+
532
+ //sessionStorage.setItem('llmTools', company.llm_tools); // Store as a string
533
+ $('#addModal').modal('show');
534
+
535
+ // Update the save button to save the edited company
536
+ $('#saveupdate').off('click').on('click', function () {
537
+
538
+ saveupdate(companyId); // Pass the company ID for updating
539
+ });
540
+ }).fail(function () {
541
+ alert("Error retrieving company details.");
542
+ });
543
+ }
544
+
545
+ // Delete company
546
+ function deleteCompany(companyId) {
547
+ console.log("company_id deleted", companyId);
548
+ $.ajax({
549
+ type: "DELETE",
550
+ url: `/api/delcompanydetails/${companyId}`,
551
+ success: function () {
552
+ // alert("Company deleted successfully.");
553
+ const messageContainer = document.getElementById('message-container');
554
+ if (messageContainer)
555
+ messageContainer.innerHTML = `
556
+ <div class='alert alert-danger'>
557
+ Company details deleted successfully.
558
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
559
+ </div>`;
560
+ fetchCompanies(); // Refresh the table
561
+ },
562
+ error: function (xhr) {
563
+ alert("Error deleting company: " + xhr.responseJSON.detail);
564
+ }
565
+ });
566
+ }
567
+ function saveupdate(companyId) {
568
+ console.log("company_id", companyId);
569
+ const llm_tools= $('#llm_tools').select2("val");
570
+ var formData = new FormData();
571
+ formData.append('company_name', $('#company_name').val());
572
+ formData.append('company_code', $('#company_code').val());
573
+ formData.append('domain', $('#domain').val());
574
+ formData.append('llm_tools',llm_tools); // Assuming llm_tools is a multi-select
575
+
576
+ console.log("company_data", formData);
577
+
578
+ $.ajax({
579
+ url: `/api/putcompanydetails/${companyId}`,
580
+ type: 'PUT',
581
+ data: formData,
582
+ processData: false, // Important for FormData
583
+ contentType: false,
584
+ success: function (response) {
585
+ // alert('Company details updated successfully.');
586
+ const messageContainer = document.getElementById('message-container');
587
+ if (messageContainer)
588
+ messageContainer.innerHTML = `
589
+ <div class='alert alert-success'>
590
+ Company Data Updated successfully
591
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
592
+ </div>`;
593
+ $('#addModal').modal('hide'); // Close the modal after saving
594
+ fetchCompanies();
595
+ },
596
+ error: function () {
597
+
598
+ const messageContainer = document.getElementById('message-container');
599
+ if (messageContainer)
600
+ messageContainer.innerHTML = `
601
+ <div class='alert alert-danger'>
602
+ No changes have been made to update company details.
603
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
604
+ </div>`;
605
+ $('#addModal').modal('hide');
606
+ //alert('No changes have been made to update company details.');
607
+ }
608
+ });
609
+ }
610
+
611
+ function saveProfile() {
612
+ const form = document.getElementById('companyForm');
613
+
614
+ // Check if the form is valid
615
+ if (!form.checkValidity()) {
616
+ // If the form is invalid, show validation messages and stop the submission
617
+ form.reportValidity();
618
+ return;
619
+ }
620
+
621
+ // Gather form data
622
+ const company_name = document.getElementById('company_name').value;
623
+ const company_code = document.getElementById('company_code').value;
624
+ const domain = document.getElementById('domain').value;
625
+ const llm_tools = $('#llm_tools').select2("val");
626
+ console.log("Selected LLM Tools:", llm_tools);
627
+ // console.log("llm_tools element:", document.getElementById('llm_tools'));
628
+ const username=$('#username').val();
629
+
630
+
631
+ // Prepare FormData
632
+ let formData = new FormData();
633
+ const password="password";
634
+ const rolesave="admin";
635
+ formData.append("company_name", company_name);
636
+ formData.append("company_code", company_code);
637
+ formData.append("domain", domain);
638
+ formData.append("llm_tools", llm_tools);
639
+ formData.append("username",username);
640
+ formData.append("password",password);
641
+ formData.append("role",rolesave);
642
+
643
+ $.ajax({
644
+ type: "POST",
645
+ url: "/submit_company_profile",
646
+ data: formData,
647
+ processData: false,
648
+ contentType: false,
649
+ success: function (response) {
650
+ // alert("Data saved successfully"); // Show success message
651
+ const messageContainer = document.getElementById('message-container');
652
+ if (messageContainer)
653
+ messageContainer.innerHTML = `
654
+ <div class='alert alert-success'>
655
+ Data saved successfully
656
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
657
+ </div>`;
658
+ fetchCompanies(); // Refresh table data
659
+
660
+ // Clear the form and close the modal
661
+ // $('#companyForm')[0].reset();
662
+ $('#addModal').modal('hide');
663
+ },
664
+ error: function (xhr) {
665
+ alert("An error occurred: " + xhr.responseJSON.detail); // Show error message
666
+ }
667
+ });
668
+ }
669
+ function dismissMessage() {
670
+ const messageContainer = document.getElementById('message-container');
671
+ if (messageContainer) {
672
+ messageContainer.innerHTML = '';
673
+ }
674
+ }
675
+ async function fetchCompanies() {
676
+ try {
677
+ console.log("Fetching companies...");
678
+ const response = await fetch(`/api/companydetails`);
679
+ const companies = await response.json();
680
+ console.log(companies); // Inspect the data here
681
+
682
+ if (!Array.isArray(companies)) {
683
+ throw new TypeError('Expected an array of companies');
684
+ }
685
+
686
+ const table = $('#companyTable').DataTable();
687
+ table.clear(); // Clear existing table data
688
+
689
+ companies.forEach((company, index) => {
690
+ table.row.add([
691
+ index + 1,
692
+ company.company_name,
693
+ company.company_code,
694
+ company.domain,
695
+ company.llm_tools, // Join array of tools into a string
696
+ `<a href='#' class='btn btn-info btn-sm'onclick='viewCompany(${company.company_id})'><i class='fas fa-eye'></i></a>`,
697
+ `<a href='#' class='btn btn-warning btn-sm'onclick='Editcompany(${company.company_id})'><i class='fas fa-edit'></i></a>`,
698
+ `<a href='#' class='btn btn-danger btn-sm' onclick='deleteCompany(${company.company_id})'><i class='fas fa-trash'></i></a>`
699
+
700
+ ])
701
+ });table.draw(false);
702
+ } catch (error) {
703
+ console.error('Error fetching companies:', error);
704
+ }
705
+ }
706
+ function clearmodal() {
707
+ $('#companyForm')[0].reset(); // Reset all form fields
708
+ $('#llm_tools').val(null).trigger('change'); // Clear and reset the Select2 field without reinitializing
709
+ }
710
+
711
+ document.querySelectorAll('.dropdown-content a').forEach(function(item) {
712
+ item.addEventListener('click', function() {
713
+ const length = item.getAttribute('data-length');
714
+ // Set the DataTable page length
715
+ $('#companyTable').DataTable().page.len(parseInt(length)).draw();
716
+ document.querySelector('.dropdown-button').textContent = length;
717
+ });
718
+ });
719
+
720
+
721
+ </script>
722
+ </body>
723
+
724
+ </html>
templates/dashboard.html ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Dashboard</title>
8
+ <!-- CSS -->
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
10
+ <link rel="stylesheet" type="text/css" href="../static/css/style.css" />
11
+ <link rel="stylesheet" type="text/css" href="../static/css/dashboard.css" />
12
+ <link rel="stylesheet" type="text/css" href="../static/css/perfect-scrollbar.css" />
13
+ <style>
14
+ .btn-primary {
15
+ background-color: #0d6efd;
16
+ border-radius:5px;
17
+ border-color: #0d6efd;
18
+ }
19
+ #sidebarToggle
20
+ {
21
+ border-radius:4px;
22
+ margin-left:250px;
23
+ }
24
+ .main-sidebar.toggled .menu-text {
25
+ display: none;
26
+ }
27
+ #selectedCompany.toggled .menu-text {
28
+ display: none;
29
+ }
30
+ .wrapper {
31
+ flex: 1;
32
+ padding: 10px;
33
+ margin-left: 300px; /* Default sidebar width */
34
+ transition: margin-left 0.3s ease;
35
+ }
36
+
37
+ .main-header {
38
+ border-bottom: none;
39
+ border-top: none;
40
+ }
41
+
42
+ .card {
43
+ margin-bottom: 15px;
44
+ border-radius: 8px;
45
+ overflow: hidden;
46
+ transition: background-color 0.3s ease;
47
+ }
48
+
49
+ .card-body {
50
+ padding: 15px;
51
+ }
52
+
53
+ .feature-icon {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ justify-content: center;
57
+ width: 50px;
58
+ height: 50px;
59
+ background: rgba(255, 255, 255, 0.1);
60
+ border-radius: 50%;
61
+ }
62
+ .sidebarPanel
63
+ {
64
+ display:none;
65
+ }
66
+ .media-body {
67
+ text-align: right;
68
+ }
69
+
70
+ .fs-30 {
71
+ font-size: 1.875rem;
72
+ }
73
+
74
+ .fs-48 {
75
+ font-size: 3rem;
76
+ }
77
+
78
+
79
+ /* Responsive Styles */
80
+ @media (max-width: 992px) {
81
+ .wrapper {
82
+ margin-left: 200px;
83
+ }
84
+
85
+ .main-header {
86
+ padding: 15px;
87
+ }
88
+
89
+ }
90
+
91
+ @media (max-width: 768px) {
92
+ .feature-icon {
93
+ width: 40px;
94
+ height: 40px;
95
+ }
96
+
97
+ .fs-30 {
98
+ font-size: 1.5rem;
99
+ }
100
+
101
+ .fs-48 {
102
+ font-size: 2.5rem;
103
+ }
104
+ }
105
+ </style>
106
+ </head>
107
+
108
+ <body>
109
+ {% set company_name = company_name %}
110
+ {% include 'sidepane.html' %}
111
+
112
+ <div class="wrapper">
113
+ <section class="main-header">
114
+ <div class="container-fluid">
115
+ <div id="company-block" class="form-group left-align" style="display: none;">
116
+ <label for="company" class="ml-3" style="display: inline-block; margin-right: 10px;">
117
+ Select the Company Name to view the details <span class="text-danger">*</span>
118
+ </label>
119
+ <select type="text" id="company" name="company" class="ml-3 form-control"
120
+ style="display: inline-block; width: 20%;" required>
121
+ <option value="" selected>Select</option>
122
+ </select>
123
+ </div>
124
+
125
+ <div class="row">
126
+ <div class="col-md-6">
127
+ <div class="card bg-primary">
128
+ <div class="card-body">
129
+ <div class="media align-items-center">
130
+ <span class="p-3 mr-3 feature-icon rounded">
131
+ <img src="../static/logos/calendar-silhouette.svg" />
132
+ </span>
133
+ <div class="media-body">
134
+ <p class="fs-30 text-white mb-2">KnowledgeBase</p>
135
+ <span id="knowledgeBaseCount" class="fs-48 text-white font-w600">{{table_count_of_each_table.knowledge_base}}</span>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ <div class="col-md-6">
142
+ <div class="card bg-info">
143
+ <div class="card-body">
144
+ <div class="media align-items-center">
145
+ <span class="p-3 mr-3 feature-icon rounded">
146
+ <img src="../static/logos/calendar-silhouette.svg" />
147
+ </span>
148
+ <div class="media-body">
149
+ <p class="fs-30 text-white mb-2">Data connectors</p>
150
+ <span id="dataConnectorsCount" class="fs-48 text-white font-w600">{{table_count_of_each_table.data_connectors}}</span>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ <div class="row">
158
+ <div class="col-md-6 ">
159
+ <div class="card bg-success">
160
+ <div class="card-body">
161
+ <div class="media align-items-center">
162
+ <span class="p-3 mr-3 feature-icon rounded">
163
+ <img src="../static/logos/email.svg" />
164
+ </span>
165
+ <div class="media-body">
166
+ <p class="fs-30 text-white mb-2">API Connectors</p>
167
+ <span id="apiConnectorsCount" class="fs-48 text-white font-w600">{{table_count_of_each_table.api_connectors}}</span>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ </div>
172
+ </div>
173
+ <div class="col-md-6 ">
174
+ <div class="card bg-secondary">
175
+ <div class="card-body">
176
+ <div class="media align-items-center">
177
+ <span class="p-3 mr-3 feature-icon rounded">
178
+ <img src="../static/logos/dots.svg" />
179
+ </span>
180
+ <div class="media-body">
181
+ <p class="fs-30 text-white mb-2">Prompt_Templates</p>
182
+ <span id="promptTemplatesCount" class="fs-48 text-white font-w600">{{table_count_of_each_table.prompt_templates}}</span>
183
+ </div>
184
+ </div>
185
+ </div>
186
+ </div>
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </section>
191
+ <input type="hidden" id="userRole" name="userRole" value={{role}}>
192
+ <input type="hidden" id="company_id" name="company_id" value={{company_id}}>
193
+ <input type="hidden" id="username" name="username" value={{username}}>
194
+ <input type="hidden" id="company_name" name="company_name" value={{company_name}}>
195
+
196
+ </div>
197
+
198
+
199
+ {% include 'footer.html' %}
200
+
201
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/adminlte.min.js"></script>
202
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
203
+ <script>
204
+ document.getElementById("add").style.display = "none";
205
+
206
+ // function updateCompanyName(newCompanyName) {
207
+ // sessionStorage.setItem('company_name', newCompanyName);
208
+ // document.getElementById('selectedCompany').innerText = `Company name: ${newCompanyName}`;
209
+ // const sidePaneCompanyName = document.querySelector('.sidebar .company-name');
210
+ // if (sidePaneCompanyName) {
211
+ // sidePaneCompanyName.innerText = newCompanyName;
212
+ // }
213
+ // }
214
+ function updateSidepane(companyName) {
215
+ const sidepaneCompanyElement = document.getElementById('selectedCompany');
216
+ if (sidepaneCompanyElement) {
217
+ sidepaneCompanyElement.innerText = `Company Name: ${companyName}`;
218
+ }
219
+ }
220
+
221
+ window.addEventListener('pageshow', function (event) {
222
+ if (event.persisted || (window.performance && window.performance.navigation.type === 2)) {
223
+ window.location.reload();
224
+ }
225
+ });
226
+
227
+ document.addEventListener('DOMContentLoaded', function () {
228
+ var role1 = document.getElementById("userRole").value;
229
+ var company_id1 = document.getElementById("company_id").value;
230
+ var company_name1=document.getElementById("company_name").value;
231
+ var username1=document.getElementById("username").value;
232
+ console.log("companyid in dasshboard",username1);
233
+ sessionStorage.setItem('userRole', role1);
234
+ // sessionStorage.setItem('siderole',role1);
235
+ // sessionStorage.setItem('sidecompanyId',company_id1);
236
+ sessionStorage.setItem('company_id', company_id1);
237
+ sessionStorage.setItem('company_name',company_name1);
238
+ sessionStorage.setItem('username',username1);
239
+ const companyName = sessionStorage.getItem('company_name');
240
+ if (companyName) {
241
+
242
+ updateSidepane(companyName);
243
+ }
244
+ else{
245
+ document.getElementById(selectedCompany).value="Select a company";
246
+ }
247
+
248
+
249
+ if (!role1) {
250
+ var roleFromInput = sessionStorage.getItem('userRole');
251
+ sessionStorage.setItem('userRole', roleFromInput);
252
+ console.log("Role set in sessionStorage:", roleFromInput);
253
+ } else {
254
+ sessionStorage.setItem('userRole', role1);
255
+ console.log("Retrieved user role from input:", role1); // Debugging
256
+ }
257
+ if (role1 === "superadmin") {
258
+ document.getElementById('company-block').style.display = 'block';
259
+ fetchCompanies();
260
+ }
261
+
262
+ });
263
+ document.getElementById('company').addEventListener('change', async function () {
264
+ const selectedCompany = this.value;
265
+ sessionStorage.setItem("company_name",selectedCompany);
266
+ // Update the sidepane immediately
267
+ updateSidepane(selectedCompany);
268
+ if (selectedCompany!== "Select") {
269
+ try {
270
+ const response = await fetch(`/api/company_id?company_name=${encodeURIComponent(selectedCompany)}`);
271
+ if (!response.ok) {
272
+ contentSection.style.display = 'none';
273
+ displayErrorMessage("Document details do not exist for this company. Please fill in the details.");
274
+ throw new Error('Network response was not ok');
275
+ }
276
+ const data = await response.json();
277
+ console.log('data returned', data);
278
+ const companyId = data.company_id;
279
+ sessionStorage.setItem("company_id",companyId);
280
+ console.log("company id for superadmin", company_id);
281
+ //document.getElementById('company_id').value = companyId;
282
+
283
+
284
+ if (companyId) {
285
+ try {
286
+ const countResponse = await fetch(`/api/company_record_count/${companyId}`);
287
+ if (!countResponse.ok) {
288
+ throw new Error('Network response was not ok');
289
+ }
290
+ const countData = await countResponse.json();
291
+ console.log('Count data:', countData); // Log the response data
292
+ updateRecordCounts(countData.table_counts);
293
+ } catch (error) {
294
+ console.error('Error fetching record counts:', error);
295
+ }
296
+ } else {
297
+ clearRecordCounts();
298
+ }
299
+ } catch (error) {
300
+ console.error('No details for this company ID or data documents:', error);
301
+ // displayEmptyTable();
302
+
303
+ displayErrorMessage("company details do not exist for this company.");
304
+
305
+ }
306
+ }
307
+ });
308
+
309
+ function updateRecordCounts(counts) {
310
+ // Update the counts displayed in the dashboard
311
+ document.getElementById('knowledgeBaseCount').textContent = counts.knowledge_base || 0;
312
+ document.getElementById('dataConnectorsCount').textContent = counts.data_connectors || 0;
313
+ document.getElementById('apiConnectorsCount').textContent = counts.api_connectors || 0;
314
+ document.getElementById('promptTemplatesCount').textContent = counts.prompt_templates || 0;
315
+ }
316
+
317
+ function clearRecordCounts() {
318
+ document.getElementById('knowledgeBaseCount').textContent = 0;
319
+ document.getElementById('dataConnectorsCount').textContent = 0;
320
+ document.getElementById('apiConnectorsCount').textContent = 0;
321
+ document.getElementById('promptTemplatesCount').textContent = 0;
322
+ }
323
+
324
+ async function fetchCompanies() {
325
+ try {
326
+ const response = await fetch('/api/companies');
327
+ if (!response.ok) {
328
+ throw new Error('Network response was not ok');
329
+ }
330
+ const data = await response.json();
331
+ displayCompanies(data.companies);
332
+ } catch (error) {
333
+ console.error('Error fetching companies:', error);
334
+ }
335
+ }
336
+
337
+ function displayCompanies(companies) {
338
+ const companySelect = document.getElementById('company');
339
+ companySelect.innerHTML = '<option value="" selected>Select</option>'; // Reset the dropdown
340
+ companies.forEach(company => {
341
+ const option = document.createElement('option');
342
+ option.value = company.name;
343
+ option.textContent = company.name;
344
+ companySelect.appendChild(option);
345
+ });
346
+ }
347
+ function clearFormFields() {
348
+ document.getElementById('APIName').value = "";
349
+ document.getElementById('APIEndpoint').value = "";
350
+ document.getElementById('Auth_Bearer').value = "";
351
+ document.getElementById('Inputjson').value = "";
352
+ document.getElementById('OutputJson').value = "";
353
+ document.getElementById('Description').value = "";
354
+ }
355
+
356
+ </script>
357
+ </body>
358
+
359
+ </html>
360
+
templates/data_connectors.html ADDED
@@ -0,0 +1,624 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Data Connectors</title>
8
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
9
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
10
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/adminlte.min.css">
11
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css">
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
13
+
14
+ <style>
15
+ #add{
16
+ display: none ;
17
+ }
18
+ html,
19
+ body {
20
+ height: 90%;
21
+ margin: 0;
22
+ display: flex;
23
+ flex-direction: column;
24
+ }
25
+
26
+ body {
27
+ display: inline-flex;
28
+ flex-direction: column;
29
+ min-height: 90%;
30
+ }
31
+
32
+ .main-content {
33
+ flex: 1;
34
+ display: inline-flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ justify-content: flex-start;
38
+ padding: 30px;
39
+ }
40
+
41
+ /* .container {
42
+ margin-top: 50px;
43
+ margin-left: 320px;
44
+ max-width: 800px;
45
+ padding: 10px;
46
+ border: 1px solid #ccc;
47
+ border-radius: 5px;
48
+ background-color: #fff;
49
+ position: relative;
50
+ z-index: 1;
51
+ } */
52
+
53
+ .form-group {
54
+ margin-bottom: 20px;
55
+ }
56
+
57
+ .form-group label {
58
+ font-weight: bold;
59
+ margin-top: -10px;
60
+ margin-left:-22px;
61
+ display: block;
62
+ }
63
+
64
+ .form-group input,
65
+ .form-group select,
66
+ .form-group textarea {
67
+ width: 90%;
68
+ margin-left:-22px;
69
+ padding: 2px;
70
+ border: 1px solid #ccc;
71
+ border-radius: 4px;
72
+ }
73
+
74
+ .btn-primary {
75
+ margin-right: 10px;
76
+ color: white;
77
+ font-size: 16px;
78
+ font-weight: bold;
79
+ }
80
+
81
+ /* .btn-container {
82
+ text-align: center;
83
+ margin-top: 20px;
84
+ margin-bottom: 10px;
85
+ } */
86
+ .btn-primary {
87
+ margin-right: 10px;
88
+ color: white;
89
+ font-size: 16px;
90
+ font-weight: bold;
91
+ }
92
+
93
+
94
+ .btn-container {
95
+ text-align: center;
96
+ margin-top: 30px;
97
+ margin-left: 20px;
98
+ margin-right: 0px;
99
+ margin-bottom: 10px;
100
+ /* color: white; */
101
+ }
102
+
103
+ .btn-container1 {
104
+ text-align: center;
105
+ margin-top: 50px;
106
+ margin-left: 30px;
107
+ margin-right: 30px;
108
+ margin-bottom: 10px;
109
+ color: white;
110
+ }
111
+
112
+ /* #selectedTables,
113
+ #labelselected {
114
+ display: none;
115
+ } */
116
+ .btn-primary:focus,
117
+ .btn-primary:active {
118
+ color: white;
119
+ background-color: #007bff;
120
+ border-color: #007bff;
121
+ box-shadow: none;
122
+ }
123
+
124
+ #saveBtn1 {
125
+
126
+ margin: 0 auto;
127
+ }
128
+
129
+ /* footer {
130
+ position: relative;
131
+ margin-top: auto;
132
+ width: 100%;
133
+ color: black;
134
+ text-align: right;
135
+ padding-right: 245px;
136
+ padding-top: 20px;
137
+ background-color: #f8f9fa;
138
+ border: none !important;
139
+ }
140
+ */
141
+ .small-select {
142
+ margin-top: 5px;
143
+ width: 200px;
144
+ /* Adjust the width as needed */
145
+ }
146
+
147
+ .custom-dropdown {
148
+ width: 250px;
149
+ /* Adjust the width as needed */
150
+ }
151
+ /* Ensure the new row aligns with the previous row */
152
+ #schema-table-section {
153
+
154
+ margin-left: -20px; /* Adjust this if you need spacing between rows */
155
+ padding-top: 5px; /* Adjust padding if needed */
156
+ }
157
+
158
+ .alert {
159
+ position: relative;
160
+ padding: 15px;
161
+ margin-bottom: 20px;
162
+ border: 1px solid transparent;
163
+ border-radius: 4px;
164
+ }
165
+
166
+ .alert-success {
167
+ color: #3c763d;
168
+ background-color: #dff0d8;
169
+ border-color: #d6e9c6;
170
+ }
171
+
172
+ .alert-danger {
173
+ color: #a94442;
174
+ background-color: #f2dede;
175
+ border-color: #ebccd1;
176
+ }
177
+
178
+ .close {
179
+ position: absolute;
180
+ bottom: 10px;
181
+ right: 10px;
182
+ border: none;
183
+ background: none;
184
+ font-size: 16px;
185
+ cursor: pointer;
186
+ }
187
+
188
+
189
+ </style>
190
+ </head>
191
+
192
+ <body>
193
+ {% include 'sidepane.html' %}
194
+ <div class="wrapper">
195
+ <div class="main-header" style="border-bottom: none;">
196
+ <!-- Content Header (Page header) -->
197
+ <div class="content-header">
198
+ <div class="container-fluid">
199
+ <div class="container mt-2">
200
+ <!-- <div class="form-group left-align">
201
+ <label for="company" class="mr-1" style="margin-left:-60px;margin-top:-1px;">Company Name <span class="text-danger">*</span></label>
202
+ <select type="text" id="company" name="company" class="form-control "style="width: 20%;margin-left:-60px;margin-bottom:-35px" required>
203
+ <option value="" selected>Select</option>
204
+ </select>
205
+ </div> -->
206
+ <div class="row">
207
+ <div id="message-container" style="padding:10px 10px;margin-left: 150px;width:500px;margin-bottom:-20px; margin-top: -30px;"></div>
208
+ </div>
209
+ </div>
210
+ </div>
211
+ </div>
212
+
213
+ <form id="databaseconnectorForm" class="needs-validation" novalidate action="/save_data_connectors"
214
+ method="post" >
215
+ <div class="form-group">
216
+ <!-- <label for="company_id">company_id</label>--->
217
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
218
+ </div>
219
+ <h4 id="selectedCompany" style="margin-left: 300px;margin-bottom: 50px;margin-top: -50px;"></h4>
220
+ <div class="row">
221
+ <div class="col-md-3">
222
+ <div class="form-group">
223
+ <label for="database">Database Type<span class="text-danger">*</span></label>
224
+ <select type="text" id="database" name="database" class="form-control" required>
225
+ <option value="" selected>Select</option>
226
+ <option value="Postgres">Postgres</option>
227
+ <option value="mysql">mysql</option>
228
+ </select>
229
+ </div>
230
+ </div>
231
+ <div class="col-md-3">
232
+ <div class="form-group">
233
+ <label for="server">Server IP <span class="text-danger">*</span></label>
234
+ <input type="text" id="server" name="server" class="form-control" required>
235
+ </div>
236
+ </div>
237
+ <div class="col-md-3">
238
+ <div class="form-group">
239
+ <label for="port">Port <span class="text-danger">*</span></label>
240
+ <input type="text" id="port" name="port" class="form-control" required>
241
+ </div>
242
+ </div>
243
+ <div class="col-md-3">
244
+ <div class="form-group">
245
+ <label for="databaseName">Database Name <span class="text-danger">*</span></label>
246
+ <input type="text" id="databaseName" name="databaseName" class="form-control" required>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ <div class="row">
251
+ <div class="col-md-3">
252
+ <div class="form-group">
253
+ <label for="userame">UserName <span class="text-danger">*</span></label>
254
+ <input type="text" id="username" name="username" class="form-control" required>
255
+ </div>
256
+ </div>
257
+ <div class="col-md-3">
258
+ <div class="form-group">
259
+ <label for="password">Password <span class="text-danger">*</span></label>
260
+ <input type="password" id="password" name="password" class="form-control" required>
261
+ </div>
262
+ </div>
263
+
264
+ <div class="col-md-6">
265
+ <div class="form-group d-flex justify-content-between">
266
+ <div class="form-group btn-container">
267
+ <button type="button" id="connectBtn" class="btn btn-primary">Connect</button>
268
+ <button type="reset" class="btn btn-primary">Clear</button>
269
+ </div>
270
+ </div>
271
+ </div>
272
+ </div>
273
+
274
+ <div id="schema-table-section" style="display: none;">
275
+ <div class="row">
276
+ <div class="col-md-3">
277
+ <div class="form-group1">
278
+ <label for="schemas">Select Schemas <span class="text-danger">*</span></label>
279
+ <select type="text" id="schemas" name="schemas" class="form-control" required>
280
+ <option value="" selected>Select</option>
281
+ <option value="schema1">Lookup</option>
282
+ <option value="schema2">Public</option>
283
+ <option value="schema3" selected>tenant_default</option>
284
+ </select>
285
+ </div>
286
+ </div>
287
+
288
+ <div class="col-md-3">
289
+ <div class="form-group1">
290
+ <label for="tableschema" style="margin-left: 30px;margin-right: 30px;">Select Tables <span
291
+ class="text-danger">*</span></label>
292
+ <div class="dropdown custom-dropdown">
293
+ <button class="btn btn-secondary dropdown-toggle"
294
+ style="margin-left: 30px;margin-right: 0px;" type="button" id="tablesDropdown"
295
+ data-bs-toggle="dropdown" aria-expanded="false">
296
+ Select Tables
297
+ </button>
298
+ <ul class="dropdown-menu" aria-labelledby="tablesDropdown">
299
+ <li>
300
+ <select type="text" id="tableschema" name="tableschema" class="form-control"
301
+ multiple required>
302
+ <option value="customer_master">customer_master</option>
303
+ <option value="efs_company_master">efs_company_master</option>
304
+ <option value="efs_group_company_master">efs_group_company_master</option>
305
+ <option value="efs_region_master">efs_region_master</option>
306
+ <option value="party_address_detail">party_address_detail</option>
307
+ <option value="wms_warehouse_master">wms_warehouse_master</option>
308
+ </select>
309
+ </li>
310
+ </ul>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ <!-- <div class="col-md-3">
315
+ <div class="btn-container1">
316
+ <button type="button" id="saveBtn" class="btn btn-primary">Save</button>
317
+ </div>
318
+ </div>
319
+ </div>
320
+ <div class="row">-->
321
+ <div class="col-md-3">
322
+ <div class="form-group1">
323
+ <label for="selectedTables" id="labelselected">Selected Tables</label>
324
+ <textarea type="text" id="selectedTables" name="selectedTables" class="form-control"
325
+ rows="4" readonly></textarea>
326
+ </div>
327
+ </div>
328
+
329
+ <div class="col-md-3">
330
+ <div class="form-group">
331
+ <div class="btn-container1">
332
+ <button type="submit" id="saveBtn" class="btn btn-primary">Save</button>
333
+ </div>
334
+ </div>
335
+ </div>
336
+ </div>
337
+ </div>
338
+ </form>
339
+ </div>
340
+ </div>
341
+ </div>
342
+ <footer class="footer">
343
+ {%include 'footer.html'%}
344
+ </footer>
345
+ <script>
346
+
347
+ document.addEventListener('DOMContentLoaded', function () {
348
+ // fetchCompanies();
349
+ // const companySelect = document.getElementById('company');
350
+ // const databaseconnectorForm = document.getElementById('databaseconnectorForm');
351
+ // database.addEventListener('change', async function () {
352
+ // $("#message-container").empty();
353
+ // });
354
+ // companySelect.addEventListener('change', async function () {
355
+ // $("#message-container").empty();
356
+ // const selectedCompanyName = companySelect.options[companySelect.selectedIndex].text;
357
+ // console.log(`Selected Company Name: ${selectedCompanyName}`);
358
+
359
+ // if (selectedCompanyName !== "Select") {
360
+ // $("#schema-table-section").hide();
361
+ // try {
362
+ // const response = await fetch(`/api/company_id?company_name=${encodeURIComponent(selectedCompanyName)}`);
363
+ // if (!response.ok) {
364
+ // throw new Error('Network response was not ok');
365
+ // }
366
+ // const data = await response.json();
367
+ // console.log(`Company ID: ${data.company_id}`);
368
+ // const companyId = data.company_id;
369
+ // document.getElementById('company_id').value = companyId;
370
+ var table = $('#databaseconnecorsform').show();
371
+ const role = sessionStorage.getItem('userRole');
372
+ const passedCompanyName=sessionStorage.getItem('company_name')
373
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
374
+ console.log('Current role:', role); // Debug statement to check the role
375
+ const storecompany_id=sessionStorage.getItem('company_id');
376
+ document.getElementById("company_id").value=storecompany_id;
377
+
378
+ data_get_from_db(storecompany_id,passedCompanyName);
379
+ });
380
+ async function data_get_from_db(storecompany_id,selectedCompanyName) {
381
+
382
+ if (storecompany_id) {
383
+ try {
384
+ const connectorsResponse = await fetch(`/api/check_data_connectors?company_id=${storecompany_id}&company_name=${selectedCompanyName}`);
385
+ if (!connectorsResponse.ok) {
386
+ throw new Error('data connector Network response was not ok');
387
+ }
388
+ const connectorsData = await connectorsResponse.json();
389
+ //setMultiSelectValues(document.getElementById('database'), connectorsData.databasetype); // Ensure this is an array
390
+ //setMultiSelectValues(document.getElementById('databaseName'), connectorsData.database_name); // Ensure this is an array
391
+ document.getElementById('database').value = connectorsData.databasetype;
392
+ document.getElementById('server').value=connectorsData.serverip; // document.getElementById('server').value = connectorsData.serverip;
393
+ document.getElementById('port').value = connectorsData.port;
394
+ document.getElementById('databaseName').value = connectorsData.database_name;
395
+ document.getElementById('username').value = connectorsData.username;
396
+ document.getElementById('password').value = connectorsData.password;
397
+ document.getElementById('selectedTables').value = connectorsData.dbtablename;
398
+ databaseconnectorForm.style.display = 'block';
399
+
400
+ } catch (error) {
401
+ document.getElementById('database').value = " ";
402
+ document.getElementById('server').value = " ";
403
+ document.getElementById('port').value = " ";
404
+ document.getElementById('databaseName').value = " ";
405
+ document.getElementById('username').value = " ";
406
+ document.getElementById('password').value = "";
407
+ document.getElementById('selectedTables').value = " ";
408
+ console.error('Error fetching data from data connectors:', error);
409
+ ("Company name does not exist. Please fill in the details.");
410
+
411
+ // Optionally, you can insert a message into the DOM
412
+ const messageContainer = document.getElementById('message-container');
413
+ if (messageContainer) {
414
+ messageContainer.innerHTML = "<div class='alert alert-danger'>Database details does not exist for this Company name.. Please fill in the details.</div>";
415
+ }
416
+
417
+
418
+ databaseconnectorForm.style.display = 'block';
419
+ }
420
+ } else {
421
+ console.log(`Company ID does not exist, you can create and save data: ${data.company_id}`);
422
+ databaseconnectorForm.style.display = 'none';
423
+ }
424
+ }
425
+
426
+ // } catch (error) {
427
+
428
+ // console.error('Error fetching company ID or data connectors:', error);
429
+ // databaseconnectorForm.style.display = 'none';
430
+ // }
431
+ // } else {
432
+ // databaseconnectorForm.style.display = 'none';
433
+ // }
434
+ // });
435
+
436
+ // document.getElementById("connectBtn").addEventListener("click", function (event) {
437
+ // var database = document.getElementById("database").value;
438
+ // var server = document.getElementById("server").value;
439
+ // var port = document.getElementById("port").value;
440
+ // var databaseName = document.getElementById("databaseName").value;
441
+ // var username = document.getElementById("username").value;
442
+ // var password = document.getElementById("password").value;
443
+
444
+ // if (!database || !server || !port || !databaseName || !username || !password) {
445
+ // alert("Please fill in all required fields.");
446
+ // return;
447
+ // }
448
+
449
+ // document.getElementById("schema-table-section").style.display = "block";
450
+ // });
451
+ $("#tableschema").change(function () {
452
+ var selectedTables = $(this).val();
453
+ var currentText = $("#selectedTables").val();
454
+ selectedTables.forEach(function (table) {
455
+ if (!currentText.includes(table)) {
456
+ if (currentText.length > 1) {
457
+ currentText += ", " + table;
458
+ } else {
459
+ currentText = table;
460
+ }
461
+ }
462
+ });
463
+ $("#selectedTables").val(currentText);
464
+ });
465
+ document.getElementById("connectBtn").addEventListener("click", function (event) {
466
+ var database = document.getElementById("database").value;
467
+ var server = document.getElementById("server").value;
468
+ var port = document.getElementById("port").value;
469
+ var databaseName = document.getElementById("databaseName").value;
470
+ var username = document.getElementById("username").value;
471
+ var password = document.getElementById("password").value || "";
472
+
473
+ if (!database || !server || !port || !databaseName || !username) {
474
+ alert("Please fill in all required fields.");
475
+ return;
476
+ }
477
+ // document.getElementById("schema-table-section").style.display = "block";
478
+ fetch("/api/connect", {
479
+ method: "POST",
480
+ headers: {
481
+ "Content-Type": "application/json"
482
+ },
483
+ body: JSON.stringify({
484
+ database_type: database,
485
+ server: server,
486
+ port: port,
487
+ databaseName: databaseName,
488
+ username: username,
489
+ password: password
490
+ })
491
+ })
492
+ .then(response => response.json())
493
+ .then(data => {
494
+ if (data.success) {
495
+ document.getElementById("schema-table-section").style.display = "block";
496
+ populateSchemaDropdown(data.schemas);
497
+ // Set default selection for tables
498
+ if (data.schemas.length > 0) {
499
+ updateTablesDropdown(data.schema_tables, data.schemas[0]);
500
+ schemas.addEventListener("change", function (event) {
501
+ var selectedSchema = event.target.value;
502
+ updateTablesDropdown(data.schema_tables, selectedSchema);
503
+ });
504
+ }
505
+ } else {
506
+ alert("Failed to connect to the database. Please check your credentials.");
507
+ document.getElementById("schema-table-section").style.display = "none";
508
+ }
509
+ })
510
+ .catch(error => {
511
+ console.error("Error:", error);
512
+ alert("An error occurred while connecting to the database.");
513
+ });
514
+ });
515
+
516
+ function populateSchemaDropdown(schemas) {
517
+ var schemaSelect = document.getElementById("schemas");
518
+ schemaSelect.innerHTML = ""; // Clear any existing options
519
+
520
+ schemas.forEach(function (schema) {
521
+ var option = document.createElement("option");
522
+ option.value = schema;
523
+ option.textContent = schema;
524
+ schemaSelect.appendChild(option);
525
+ });
526
+
527
+ }
528
+
529
+ function updateTablesDropdown(schemaTables, selectedSchema) {
530
+ var tableSchemaSelect = document.getElementById("tableschema");
531
+ tableSchemaSelect.innerHTML = ""; // Clear any existing options
532
+
533
+ if (schemaTables[selectedSchema]) {
534
+ schemaTables[selectedSchema].forEach(function (table) {
535
+ var option = document.createElement("option");
536
+ option.value = table;
537
+ option.textContent = table;
538
+ tableSchemaSelect.appendChild(option);
539
+ });
540
+ }
541
+ }
542
+
543
+ document.getElementById("saveBtn").addEventListener("click", async function (event) {
544
+ event.preventDefault(); // Prevent the default form submission
545
+
546
+ // Set the password value
547
+ //document.getElementById("password").value = "root";
548
+
549
+ const form = document.getElementById('databaseconnectorForm');
550
+ const formData = new FormData(form);
551
+ formData.append("company_id", document.getElementById('company_id').value);
552
+ try {
553
+ console.log("inside save",formData);
554
+ console.log("comaonyid", document.getElementById('company_id').value);
555
+ for (const [key, value] of formData.entries()) {
556
+ console.log(`${key}: ${value}`);
557
+ }
558
+ const response = await fetch(form.action, {
559
+ method: "POST",
560
+ body: formData
561
+ });
562
+
563
+ if (!response.ok) {
564
+ throw new Error('Network response was not ok');
565
+ }
566
+
567
+ const data = await response.json();
568
+
569
+ console.log("result", response);
570
+
571
+ const messageContainer = document.getElementById('message-container');
572
+ if (data.created) {
573
+ if (messageContainer) {
574
+ const messageType = data.created ? 'alert-success' : 'alert-danger';
575
+ messageContainer.innerHTML = `
576
+ <div class='alert ${messageType}'>
577
+ ${data.msg}
578
+ <button class='close'style='font-size:medium;margin-top:6px;'onclick='dismissMessage()'>OK</button>
579
+ </div>`;
580
+ }
581
+ }
582
+
583
+ } catch (error) {
584
+ console.error('Error saving data:', error);
585
+ const messageContainer = document.getElementById('message-container');
586
+ if (messageContainer) {
587
+ messageContainer.innerHTML = `
588
+ <div class='alert alert-danger'>
589
+ An error occurred while saving data in database.
590
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
591
+ </div>`;
592
+ }
593
+ }
594
+ });
595
+
596
+
597
+ function dismissMessage() {
598
+ const messageContainer = document.getElementById('message-container');
599
+ if (messageContainer) {
600
+ messageContainer.innerHTML = '';
601
+ }
602
+ }
603
+ function handleError() {
604
+ document.getElementById('database').value = " ";
605
+ document.getElementById('server').value = " ";
606
+ document.getElementById('port').value = " ";
607
+ document.getElementById('databaseName').value = " ";
608
+ document.getElementById('username').value = " ";
609
+ document.getElementById('password').value = " ";
610
+ }
611
+
612
+
613
+ function setMultiSelectValues(selectElement, values) {
614
+ // Ensure values is an array
615
+ if (!Array.isArray(values)) {
616
+ values = [values];
617
+ }
618
+ Array.from(selectElement.options).forEach(option => {
619
+ option.selected = values.includes(option.value);
620
+ });
621
+ }
622
+ </script>
623
+ </body>
624
+ </html>
templates/footer.html ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- footer.html -->
2
+
3
+ <!--
4
+ This is the HTML code for the footer section of a web page.
5
+ It displays the version number and copyright information.
6
+
7
+ HTML Structure:
8
+ - The footer element has a class of "main-footer".
9
+ - Inside the footer, there is a div element with classes "float-right" and "d-none d-sm-block".
10
+ - Inside the div, there is a bold tag (<b>) displaying the version number.
11
+ - After the div, there is a strong tag (<strong>) displaying the copyright information.
12
+ - The copyright information includes the year and a link to the company's website.
13
+
14
+ Example Usage:
15
+ <footer class="main-footer">
16
+ <div class="float-right d-none d-sm-block">
17
+ <b>Version</b> 3.0.5
18
+ </div>
19
+ <strong>&copy; 2023 <a href="https://yourcompany.com">Your Company</a>.</strong> All rights reserved.
20
+ </footer>
21
+
22
+ <footer class="main-footer" style="position: absolute; bottom: 0; width: 100%; color: black; text-align: right; padding-right:245px ;">
23
+ <div class="container-fluid">
24
+ <a href="https://redmindtechnologies.com" target="_blank" style="color: black; text-decoration: none;">Visit Redmind Technologies at https://redmindtechnologies.com</a>
25
+ </div>
26
+ </footer>-->
templates/index.html ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
+ <title>Sign In/Up Form</title>
8
+ <!-- Google Font -->
9
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:400,800" rel="stylesheet">
10
+ <!-- Font Awesome -->
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
12
+ <style>
13
+ * {
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ body {
18
+ background: #f6f5f7;
19
+ display: flex;
20
+ justify-content: center;
21
+ align-items: center;
22
+ flex-direction: column;
23
+ font-family: 'Montserrat', sans-serif;
24
+ height: 100vh;
25
+ margin: -20px 0 50px;
26
+ }
27
+
28
+ h1 {
29
+ font-weight: bold;
30
+ margin: 0;
31
+ }
32
+
33
+ h2 {
34
+ text-align: center;
35
+ }
36
+
37
+ p {
38
+ font-size: 14px;
39
+ font-weight: 100;
40
+ line-height: 20px;
41
+ letter-spacing: 0.5px;
42
+ margin: 20px 0 30px;
43
+ }
44
+
45
+ span {
46
+ font-size: 12px;
47
+ }
48
+
49
+ a {
50
+ color: #333;
51
+ font-size: 14px;
52
+ text-decoration: none;
53
+ margin: 15px 0;
54
+ }
55
+
56
+ button {
57
+ border-radius: 20px;
58
+ border: 1px solid #1c6bae;
59
+ background-color: #1c6bae;
60
+ color: #FFFFFF;
61
+ font-size: 12px;
62
+ font-weight: bold;
63
+ padding: 12px 45px;
64
+ margin-top: 30px;
65
+ letter-spacing: 1px;
66
+ text-transform: uppercase;
67
+ transition: transform 80ms ease-in;
68
+ }
69
+
70
+ button:active {
71
+ transform: scale(0.95);
72
+ }
73
+
74
+ button:focus {
75
+ outline: none;
76
+ }
77
+
78
+ button.ghost {
79
+ background-color: transparent;
80
+ border-color: #FFFFFF;
81
+ }
82
+
83
+ form {
84
+ /* background-color: #FFFFFF;*/
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: center;
88
+ flex-direction: column;
89
+ padding: 0 50px;
90
+ height: 100%;
91
+ text-align: center;
92
+ }
93
+
94
+ input {
95
+ background-color: #eee;
96
+ border: none;
97
+ padding: 12px 15px;
98
+ margin: 8px 0;
99
+ width: 100%;
100
+ }
101
+
102
+ .container {
103
+ background-color: #fff;
104
+ border-radius: 10px;
105
+ box-shadow: 0 14px 28px rgba(0,0,0,0.25),
106
+ 0 10px 10px rgba(0,0,0,0.22);
107
+ position: relative;
108
+ overflow: hidden;
109
+ width: 528px;
110
+ max-width: 100%;
111
+ min-height: 400px;
112
+ }
113
+
114
+ .form-container {
115
+ position: absolute;
116
+ top: 0;
117
+ height: 100%;
118
+ transition: all 0.6s ease-in-out;
119
+ }
120
+
121
+ .sign-in-container {
122
+ left: 0;
123
+ width: 50%;
124
+ z-index: 2;
125
+
126
+ }
127
+
128
+ .container.right-panel-active .sign-in-container {
129
+ transform: translateX(100%);
130
+ }
131
+
132
+ .sign-up-container {
133
+ left: 0;
134
+ width: 50%;
135
+ opacity: 0;
136
+ z-index: 1;
137
+ }
138
+
139
+ .container.right-panel-active .sign-up-container {
140
+ transform: translateX(100%);
141
+ opacity: 1;
142
+ z-index: 5;
143
+ animation: show 0.6s;
144
+ }
145
+
146
+ @keyframes show {
147
+ 0%, 49.99% {
148
+ opacity: 0;
149
+ z-index: 1;
150
+ }
151
+ 50%, 100% {
152
+ opacity: 1;
153
+ z-index: 5;
154
+ }
155
+ }
156
+
157
+ .overlay-container {
158
+ position: absolute;
159
+ top: 0;
160
+ left: 50%;
161
+ width: 50%;
162
+ height: 100%;
163
+ overflow: hidden;
164
+ transition: transform 0.6s ease-in-out;
165
+ z-index: 100;
166
+ }
167
+
168
+ .container.right-panel-active .overlay-container {
169
+ transform: translateX(-100%);
170
+ }
171
+
172
+ .overlay {
173
+ background: #FF416C;
174
+ background: -webkit-linear-gradient(to right,#1c6bae, #1c6bae);
175
+ background: linear-gradient(to right, #1c6bae, #1c6bae);
176
+ background-repeat: no-repeat;
177
+ background-size: cover;
178
+ background-position: 0 0;
179
+ color: #FFFFFF;
180
+ position: relative;
181
+ left: -100%;
182
+ height: 100%;
183
+ width: 200%;
184
+ transform: translateX(0);
185
+ transition: transform 0.6s ease-in-out;
186
+ }
187
+
188
+ .container.right-panel-active .overlay {
189
+ transform: translateX(50%);
190
+ }
191
+
192
+ .overlay-panel {
193
+ position: absolute;
194
+ display: flex;
195
+ align-items: center;
196
+ justify-content: center;
197
+ flex-direction: column;
198
+ padding: 0 40px;
199
+ text-align: center;
200
+ top: 0;
201
+ height: 100%;
202
+ width: 50%;
203
+ transform: translateX(0);
204
+ transition: transform 0.6s ease-in-out;
205
+ }
206
+
207
+ .overlay-left {
208
+ transform: translateX(-20%);
209
+ }
210
+
211
+ .container.right-panel-active .overlay-left {
212
+ transform: translateX(0);
213
+ }
214
+
215
+ .overlay-right {
216
+ right: 0;
217
+ transform: translateX(0);
218
+ }
219
+
220
+ .container.right-panel-active .overlay-right {
221
+ transform: translateX(20%);
222
+ }
223
+
224
+ .social-container {
225
+ margin: 20px 0;
226
+ }
227
+
228
+ .social-container a {
229
+ border: 1px solid #DDDDDD;
230
+ border-radius: 50%;
231
+ display: inline-flex;
232
+ justify-content: center;
233
+ align-items: center;
234
+ margin: 0 5px;
235
+ height: 40px;
236
+ width: 40px;
237
+ }
238
+
239
+ /* Styling the logo inside a circle */
240
+ .logo-container {
241
+ display: flex;
242
+ justify-content: center;
243
+ align-items: center;
244
+ margin-bottom: 20px; /* Add spacing between logo and text */
245
+ }
246
+
247
+ .logo {
248
+ border-radius: 50%; /* Make the image circular */
249
+ background-color: white; /* White background for the circle */
250
+ padding: 20px; /* Adjust the padding to create the circle effect */
251
+ width: 200px; /* Adjust size as needed */
252
+ height: 200px; /* Adjust size as needed */
253
+ object-fit: contain; /* Keep the image aspect ratio */
254
+ }
255
+
256
+
257
+ footer {
258
+ background-color: #222;
259
+ color: #fff;
260
+ font-size: 14px;
261
+ bottom: 0;
262
+ position: fixed;
263
+ left: 0;
264
+ right: 0;
265
+ text-align: center;
266
+ z-index: 999;
267
+ }
268
+
269
+ footer p {
270
+ margin: 10px 0;
271
+ }
272
+
273
+ footer i {
274
+ color: red;
275
+ }
276
+
277
+ footer a {
278
+ color: #3c97bf;
279
+ text-decoration: none;
280
+ }
281
+ </style>
282
+ </head>
283
+ <body class="hold-transition login-page" style="background-image: url('static/img/AI.jpg'); background-size: cover;">
284
+ <!-- <h2>Weekly Coding Challenge #1: Sign in/up Form</h2> -->
285
+ <form action='/validate-user' name='loginForm' method="post" onsubmit="return validateForm()">
286
+ <div class="container" id="container">
287
+ <div class="form-container sign-up-container">
288
+
289
+ <h1>Create Account</h1>
290
+ <div class="social-container">
291
+ <a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
292
+ <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
293
+ <a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
294
+ </div>
295
+ <span>or use your email for registration</span>
296
+ <input type="text" placeholder="Name" />
297
+ <input type="password" placeholder="Password" />
298
+ <button>Sign Up</button>
299
+ </form>
300
+ </div>
301
+ <div class="form-container sign-in-container">
302
+
303
+ <h1>Sign in</h1>
304
+ <div class="social-container">
305
+ <a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
306
+ <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
307
+ <a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
308
+ </div>
309
+ <span>or use your account</span>
310
+ <input type="text" name="username" placeholder="Username" />
311
+ <input type="password" name="password" placeholder="Password" />
312
+ <a href="#">Forgot your password?</a>
313
+ <button type="submit">Sign In</button>
314
+ </form>
315
+ </div>
316
+ <div class="overlay-container">
317
+ <div class="overlay">
318
+ <div class="overlay-panel overlay-left">
319
+ <h1>Welcome Back!</h1>
320
+ <p>To keep connected with us please login with your personal info</p>
321
+ <button type="submit" class="ghost" id="signIn">Sign In</button>
322
+ </div>
323
+ <div class="overlay-panel overlay-right">
324
+ <div class="logo-container">
325
+ <img src="/static/img/redmindlogo3.jpg" alt="Logo" class="logo">
326
+ </div>
327
+ <h1>RedMindGPT</h1>
328
+ <p> Start Journey With Us</p>
329
+ <button class="ghost" id="signUp">Sign Up</button>
330
+ </div>
331
+ </div>
332
+ </div>
333
+ </div>
334
+
335
+ <footer>
336
+ <p>
337
+ Created with <i class="fa fa-heart"></i> by RedMind Technologies</p>
338
+ </footer>
339
+
340
+
341
+
342
+ <!-- jQuery -->
343
+ </form>
344
+ <script>
345
+ function validateForm() {
346
+ //alert("Validating form");
347
+ var username = document.forms["loginForm"]["username"].value;
348
+ var password = document.forms["loginForm"]["password"].value;
349
+ if (username == "" || password == "") {
350
+ alert("Username and Password must be filled out");
351
+ return false;
352
+ }
353
+
354
+ }
355
+
356
+ </script>
357
+
358
+ </body>
359
+ </html>
templates/knowledgebase.html ADDED
@@ -0,0 +1,710 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <title>Knowledge Base</title>
6
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
8
+ <!-- Include AdminLTE CSS -->
9
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/adminlte.min.css">
10
+ <!-- Include DataTables CSS -->
11
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css">
12
+ <!-- Include AdminLTE JS -->
13
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/adminlte.min.js"></script>
14
+ <!-- Include DataTables JS -->
15
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
16
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
17
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
18
+ <style>
19
+ body {
20
+ background-color: transparent !important;
21
+ }
22
+
23
+ .content-wrapper {
24
+ flex: 1;
25
+ overflow-y: auto;
26
+ }
27
+
28
+ .wrapper {
29
+ display: flex;
30
+ flex-direction: column;
31
+ height: 100vh;
32
+ }
33
+
34
+
35
+ .modal-content {
36
+ background-color: #fff;
37
+ }
38
+
39
+ .content-header {
40
+ padding: 1rem;
41
+ }
42
+
43
+ h1 {
44
+ text-align: center;
45
+ margin-bottom: 30px;
46
+ }
47
+
48
+ .card {
49
+ padding: 0;
50
+ margin-top: -15px;
51
+ margin-left: -40px;
52
+ }
53
+
54
+ .table-responsive {
55
+ width: 100%;
56
+ overflow-x: auto;
57
+ /*overflow-y: scroll;*/
58
+ /* Allows horizontal scrolling if necessary */
59
+ }
60
+
61
+ .table,
62
+ .table-bordered {
63
+ width: 100%;
64
+ border-collapse: collapse;
65
+ margin-right: 7.5px;
66
+ }
67
+
68
+
69
+ .text-wrap {
70
+ white-space: normal !important;
71
+ word-break: break-word;
72
+ }
73
+
74
+ div.dataTables_wrapper div.dataTables_length select {
75
+ width: 60px;
76
+ display: inline-block;
77
+ }
78
+
79
+ th {
80
+ white-space: nowrap;
81
+ }
82
+
83
+ th:nth-child(1),
84
+ td:nth-child(1) {
85
+ /* Sno column */
86
+ width: 2%;
87
+ }
88
+
89
+ th:nth-child(2),
90
+ td:nth-child(2) {
91
+ /* Document Name column */
92
+ width: auto;
93
+ }
94
+
95
+ th:nth-child(3),
96
+ td:nth-child(3) {
97
+ /* Document Description column */
98
+ width: auto;
99
+ }
100
+
101
+ th:nth-child(4),
102
+ td:nth-child(4) {
103
+ /* Document Version column */
104
+ width: 20%;
105
+ }
106
+
107
+ th:nth-child(5),
108
+ td:nth-child(5) {
109
+ /* VectorDB Flag column */
110
+ width: auto;
111
+ }
112
+
113
+ th:nth-child(6),
114
+ td:nth-child(6) {
115
+ /* View column */
116
+ width: 10%;
117
+ }
118
+
119
+ th:nth-child(7),
120
+ td:nth-child(7) {
121
+ /* Edit column */
122
+ width: 10%;
123
+ }
124
+
125
+ th:nth-child(8),
126
+ td:nth-child(8) {
127
+ /* Delete column */
128
+ width: auto;
129
+ }
130
+
131
+ .alert {
132
+ position: relative;
133
+ padding: 15px;
134
+ margin-bottom: 20px;
135
+ border: 1px solid transparent;
136
+ border-radius: 4px;
137
+ }
138
+
139
+ .alert-success {
140
+ color: #3c763d;
141
+ background-color: #dff0d8;
142
+ border-color: #d6e9c6;
143
+ }
144
+
145
+ .alert-danger {
146
+ color: #a94442;
147
+ background-color: #f2dede;
148
+ border-color: #ebccd1;
149
+ }
150
+
151
+ /* .close {
152
+ position: absolute;
153
+ bottom: 10px;
154
+ right: 10px;
155
+ border: none;
156
+ background: none;
157
+ font-size: 16px;
158
+ cursor: pointer;
159
+ } */
160
+ </style>
161
+ </head>
162
+
163
+ <body>
164
+ {% include 'sidepane.html' %}
165
+ <div class="wrapper">
166
+ <div class="main-header" style="border-bottom: none;">
167
+ <div class="container mt-2">
168
+ <div id="company-select" class="form-group left-align">
169
+ <!-- <label for="company" class="mr-1" style="margin-left:-40px; margin-top: 12px;">Company Name <span class="text-danger">*</span></label>
170
+ <select type="text" id="company" name="company" class="form-control" style="width:20%;margin-left:-40px;"required>
171
+ <option value="" selected>Select</option>
172
+ </select> -->
173
+ <!-- <div class="col-12 d-flex justify-content-end mb-3">
174
+ <button class="btn btn-primary" style="margin-top:10px;margin-right: -10px;position: fixed;"
175
+ id="add" data-action="add">Add</button>
176
+ </div> -->
177
+ </div>
178
+ </div>
179
+ <div class="row">
180
+ <div id="message-container" style="margin-left: 200px;width:600px;"></div>
181
+ </div>
182
+ <h3 id="company_name" style="margin-left: 400px;">{{company_name}}</h3>
183
+ <section class="content" id="contentSection" style="display: none;">
184
+ <div class="container-fluid">
185
+ <div>
186
+ <div class="form-group">
187
+ <!-- <label for="company_id">company_id</label>--->
188
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
189
+ </div>
190
+ <h4 id="selectedCompany" style="margin-left: 300px;"></h4>
191
+ <div class="row" style="margin-top: 50px;">
192
+ <div class="col-12">
193
+ <div class="card">
194
+ <div id="message-container">
195
+ <div class="card-body table-container">
196
+ <table id="knowledgeTable" class="table table-bordered table-striped">
197
+ <thead>
198
+ <tr>
199
+
200
+ <th>Sno</th>
201
+ <th>Document Name</th>
202
+ <th>Document Description</th>
203
+ <th>Document Version</th>
204
+ <th>VectorDB Flag</th>
205
+ <th>View</th>
206
+ <th>Edit</th>
207
+ <th>Delete</th>
208
+ <!-- <th style="display:none;">Company ID</th> -->
209
+ </tr>
210
+ </thead>
211
+ <tbody>
212
+
213
+ </tbody>
214
+ </table>
215
+ </div>
216
+ </div>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </section>
221
+ </div>
222
+
223
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
224
+ aria-hidden="true">
225
+ <div class="modal-dialog" role="document">
226
+ <div class="modal-content">
227
+ <div class="modal-header">
228
+ <h5 class="modal-title" id="addModalLabel">Add Document Details</h5>
229
+ <button type="button" class="btn-close" data-dismiss="modal">
230
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false"></span>
231
+ </button>
232
+ </div>
233
+ <div class="modal-body">
234
+ <div class="form-group">
235
+ <!-- <label for="company_id">company_id</label>--->
236
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
237
+ </div>
238
+ <form id="documentForm">
239
+ <div class="form-group">
240
+ <label for="uploadFile">Upload File<span class="text-danger">*</span></label>
241
+ <span id="file-name"></span>
242
+ <input type="hidden" id="file_name" name="file_name" class="form-control" required>
243
+ <input type="file" class="form-control-file" id="uploadFile" name="uploadFile" required
244
+ accept=".pdf,.doc,.docx">
245
+ <small class="form-text text-muted">Accepted formats: .pdf, .doc, .docx</small>
246
+ </div>
247
+ <div class="form-group">
248
+ <label for="documentName">Document Name<span class="text-danger">*</span></label>
249
+ <input type="text" class="form-control" id="documentName" name="documentName" required>
250
+ </div>
251
+ <div class="form-group">
252
+ <label for="documentDescription">Document Description<span
253
+ class="text-danger">*</span></label>
254
+ <textarea class="form-control" id="documentDescription" name="documentDescription"
255
+ rows="3" required></textarea>
256
+ </div>
257
+ <div class="form-group">
258
+ <label for="department">Department<span class="text-danger">*</span></label>
259
+ <input type="text" class="form-control" id="department" name="department" required>
260
+ </div>
261
+ <div class="form-group">
262
+ <label for="version">Version<span class="text-danger">*</span></label>
263
+ <input type="text" class="form-control" id="version" name="version" required>
264
+ </div>
265
+ <div class="form-group">
266
+ <label for="lastUpdated">Last Updated<span class="text-danger">*</span></label>
267
+ <input type="text" class="form-control" id="lastUpdated" name="lastUpdated" required>
268
+ </div>
269
+ </form>
270
+ </div>
271
+ <div class="modal-footer">
272
+ <!-- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> -->
273
+ <button type="button" id="saveupdate" class="btn btn-primary"
274
+ style="display: none;">Update</button>
275
+ <button type="button" id="save" onclick="save_file()" class="btn btn-primary">Save</button>
276
+ </div>
277
+ </div>
278
+ </div>
279
+ </div>
280
+ </div>
281
+
282
+ {%include 'footer.html'%}
283
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
284
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
285
+
286
+ <script>
287
+ var table = $('#knowledgeTable').DataTable();
288
+ const role = sessionStorage.getItem('userRole');
289
+ const company_name=sessionStorage.getItem('company_name');
290
+ console.log("company_name",company_name);
291
+ // document.getElementById('company_name').textContent = company_name;
292
+
293
+ document.addEventListener("DOMContentLoaded", function () {
294
+ now = new Date().toISOString().replace('T', ' ').substr(0, 19);
295
+ document.getElementById('lastUpdated').value = now;
296
+ const inputs = document.querySelectorAll("#documentForm input, textarea");
297
+ inputs.forEach((input, index) => {
298
+ input.addEventListener("keydown", function (event) {
299
+ if (event.key === "Enter") {
300
+ event.preventDefault();
301
+ moveToNextInput(inputs, index);
302
+ }
303
+ });
304
+ });
305
+
306
+ const passedCompanyName=sessionStorage.getItem('company_name')
307
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
308
+ console.log('Current role:', role); // Debug statement to check the role
309
+ const company_id=sessionStorage.getItem('company_id');
310
+ document.getElementById("company_id").value=company_id;
311
+ console.log("inside knowledgebaae sessionstorage",company_id);
312
+ data_get_from_db(company_id);
313
+
314
+
315
+
316
+
317
+ const companySelect = document.getElementById('company');
318
+ const documentForm = document.getElementById('documentForm');
319
+
320
+
321
+ });
322
+ function moveToNextInput(inputs, currentIndex) {
323
+ const nextInput = inputs[currentIndex + 1];
324
+ if (nextInput) {
325
+ nextInput.focus();
326
+ } else {
327
+ // Optionally, submit the form or trigger the save button
328
+ document.getElementById("save").focus();
329
+ }
330
+ }
331
+
332
+ async function data_get_from_db(company_id) {
333
+ if (company_id) {
334
+ try {
335
+ const Response = await fetch(`/api/document_upload?company_id=${company_id}`);
336
+ console.log("responce from api :==> ", Response)
337
+ const connectorsResponse = await Response.json();
338
+ console.log("knowledge data table after connecting to table", connectorsResponse);
339
+ const table = $('#knowledgeTable').DataTable(); // Initialize DataTable at the start
340
+ table.clear();
341
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
342
+ // displayEmptyTable();
343
+ displayErrorMessage("Document details do not exist for this company. Please fill in the details.");
344
+ contentSection.style.display = 'none';
345
+ } else {
346
+ console.log('company data retrived succesfully ! .........')
347
+ connectorsResponse.forEach((company, index) => {
348
+ table.row.add([
349
+ index + 1,
350
+ company.document_name,
351
+ company.document_desc,
352
+ company.version,
353
+ company.vectorDBflag,
354
+ `<a href='#' class='btn btn-info btn-sm'data-kid-id='${company.row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`,
355
+ `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${company.row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`,
356
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
357
+ company.row_id
358
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>",
359
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
360
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
361
+ ]).draw(false);
362
+ });
363
+ contentSection.style.display = 'block';
364
+ }
365
+ } catch (error) {
366
+ console.error('Error fetching company documents:', error);
367
+ //displayEmptyTable();
368
+
369
+ displayErrorMessage("Document details1 do not exist for this company. Please fill in the details.");
370
+ contentSection.style.display = 'none';
371
+ }
372
+ } else {
373
+ // displayEmptyTable();
374
+
375
+ displayErrorMessage("Details for knowledgebase do not exist for this company. Please fill in the details.");
376
+ }
377
+
378
+ }
379
+
380
+ function displayErrorMessage(message) {
381
+ const messageContainer = document.getElementById('message-container');
382
+ if (messageContainer) {
383
+ messageContainer.innerHTML = `<div class='alert alert-danger'>${message}</div>`;
384
+ }
385
+ }
386
+
387
+
388
+
389
+ function clearFormFields() {
390
+ document.getElementById('file-name').textContent = ""
391
+ document.getElementById('uploadFile').value = "";
392
+ document.getElementById('documentName').value = "";
393
+ document.getElementById('documentDescription').value = "";
394
+ document.getElementById('department').value = "";
395
+ document.getElementById('version').value = "";
396
+ // document.getElementById('lastUpdated').value = "";
397
+ }
398
+
399
+
400
+ $(document).ready(function () {
401
+ // Show modal function
402
+ $('#add').on('click', function () {
403
+ $('#documentName').removeAttr('readonly');
404
+ $('#documentDescription').removeAttr('readonly');
405
+ $('#department').removeAttr('readonly');
406
+ $('#version').removeAttr('readonly');
407
+ $('#lastUpdated').removeAttr('readonly');
408
+ const modalTitle = document.getElementById('addModalLabel');
409
+ modalTitle.textContent = 'Add Document Details';
410
+ $('#save').show();
411
+ $('#uploadFile').show();
412
+ $('#saveupdate').hide();
413
+ clearFormFields();
414
+ $('#message-container').empty(); // Clear the message container
415
+ $('#addModal').modal('show');
416
+ });
417
+ $('.modal-footer .btn-secondary, .modal-header .btn-close').on('click', function () {
418
+ $('#addModal').modal('hide');
419
+ });
420
+ // $('#knowledgeTable').DataTable({
421
+ // autoWidth: false
422
+ // });
423
+
424
+ });
425
+ function viewCompany(button) {
426
+ var companyId = $(button).data('kid-id');
427
+ const modalTitle = document.getElementById('addModalLabel');
428
+ modalTitle.textContent = 'View Document Details';
429
+ if(companyId)
430
+ {
431
+ $.getJSON(`/api/getknowledgebase/${companyId}`, function (company) {
432
+ $('#uploadFile').hide();
433
+ $('#file-name').text(company.file_path).attr('readonly', 'readonly');
434
+ $('#documentName').val(company.document_name).attr('readonly', 'readonly');
435
+ $('#documentDescription').val(company.document_desc).attr('readonly', 'readonly');
436
+ $('#department').val(company.department).attr('readonly', 'readonly');
437
+ $('#version').val(company.version).attr('readonly', 'readonly');
438
+ //$('#lastUpdated').val(company.last_updated).attr('readonly', 'readonly');
439
+ var lastUpdated = company.last_updated;
440
+ $('#lastUpdated').val(lastUpdated).attr('readonly', 'readonly');
441
+ $('#save').hide();// Disable the "Save" button when the modal opens
442
+ $('#addModal').modal('show');
443
+ }).fail(function () {
444
+ alert("Error retrieving knowledge base check the sidepane working.");
445
+ });
446
+ }
447
+ }
448
+
449
+ // Edit knowledge base details
450
+ function editCompany(button) {
451
+ var companyId = $(button).data('kid-id');
452
+
453
+ const modalTitle = document.getElementById('addModalLabel');
454
+ modalTitle.textContent = 'Edit Document Details';
455
+
456
+ // Fetch company details by ID
457
+ if(companyId)
458
+ {
459
+ $.getJSON(`/api/getknowledgebase/${companyId}`, function (company) {
460
+
461
+ const fileName = company.file_path.split('/').pop();
462
+ const fileContent = new Blob([""], { type: 'text/plain' });
463
+ const file = new File([fileContent], fileName, { type: fileContent.type });
464
+ const dataTransfer = new DataTransfer();
465
+ dataTransfer.items.add(file);
466
+
467
+ // Set the file input's files property to the created file
468
+ const fileInput = document.getElementById('uploadFile');
469
+ fileInput.files = dataTransfer.files;
470
+
471
+ // Check if the input element is of type 'file'
472
+ if (fileInput.type === 'file') {
473
+ console.log("The input is of type 'file'.");
474
+ } else {
475
+ console.log("The input is NOT of type 'file'.");
476
+ }
477
+
478
+ // Check if the value is of type 'File'
479
+ const files = fileInput.files;
480
+ if (files.length > 0 && files[0] instanceof File) {
481
+ console.log("The value is of type 'File':", files[0].name);
482
+ } else {
483
+ console.log("No file is selected or the value is not of type 'File'.");
484
+ }
485
+
486
+ $('#uploadFileLabel').text(files[0].name);
487
+ $('#uploadFile').text(files[0].name)
488
+ $('#documentName').val(company.document_name);
489
+ $('#documentDescription').val(company.document_desc);
490
+ $('#department').val(company.department);
491
+ $('#version').val(company.version);
492
+ $('#lastUpdated').val(company.last_updated).attr('readonly', 'readonly');
493
+ $('#company_id').val(company.company_id);
494
+
495
+ // Show/hide appropriate elements
496
+ $('#uploadFile').show(); // Hide the file upload field
497
+ $('#save').hide(); // Hide the default save button
498
+ $('#saveupdate').show(); // Show the update button
499
+
500
+ // Ensure fields are editable
501
+ $('#documentName').removeAttr('readonly');
502
+ $('#documentDescription').removeAttr('readonly');
503
+ $('#department').removeAttr('readonly');
504
+ $('#version').removeAttr('readonly');
505
+ // $('#lastUpdated').removeAttr('readonly');
506
+ $('#company_id').val(company.company_id); // Ensure company_id is included if necessary
507
+
508
+ // Show the modal
509
+ $('#addModal').modal('show');
510
+
511
+ // Set up the click event for the update button
512
+ $('#saveupdate').off('click').on('click', function () {
513
+ saveupdate(companyId, files[0].name); // Pass the company ID for updating
514
+ });
515
+ }).fail(function () {
516
+ alert("Error retrieving knowledge base error 2 details.");
517
+ });
518
+ }
519
+ }
520
+
521
+ // Delete company
522
+ function deleteCompany(button) {
523
+ var companyId = $(button).data('kid-id');
524
+ console.log("k_id deleted", companyId);
525
+ $.ajax({
526
+ type: "DELETE",
527
+ url: `/api/delknowledgebase/${companyId}`,
528
+ success: function () {
529
+ var table = $('#knowledgeTable').DataTable();
530
+ table.row($(button).closest('tr')).remove().draw();
531
+ //alert("Company deleted successfully.");
532
+ const messageContainer = document.getElementById('message-container');
533
+ if (messageContainer)
534
+ messageContainer.innerHTML = `
535
+ <div class='alert alert-danger'>
536
+ Prompt details deleted successfully
537
+ <button class='close' onclick='dismissMessage()'>OK</button>
538
+ </div>`;
539
+ // fetchCompanies(); // Refresh the table
540
+ },
541
+ error: function (xhr) {
542
+ alert("Error deleting company: " + xhr.responseJSON.detail);
543
+ }
544
+ });
545
+ }
546
+ function saveupdate(companyId, filename) {
547
+ const formData = new FormData();
548
+ const fileInput = document.getElementById("uploadFile");
549
+ const uploadFile = fileInput.files[0]; // Get the file object
550
+ const company_id = document.getElementById("company_id").value;
551
+ formData.append("company_id", $('#company_id').val());
552
+ formData.append("documentName", $('#documentName').val());
553
+ formData.append("documentDescription", $('#documentDescription').val());
554
+ formData.append("department", $('#department').val());
555
+ formData.append("version", $('#version').val());
556
+ formData.append("vectorDBFlag", 'NO');
557
+ formData.append("lastUpdated", $('#lastUpdated').val());
558
+ console.log("company_id to table refresh", company_id)
559
+ // Append the file only if it exists, otherwise, append the filename
560
+ if (uploadFile) {
561
+ formData.append("file_path", uploadFile); // Append the file object
562
+ } else {
563
+ formData.append("file_path", filename); // Append the existing filename
564
+ }
565
+
566
+ $.ajax({
567
+ url: `/api/putknowledgebase/${companyId}`,
568
+ type: 'PUT',
569
+ data: formData,
570
+ processData: false, // Required for FormData
571
+ contentType: false, // Required for FormData
572
+ success: function (response) {
573
+ // alert('Knowledgebase details updated successfully.');
574
+ const messageContainer = document.getElementById('message-container');
575
+ if (messageContainer)
576
+ messageContainer.innerHTML = `
577
+ <div class='alert alert-success'>
578
+ Data saved successfully
579
+ <button class='close' onclick='dismissMessage()'>OK</button>
580
+ </div>`;
581
+ $('#addModal').modal('hide'); // Close the modal after saving
582
+ fetchUpdatedDocuments(company_id);
583
+ },
584
+ error: function () {
585
+ alert('Form has no changes to update knowledge base details.');
586
+ }
587
+ });
588
+ }
589
+
590
+ async function fetchUpdatedDocuments(company_id) {
591
+ console.log("company_id", company_id);
592
+ var table = $('#knowledgeTable').DataTable();
593
+ const Response = await fetch(`/api/document_update?company_id=${company_id}`);
594
+ const connectorsResponse = await Response.json();
595
+ console.log("knowledge data table after connecting to table", connectorsResponse);
596
+ table.clear();
597
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
598
+ //displayEmptyTable();
599
+
600
+ displayErrorMessage("Document details do not exist for this company. Please fill in the details.");
601
+ contentSection.style.display = 'none';
602
+ } else {
603
+
604
+ connectorsResponse.forEach((company, index) => {
605
+ table.row.add([
606
+ index + 1,
607
+ company.document_name,
608
+ company.document_desc,
609
+ company.version,
610
+ company.vectorDBflag,
611
+ `<a href='#' class='btn btn-info btn-sm'data-kid-id='${company.row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`,
612
+ `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${company.row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`,
613
+ //`<a href='#' class='btn btn-danger btn-sm' onclick='deleteCompany(${company.company_id})'><i class='fas fa-trash'></i></a>`,
614
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
615
+ company.row_id
616
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>",
617
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
618
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
619
+ ]).draw(false);
620
+ });
621
+ contentSection.style.display = 'block';
622
+ }
623
+ }
624
+
625
+ function save_file() {
626
+ const form = document.getElementById('documentForm');
627
+
628
+ // Check if the form is valid
629
+ if (!form.checkValidity()) {
630
+ // If the form is invalid, show validation messages and stop the submission
631
+ form.reportValidity();
632
+ return;
633
+ }
634
+ const uploadFile = document.getElementById("uploadFile").files[0];
635
+ const documentName = document.getElementById("documentName").value;
636
+ const documentDescription = document.getElementById("documentDescription").value;
637
+ const department = document.getElementById("department").value;
638
+ const version = document.getElementById("version").value;
639
+ const lastUpdated = document.getElementById("lastUpdated").value;
640
+ const company_id = document.getElementById("company_id").value;
641
+
642
+ //const formData = new FormData();
643
+ var formData = new FormData($('#documentForm')[0]);
644
+ const vectorDBFlag = "NO"; // Example value
645
+ // const view = "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>";
646
+ // const edit = "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>";
647
+ // const dele= "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></a>";
648
+
649
+
650
+ formData.append("uploadFile", uploadFile);
651
+ formData.append("documentName", documentName);
652
+ formData.append("documentDescription", documentDescription);
653
+ formData.append("department", department);
654
+ formData.append("version", version);
655
+ formData.append("lastUpdated", lastUpdated);
656
+ formData.append("vectorDBflag", vectorDBFlag);
657
+ formData.append("company_id", company_id);
658
+ console.log("formdata",formData);
659
+ fetch('/upload_document', {
660
+ method: 'POST',
661
+ body: formData
662
+ })
663
+ .then(response => {
664
+ if (!response.ok) {
665
+ throw new Error('Network response was not ok');
666
+ }
667
+ return response.json();
668
+ })
669
+ .then(data => {
670
+ const row_id=data.row_id;
671
+ var table = $('#knowledgeTable').DataTable();
672
+ var rowCount = table.rows().count();
673
+ const view=`<a href='#' class='btn btn-info btn-sm'data-kid-id='${row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`;
674
+ const edit=`<a href='#' class='btn btn-warning btn-sm'data-kid-id='${row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`;
675
+ const dele= `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`;
676
+ table.row.add([
677
+ rowCount + 1,
678
+ documentName,
679
+ documentDescription,
680
+ version,
681
+ vectorDBFlag,
682
+ view,
683
+ edit,
684
+ dele
685
+ ]).draw(false);
686
+
687
+ const messageContainer = document.getElementById('message-container');
688
+ if(messageContainer)
689
+ messageContainer.innerHTML = `
690
+ <div class='alert alert-success'>
691
+ Knowledgebase Data saved successfully
692
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
693
+ </div>`;
694
+ // alert('Document saved successfully');
695
+ $('#addModal').modal('hide');
696
+ document.getElementById('contentSection').style.display = 'block'; // Show the table section
697
+ })
698
+ .catch(error => console.error('Error:', error));
699
+ }
700
+ function dismissMessage() {
701
+ const messageContainer = document.getElementById('message-container');
702
+ if (messageContainer) {
703
+ messageContainer.innerHTML = '';
704
+ }
705
+ }
706
+
707
+ </script>
708
+ </body>
709
+
710
+ </html>
templates/prompt_template.html ADDED
@@ -0,0 +1,643 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <title>Prompt Template</title>
6
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
7
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
8
+ <!-- Include AdminLTE CSS -->
9
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/adminlte.min.css">
10
+ <!-- Include DataTables CSS -->
11
+ <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap4.min.css">
12
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
13
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
14
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" />
15
+ <style>
16
+ .header-row {
17
+ display: flex;
18
+ justify-content: space-between;
19
+ align-items: center;
20
+ }
21
+
22
+ .card {
23
+ padding: 0;
24
+ margin-top: -15px;
25
+ margin-left: -40px;
26
+ }
27
+
28
+ .table-container {
29
+ width: 100%;
30
+ overflow-x: auto;
31
+
32
+ }
33
+
34
+ .wrapper {
35
+ display: flex;
36
+ flex-direction: column;
37
+ height: 100vh;
38
+ }
39
+
40
+ .content-wrapper {
41
+ flex: 1;
42
+ overflow-y: auto;
43
+ }
44
+
45
+ .content-header {
46
+ padding: 5px;
47
+
48
+ }
49
+
50
+ div.dataTables_wrapper div.dataTables_length select {
51
+ width: 60px;
52
+ display: inline-block;
53
+ }
54
+
55
+ th,
56
+ td {
57
+ white-space: nowrap;
58
+ }
59
+
60
+ th:nth-child(1),
61
+ td:nth-child(1) {
62
+ /* Sno column */
63
+ width: 1%;
64
+ }
65
+
66
+ th:nth-child(2),
67
+ td:nth-child(2) {
68
+ /* API Name column */
69
+ width: 20%;
70
+ }
71
+
72
+ th:nth-child(3),
73
+ td:nth-child(3) {
74
+ /* API Endpoint column */
75
+ width: 45%;
76
+ }
77
+
78
+ th:nth-child(4),
79
+ td:nth-child(4) {
80
+ /* view column*/
81
+ width: 5%;
82
+ }
83
+
84
+ th:nth-child(5),
85
+ td:nth-child(5) {
86
+ /* view column*/
87
+ width: 5%;
88
+ }
89
+
90
+ th:nth-child(6),
91
+ td:nth-child(6) {
92
+ /* view column*/
93
+ width: 5%;
94
+ }
95
+
96
+ .reduced-width {
97
+ width: 25%;
98
+ }
99
+
100
+ .viewButton {
101
+ size: 2px;
102
+ }
103
+
104
+ div.dataTables_wrapper div.dataTables_length select {
105
+ width: 60px;
106
+ display: inline-block;
107
+ }
108
+ </style>
109
+ </head>
110
+
111
+ <body>
112
+ {% include 'sidepane.html' %}
113
+
114
+ <div class="wrapper">
115
+ <div class="main-header" style="border-bottom: none;">
116
+ <!-- Content Header (Page header) -->
117
+ <div class="content-header">
118
+ <div class="container-fluid">
119
+ <div class="container mt-2">
120
+ <div class="form-group left-align" id="company-select">
121
+ <!-- <label for="company" class="mr-1" style="margin-left:-60px;margin-top:-11px;">Company Name
122
+ <span class="text-danger">*</span></label>
123
+ <select type="text" id="company" name="company" class="form-control "
124
+ style="width: 20%;margin-left:-60px;" required>
125
+ <option value="" selected>Select</option>
126
+ </select> -->
127
+ <h4 id="selectedCompany" style="margin-left: 300px;"></h4>
128
+ <!-- <div class="col-12 d-flex justify-content-end mb-2">
129
+ <button class="btn btn-primary"
130
+ style="margin-top:-40px;margin-right: -25px;position: fixed;" id="add">Add</button>
131
+
132
+
133
+ </div> -->
134
+ </div>
135
+ <div class="row">
136
+ <div id="message-container" style="margin-left: 150px;width:500px;"></div>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ <section class="content" id="contentSection" style="display: none;">
142
+ <div class="container-fluid">
143
+ <div class="form-group">
144
+ <!-- <label for="company_id">company_id</label>--->
145
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
146
+ </div>
147
+ </div>
148
+
149
+
150
+ <!-- Main content-->
151
+ <section class="content">
152
+ <div class="container-fluid">
153
+ <div class="row">
154
+ <div class="col-12">
155
+ <div class="card">
156
+ <div class="card-body table-container">
157
+ <table id="promptTable" class="table table-bordered table-striped">
158
+ <thead>
159
+ <tr>
160
+ <th>Sno</th>
161
+ <th>Datasource</th>
162
+ <th>Sample Prompt</th>
163
+ <th>View</th>
164
+ <th>Edit</th>
165
+ <th>Delete</th>
166
+ </tr>
167
+ </thead>
168
+ <tbody>
169
+ <!-- <tr>
170
+ <td>1</td>
171
+ <td>API</td>
172
+ <td>What are the details of ASN24080200002?</td>
173
+ <td><button class="btn btn-primary viewButton">View</button></td>
174
+ </tr>
175
+ <tr>
176
+ <td>2</td>
177
+ <td>API</td>
178
+ <td>What is the expected receiving date of ASN24080200002</td>
179
+ <td><button class="btn btn-primary viewButton">View</button></td>
180
+ </tr>
181
+ <tr>
182
+ <td>3</td>
183
+ <td>Document</td>
184
+ <td>Explain Pre-Receiving Yard Management</td>
185
+ <td><button class="btn btn-primary viewButton">View</button></td>
186
+ </tr>
187
+ <tr>
188
+ <td>4</td>
189
+ <td>Document</td>
190
+ <td>Can you explain the process of unloading a vehicle in more detail?</td>
191
+ <td><button class="btn btn-primary viewButton">View</button></td>
192
+ </tr>
193
+ <tr>
194
+ <td>5</td>
195
+ <td>Visual Analysis</td>
196
+ <td>I want to analyze item name and quantity in a bar chart in warehouse Allcargo Logistics</td>
197
+ <td><button class="btn btn-primary viewButton">View</button></td>
198
+ </tr>
199
+ <tr>
200
+ <td>6</td>
201
+ <td>Visual Analysis</td>
202
+ <td>Can you generate a pie chart with item names and quantities in warehouse Allcargo Logistics</td>
203
+ <td><button class="btn btn-primary viewButton">View</button></td>
204
+ </tr>
205
+ <tr>
206
+ <td>7</td>
207
+ <td>Database</td>
208
+ <td>What are the active warehouses available</td>
209
+ <td><button class="btn btn-primary viewButton">View</button></td>
210
+ </tr>
211
+ <tr>
212
+ <td>8</td>
213
+ <td>Database</td>
214
+ <td>What are the warehouses available</td>
215
+ <td><button class="btn btn-primary viewButton">View</button></td>
216
+ </tr>
217
+ -->
218
+ </tbody>
219
+ </table>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </div>
224
+ </div>
225
+ </section>
226
+ </section>
227
+ </div>
228
+
229
+ </div>
230
+
231
+ <!-- Modal -->
232
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
233
+ aria-hidden="true">
234
+ <div class="modal-dialog" role="document">
235
+ <div class="modal-content">
236
+ <div class="modal-header">
237
+ <h5 class="modal-title" id="addModalLabel">Add Prompt templates</h5>
238
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"></button>
239
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false">&times;</span>
240
+ </div>
241
+ <div class="modal-body">
242
+ <div class="form-group">
243
+ <!-- <label for="company_id">company_id</label>--->
244
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
245
+ </div>
246
+ <form id="addPromptForm">
247
+ <div class="form-group">
248
+ <label for="scenario">Scenario <span class="text-danger">*</span></label>
249
+ <input type="text" class="form-control" id="scenario" name="scenario" required>
250
+ </div>
251
+ <div class="form-group">
252
+ <label for="prompt">Sample Prompt <span class="text-danger">*</span></label>
253
+ <input type="text" class="form-control" id="prompt" name="sampleprompt" required>
254
+ </div>
255
+ <div class="form-group">
256
+ <label for="comments">Comments <span class="text-danger">*</span></label>
257
+ <input type="text" class="form-control" id="comments" name="comments" required>
258
+ </div>
259
+ </form>
260
+ </div>
261
+ <div class="modal-footer">
262
+ <button type="button" id="saveupdate" class="btn btn-primary" style="display: none;">Update</button>
263
+ <!-- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> -->
264
+ <button type="button" id="save" onclick="save_file()" class="btn btn-primary">Save</button>
265
+ </div>
266
+ </div>
267
+ </div>
268
+ </div>
269
+
270
+ { %include 'footer.html'%}
271
+ <!-- Include DataTables JS and your custom script -->
272
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
273
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
274
+ <script>
275
+
276
+ var table = $('#promptTable').DataTable();
277
+ const role = sessionStorage.getItem('userRole');
278
+ console.log('Current role:', role); // Debug statement to check the role
279
+ const passedCompanyName = sessionStorage.getItem('company_name')
280
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
281
+ const company_id = sessionStorage.getItem('company_id');
282
+ document.getElementById("company_id").value = company_id;
283
+
284
+ data_get_from_db(company_id);
285
+
286
+ // if (role === 'superadmin') {
287
+ // const storecompany_id = sessionStorage.getItem('company_id');
288
+ // data_get_from_db(storecompany_id);
289
+ // document.getElementById('company-select').style.display = 'block';
290
+ // //var companyId = getCookie('company_id')
291
+ // //console.log("company id for superadmin",storecompany_id);
292
+ // fetchCompanies();
293
+
294
+ // } else {
295
+ // document.getElementById('company-select').style.display = 'block';
296
+ // const storecompany_id = sessionStorage.getItem('company_id');
297
+ // console.log('Current company_id:', storecompany_id); // Debug statement to check the role
298
+ // data_get_from_db(storecompany_id);
299
+ // }
300
+
301
+ function moveToNextInput(inputs, currentIndex) {
302
+ const nextInput = inputs[currentIndex + 1];
303
+ if (nextInput) {
304
+ nextInput.focus();
305
+ } else {
306
+ // Optionally, submit the form or trigger the save button
307
+ document.getElementById("save").focus();
308
+ }
309
+ }
310
+
311
+ const companySelect = document.getElementById('company');
312
+ const addPromptForm = document.getElementById('addPromptForm');
313
+
314
+
315
+
316
+
317
+ async function data_get_from_db(companyId) {
318
+
319
+ if (companyId) {
320
+ try {
321
+ const Response = await fetch(`/api/get_prompt_templates?company_id=${companyId}`);
322
+ console.log("responce from api :==> ", Response)
323
+ const connectorsResponse = await Response.json();
324
+ console.log("knowledge data table after connecting to table", connectorsResponse);
325
+ console.log("prompt template data table after connecting to table", connectorsResponse);
326
+ const table = $('#promptTable').DataTable(); // Initialize DataTable at the start
327
+ table.clear();
328
+ if (!Array.isArray(connectorsResponse)) {
329
+ throw new TypeError('Expected an array of companies');
330
+ displayErrorMessage("prompt template details do not exist for this company. Please fill in the details.");
331
+ contentSection.style.display = 'none';
332
+ } else {
333
+
334
+ connectorsResponse.forEach((company, index) => {
335
+ table.row.add([
336
+ index + 1,
337
+ company.scenario,
338
+ company.prompt,
339
+ `<a href='#' class='btn btn-info btn-sm'data-kid-id='${company.row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`,
340
+ `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${company.row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`,
341
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
342
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye' fa-eye'></i></a>",
343
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
344
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
345
+ ]).draw(false);
346
+ });
347
+ contentSection.style.display = 'block';
348
+ }
349
+
350
+ } catch (error) {
351
+ console.error('Error fetching company documents:', error);
352
+ //displayEmptyTable();
353
+
354
+ displayErrorMessage("Prompt template do not exist for this company. Please fill in the details by clicking add button.");
355
+ contentSection.style.display = 'none';
356
+ }
357
+ }
358
+ else {
359
+ // displayEmptyTable();
360
+
361
+ displayErrorMessage("Company id do not exist for this company. Please fill in the details by clicking add button.");
362
+ }
363
+
364
+ }
365
+
366
+ function displayErrorMessage(message) {
367
+ const messageContainer = document.getElementById('message-container');
368
+ if (messageContainer) {
369
+ messageContainer.innerHTML = `<div class='alert alert-danger'>${message}</div>`;
370
+ }
371
+ }
372
+
373
+
374
+ // Delete company
375
+ function deleteCompany(button) {
376
+ var companyId = $(button).data('kid-id');
377
+ console.log("k_id deleted", companyId);
378
+ $.ajax({
379
+ type: "DELETE",
380
+ url: `/api/prompt_template_for_del/${companyId}`,
381
+ success: function () {
382
+ var table = $('#promptTable').DataTable();
383
+ table.row($(button).closest('tr')).remove().draw();
384
+
385
+ //alert("Company deleted successfully.");
386
+ const messageContainer = document.getElementById('message-container');
387
+ if (messageContainer)
388
+ messageContainer.innerHTML = `
389
+ <div class='alert alert-danger'>
390
+ Prompt details deleted successfully
391
+ <button class='close' onclick='dismissMessage()'>OK</button>
392
+ </div>`;
393
+ fetchCompanies(); // Refresh the table
394
+ },
395
+ error: function (xhr) {
396
+ alert("Error deleting company: " + xhr.responseJSON.detail);
397
+ }
398
+ });
399
+ }
400
+ // view company ! ...
401
+ function viewCompany(button) {
402
+ var companyId = $(button).data('kid-id');
403
+ const modalTitle = document.getElementById('addModalLabel');
404
+ modalTitle.textContent = 'View Prompt Template Details';
405
+ console.log("view promt id (Rowid) ===> ", companyId)
406
+ if(companyId)
407
+ {
408
+ $.getJSON(`/api/getpromttemplate/${companyId}`, function (company) {
409
+ console.log("view data scenario =====> ", company.scenario)
410
+ console.log("view data prompt =====> ", company.prompt)
411
+ console.log("view data comments =====> ", company.comments)
412
+ $('#scenario').val(company.scenario).attr('readonly', 'readonly');
413
+ $('#prompt').val(company.prompts).attr('readonly', 'readonly');
414
+ $('#comments').val(company.comments).attr('readonly', 'readonly');
415
+ $('#save').hide();// Disable the "Save" button when the modal opens
416
+ $('#addModal').modal('show');
417
+ $('#saveupdate').hide();
418
+ }).fail(function () {
419
+ alert("Error retrieving company details.");
420
+ });
421
+ }
422
+ }
423
+ // Edit company details
424
+
425
+ function editCompany(button) {
426
+ var companyId = $(button).data('kid-id');
427
+ const modalTitle = document.getElementById('addModalLabel');
428
+ modalTitle.textContent = 'Edit Prompt Templates Details';
429
+
430
+ console.info("company id ====#> ", companyId);
431
+ if(companyId)
432
+ {
433
+ $.getJSON(`/api/getpromttemplate/${companyId}`, function (company) {
434
+ $('#scenario').val(company.scenario).removeAttr('readonly');
435
+ $('#prompt').val(company.prompts).removeAttr('readonly');
436
+ $('#comments').val(company.comments).removeAttr('readonly');
437
+ $('#save').hide();
438
+ $('#saveupdate').show();
439
+
440
+ $('#addModal').modal('show');
441
+
442
+ // Update the save button to save the edited company
443
+ $('#saveupdate').off('click').on('click', function () {
444
+ saveupdate(companyId); // Pass the company ID for updating
445
+ });
446
+ console.log(" edit process completed !")
447
+ }).fail(function () {
448
+ alert("Error retrieving company details.");
449
+ });
450
+ }
451
+ }
452
+
453
+ // Save the updated details
454
+ function saveupdate(companyId) {
455
+ console.log("k_id for updating process _ id ! ..,..", companyId);
456
+ const company_id = document.getElementById("company_id").value;
457
+ var formData = new FormData();
458
+ formData.append('scenario', $('#scenario').val());
459
+ formData.append('prompt', $('#prompt').val());
460
+ formData.append('comments', $('#comments').val());
461
+ console.log("edited form data saved process begin ! ....", formData);
462
+
463
+ $.ajax({
464
+ url: `/api/putprompttemplates/${companyId}`,
465
+ type: 'PUT',
466
+ data: formData,
467
+ processData: false, // Required for FormData
468
+ contentType: false, // Required for FormData
469
+ success: function (response) {
470
+ // alert('Prompt details updated successfully.');
471
+ const messageContainer = document.getElementById('message-container');
472
+ if (messageContainer)
473
+ messageContainer.innerHTML = `
474
+ <div class='alert alert-success'>
475
+ Prompt Data updated successfully
476
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
477
+ </div>`;
478
+ $('#addModal').modal('hide'); // Close the modal after saving
479
+ fetchUpdatedDocuments(company_id);
480
+ },
481
+ error: function () {
482
+ alert('Form has no changes to update prompt details.');
483
+ }
484
+ });
485
+ }
486
+ function dismissMessage() {
487
+ const messageContainer = document.getElementById('message-container');
488
+ if (messageContainer) {
489
+ messageContainer.innerHTML = '';
490
+ }
491
+ }
492
+ async function fetchUpdatedDocuments(company_id) {
493
+ console.log("company_id", company_id);
494
+ var table = $('#promptTable').DataTable();
495
+ const Response = await fetch(`/api/prompt_update?company_id=${company_id}`);
496
+ const connectorsResponse = await Response.json();
497
+ console.log("prompt data table after connecting to table", connectorsResponse);
498
+ table.clear();
499
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
500
+ //displayEmptyTable();
501
+
502
+ displayErrorMessage("Promptdetails do not exist for this company. Please fill in the details.");
503
+ contentSection.style.display = 'none';
504
+ } else {
505
+
506
+ connectorsResponse.forEach((company, index) => {
507
+ table.row.add([
508
+
509
+ index + 1,
510
+ company.scenario,
511
+ company.prompts,
512
+ `<a href='#' class='btn btn-info btn-sm'data-kid-id='${company.id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`,
513
+ `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${company.id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`,
514
+ //`<a href='#' class='btn btn-danger btn-sm' onclick='deleteCompany(${company.company_id})'><i class='fas fa-trash'></i></a>`,
515
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
516
+ company.id
517
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>",
518
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
519
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
520
+ ]).draw(false);
521
+ });
522
+ contentSection.style.display = 'block';
523
+ }
524
+ }
525
+ function save_file() {
526
+ const form = document.getElementById('addPromptForm');
527
+
528
+ // Check if the form is valid
529
+ if (!form.checkValidity()) {
530
+ // If the form is invalid, show validation messages and stop the submission
531
+ form.reportValidity();
532
+ return;
533
+ }
534
+ const company_id = $('#company_id').val();
535
+ const scenario = $('#scenario').val();
536
+ const prompt = $('#prompt').val();
537
+ const comments = $('#comments').val();
538
+
539
+ // const view = "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>";
540
+ // const edit = "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>";
541
+ // const dele = "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></a>";
542
+
543
+ var formData = new FormData($('#addPromptForm')[0]);
544
+ const messageContainer = document.getElementById('message-container');
545
+ formData.append("company_id", company_id),
546
+ formData.append("scenario", scenario),
547
+ formData.append("prompt", prompt),
548
+ formData.append("comments", comments),
549
+
550
+ //const formData = new FormData();
551
+ fetch('/api/save_prompt_details', {
552
+ method: 'POST',
553
+ body: formData
554
+ })
555
+ .then(response => {
556
+ if (!response.ok) {
557
+ throw new Error('Network response was not ok');
558
+ }
559
+ return response.json();
560
+ })
561
+ .then(data => {
562
+ const row_id = data.row_id;
563
+ console.log("rowid", row_id);
564
+ var table = $('#promptTable').DataTable();
565
+ var rowCount = table.rows().count();
566
+ const view = `<a href='#' class='btn btn-info btn-sm'data-kid-id='${row_id}' data-action="view" onclick='viewCompany(this)''><i class='fas fa-eye'></i></a>`;
567
+ const edit = `<a href='#' class='btn btn-warning btn-sm'data-kid-id='${row_id}' data-action="edit" onclick='editCompany(this)'><i class='fas fa-edit'></i></a>`;
568
+ const dele = `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`;
569
+ table.row.add([
570
+ rowCount + 1,
571
+ scenario,
572
+ prompt,
573
+ view,
574
+ edit,
575
+ dele
576
+ ]).draw(false);
577
+
578
+ // const messageContainer = document.getElementById('message-container');
579
+ if (messageContainer)
580
+ messageContainer.innerHTML = `
581
+ <div class='alert alert-success'>
582
+ Data saved successfully
583
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
584
+ </div>`;
585
+ $('#addModal').modal('hide');
586
+ document.getElementById('contentSection').style.display = 'block'; // Show the table section
587
+ })
588
+ .catch(error => console.error('Error:', error));
589
+ }
590
+ async function fetchCompanies() {
591
+ try {
592
+ const response = await fetch('/api/companies');
593
+ if (!response.ok) {
594
+ throw new Error('Network response was not ok');
595
+ }
596
+ const data = await response.json();
597
+ displayCompanies(data.companies);
598
+ } catch (error) {
599
+ console.error('Error fetching companies:', error);
600
+ }
601
+ }
602
+
603
+ function displayCompanies(companies) {
604
+ const companySelect = document.getElementById('company');
605
+ companySelect.innerHTML = '<option value="" selected>Select</option>'; // Reset the dropdown
606
+ companies.forEach(company => {
607
+ const option = document.createElement('option');
608
+ option.value = company.name;
609
+ option.textContent = company.name;
610
+ companySelect.appendChild(option);
611
+ });
612
+ }
613
+ function clearFormFields() {
614
+ document.getElementById('scenario').value = "";
615
+ document.getElementById('prompt').value = "";
616
+ document.getElementById('comments').value = "";
617
+
618
+ }
619
+
620
+
621
+ $(document).ready(function () {
622
+ $('#add').on('click', function () {
623
+ const modalTitle = document.getElementById('addModalLabel');
624
+ modalTitle.textContent = 'Add Prompt Template Details';
625
+ $('#scenario').removeAttr('readonly');
626
+ $('#prompt').removeAttr('readonly');
627
+ $('#comments').removeAttr('readonly');
628
+ $('#saveupdate').hide();
629
+ $('#save').show();
630
+ clearFormFields();
631
+ $('#message-container').empty(); // Clear the message container
632
+ $('#addModal').modal('show');
633
+ });
634
+ $('.modal-footer .btn-secondary, .modal-header .close').on('click', function () {
635
+ $('#addModal').modal('hide');
636
+ });
637
+
638
+ });
639
+
640
+ </script>
641
+ </body>
642
+
643
+ </html>
templates/redmindlogo2.jpg ADDED
templates/redmindlogo3.jpg ADDED
templates/sidepane.html ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- sidepane.html -->
2
+ <!-- This file represents the sidepane component of a web application. It contains the navigation menu and sidebar. -->
3
+ <!-- <!DOCTYPE html>
4
+ <html lang="en"> -->
5
+
6
+ <head>
7
+
8
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
9
+ <!-- Include Bootstrap JS -->
10
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
11
+
12
+ <style>
13
+
14
+ /* Sidebar Styles */
15
+ .main-sidebar {
16
+ background: #222; /* Dark background for sidebar */
17
+ color: #fff;
18
+ width: 250px; /* Default width */
19
+ height: 600px !important;
20
+ position: fixed;
21
+ top: 0;
22
+ left: 0;
23
+ transition: all 0.3s ease;
24
+ /* Ensure sidebar content scrolls if needed */
25
+ }
26
+
27
+ .main-sidebar.toggled {
28
+ width: 60px; /* Minimized width */
29
+ }
30
+
31
+ .sidebar-header {
32
+ text-align: center;
33
+ padding: 15px;
34
+ background: #333; /* Dark background for header */
35
+ color: #fff;
36
+ border-radius: 5px;
37
+ margin-bottom: 15px;
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ }
42
+
43
+ .sidebar-header i {
44
+ font-size: 1.5rem;
45
+ }
46
+
47
+ .sidebar-header .menu-text {
48
+ font-size: 14px;
49
+ font-weight: bold;
50
+ }
51
+
52
+ /* Navigation Menu */
53
+ .nav-link {
54
+ display: flex;
55
+ align-items: center;
56
+ color: #fff;
57
+ padding: 10px;
58
+ border-radius: 5px;
59
+ transition: background-color 0.3s ease;
60
+ text-decoration: none;
61
+ }
62
+
63
+ .nav-link:hover {
64
+ background-color: #F8BE12; /* Highlight color on hover */
65
+ color: #fff;
66
+ }
67
+
68
+ .menu-text {
69
+ margin-left: 10px;
70
+ font-weight: bold;
71
+ color: #fff;
72
+ }
73
+
74
+ /* Sidebar Icon Sizes */
75
+ .nav-icon {
76
+ font-size: 20px;
77
+ }
78
+
79
+ /* Hide menu text when sidebar is collapsed */
80
+ .main-sidebar.toggled .menu-text {
81
+ display: none;
82
+ }
83
+
84
+ /* Content Wrapper */
85
+ #content-wrapper {
86
+ margin-left: 250px;
87
+ padding: 15px;
88
+ height: 700px !important;
89
+ transition: margin-left 0.3s ease;
90
+ }
91
+
92
+ #content-wrapper.toggled {
93
+ margin-left: 60px;
94
+ }
95
+
96
+ /* Responsive Design */
97
+ @media (max-width: 991px) {
98
+ .main-sidebar {
99
+ width: 60px; /* Default to minimized on small screens */
100
+
101
+ }
102
+
103
+ #content-wrapper {
104
+ margin-left: 60px;
105
+ }
106
+
107
+ .main-sidebar.toggled + #content-wrapper {
108
+ margin-left: 0;
109
+ }
110
+ }
111
+ </style>
112
+
113
+ <nav class="main-header navbar navbar-expand navbar-light bg-white shadow-sm" style="padding: 15px; ">
114
+ <div class="container-fluid d-flex justify-content-between align-items-center">
115
+ <!-- Toggle Sidebar Button -->
116
+ <button class="btn btn-outline-secondary" id="sidebarToggle" style="margin-right: 15px;">
117
+ <i class="fas fa-bars"></i>
118
+ </button>
119
+
120
+ <!-- Logo and Title Section -->
121
+ <div class="d-flex align-items-center">
122
+ <img src="/static/img/redmindlogo3.jpg" alt="Logo" style="width: 70px; height: auto; margin-right: 15px;">
123
+ <h3 class="m-0" style="font-weight: 500;">RedMindGPT - {{title}}</h3>
124
+ </div>
125
+
126
+ <!-- Buttons Section -->
127
+ <div>
128
+ <button class="btn btn-primary me-3" id="add">Add</button>
129
+ <button class="btn btn-primary" onclick="logout()">Logout</button>
130
+ </div>
131
+ </div>
132
+ </nav>
133
+ <div id="wrapper">
134
+ <!-- Main Sidebar Container -->
135
+ <aside class="main-sidebar sidebar-custom elevation-4" id="sidebarPanel">
136
+ <!-- Sidebar -->
137
+ <div class="sidebar">
138
+ <!-- Sidebar Menu -->
139
+ <nav class="mt-2">
140
+ <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false" id="sidebarMenu">
141
+ <input type="hidden" id="userRole" name="userRole" value={{role}}>
142
+ <input type="hidden" id="company_id" name="company_id" value={{company_id}}>
143
+ <div class="form-group"style="display: none;">
144
+ <label for="llm_tools" >LLM Tools<span class="text-danger">*</span></label>
145
+ <select class="form-control" id="llm_tools" name="llm_tools" multiple required style="display: none;">
146
+ <option value="Database">Database</option>
147
+ <option value="Static Documents">Static Documents</option>
148
+ <option value="API">API</option>
149
+ </select>
150
+ <div class="invalid-feedback">
151
+ Please select at least one LLM tool.
152
+ </div>
153
+ </div>
154
+
155
+ <li class="nav-item">
156
+ <a href="{{url_for('dashboard')}}" class="nav-link">
157
+ <i class="nav-icon fas fa-home"></i>
158
+ <p>Dashboard</p>
159
+ </a>
160
+ </li>
161
+ <li class="nav-item">
162
+ <div class="sidebar-header">
163
+ <i class="nav-icon fas fa-building"></i>
164
+ <span class="menu-text" id="selectedCompany">Select a company</span> <!-- Initial text as fallback -->
165
+ <!-- <span class="menu-text" id="selectedCompany">{{company_name}}</span> -->
166
+ </div>
167
+ </li>
168
+
169
+ <li class="nav-item" >
170
+ <a href="{{ url_for('company_profile') }}" class="nav-link">
171
+ <i class="nav-icon fas fa-users"></i>
172
+ <p>Company Profile</p>
173
+ </a>
174
+ </li>
175
+ <li class="nav-item" id="knowledgebase_link">
176
+ <a href="{{ url_for('knowledgebase') }}" class="nav-link">
177
+ <i class="nav-icon fas fa-cogs"></i>
178
+ <p>KnowledgeBase</p>
179
+ </a>
180
+ </li>
181
+ <li class="nav-item" id="data_connectors_link">
182
+ <a href="{{ url_for('data_connectors') }}" class="nav-link">
183
+ <i class="nav-icon fas fa-cogs"></i>
184
+ <p>Data Connectors</p>
185
+ </a>
186
+ </li>
187
+ <li class="nav-item" id="api_connectors_link">
188
+ <a href="{{ url_for('API_connectors') }}" class="nav-link">
189
+ <i class="nav-icon fas fa-cogs"></i>
190
+ <p>API Connectors</p>
191
+ </a>
192
+ </li>
193
+ <li class="nav-item">
194
+ <a href="{{url_for('prompt_template')}}" class="nav-link">
195
+ <i class="nav-icon fas fa-cogs"></i>
196
+ <p>Prompt Templates</p>
197
+ </a>
198
+ </li>
199
+ <!--<li class="nav-item">
200
+ <a href="#" class="nav-link">
201
+ <i class="nav-icon fas fa-cogs"></i>
202
+ <p>LLM Settings</p>
203
+ </a>
204
+ <ul class="nav nav-treeview">
205
+ <li class="nav-item">
206
+ <a href="#" class="nav-link">
207
+ <i class="far fa-circle nav-icon"></i>
208
+ <p>Sublink 1</p>
209
+ </a>
210
+ </li>
211
+ <li class="nav-item">
212
+ <a href="#" class="nav-link">
213
+ <i class="far fa-circle nav-icon"></i>
214
+ <p>Sublink 2</p>
215
+ </a>
216
+ </li>
217
+
218
+ </ul>
219
+ </li> -->
220
+
221
+ <!-- Add more navigation links here -->
222
+ </ul>
223
+ </nav>
224
+ <!-- /.sidebar-menu -->
225
+ </div>
226
+ <!-- /.sidebar -->
227
+ </aside>
228
+
229
+
230
+ <input type="hidden" id="userRole" name="userRole" value={{role}}>
231
+ <input type="hidden" id="company_id" name="company_id" value={{company_id}}>
232
+ <div class="form-group"style="display: none;">
233
+ <label for="llm_tools" >LLM Tools<span class="text-danger">*</span></label>
234
+ <select class="form-control" id="llm_tools" name="llm_tools" multiple required style="display: none;">
235
+ <option value="Database">Database</option>
236
+ <option value="Static Documents">Static Documents</option>
237
+ <option value="API">API</option>
238
+ </select>
239
+ <div class="invalid-feedback">
240
+ Please select at least one LLM tool.
241
+ </div>
242
+ </div>
243
+ </div>
244
+
245
+ <!-- AdminLTE JS -->
246
+
247
+ <script >
248
+
249
+ function logout() {
250
+ sessionStorage.removeItem('role');
251
+ sessionStorage.clear();
252
+ window.location.href = '/';
253
+ }
254
+
255
+
256
+ document.addEventListener("DOMContentLoaded", function() {
257
+
258
+ const company_id1 = document.getElementById("company_id").value;
259
+ const role1 = document.getElementById("userRole").value;
260
+ sessionStorage.setItem('siderole1',role1);
261
+ sessionStorage.setItem('sidecompanyId1',company_id1);
262
+
263
+ const sidecompanyId = sessionStorage.getItem('sidecompanyId1');
264
+ const siderole = sessionStorage.getItem('siderole1');
265
+ if (siderole==='admin') {
266
+ console.log("Company ID inside sidepane:", sidecompanyId);
267
+ console.log("Role inside sidepane:",siderole);
268
+ editCompany(sidecompanyId,siderole);
269
+
270
+ console.log("inside admin after edit");
271
+ updateLinkVisibility(siderole);
272
+
273
+ }
274
+
275
+ });
276
+
277
+ async function updateLinkVisibility(siderole) {
278
+ //const role = sessionStorage.getItem('role');
279
+ if(siderole==='admin')
280
+ {
281
+ const displayState = JSON.parse(sessionStorage.getItem('displayState'));
282
+
283
+ // Update the visibility of links based on the stored state
284
+ document.getElementById('api_connectors_link').style.display = displayState.apiConnectors;
285
+ document.getElementById('knowledgebase_link').style.display = displayState.knowledgeBase;
286
+ document.getElementById('data_connectors_link').style.display = displayState.dataConnectors
287
+ }
288
+ }
289
+ async function editCompany(sidecompanyId,siderole) {
290
+ console.log("inside edit company id", sidecompanyId);
291
+ console.log("inside edit role role",siderole);
292
+ $.getJSON(`/api/getcompanydetails/${sidecompanyId}`, function (company) {
293
+ // Set the value of #llm_tools and trigger change event
294
+ $('#llm_tools').val(company.llm_tools.split(',')).trigger('change');
295
+
296
+ // Get the selected values from #llm_tools
297
+ const llmTools = $('#llm_tools').val(); // This is an array
298
+
299
+ console.log("inside sidepane edit llmTools", llmTools);
300
+ //const role =sessionStorage.getItem('role');
301
+
302
+ if (llmTools && llmTools.length > 0) {
303
+ console.log("inside if");
304
+
305
+ // Example: Conditionally display some links based on llm_tools
306
+ if (api_connectors_link) {
307
+ api_connectors_link.style.display = llmTools.includes('API') ? 'block' : 'none';
308
+ console.log("state api",api_connectors_link.style.display );
309
+ }
310
+
311
+ if (knowledgebase_link) {
312
+ knowledgebase_link.style.display = llmTools.includes('Static Documents') ? 'block' : 'none';
313
+ console.log("state know", knowledgebase_link.style.display);
314
+ }
315
+
316
+ if (data_connectors_link) {
317
+ data_connectors_link.style.display = llmTools.includes('Database') ? 'block' : 'none';
318
+ console.log("state dataconn", data_connectors_link.style.display);
319
+ }
320
+
321
+ console.log("inside storageadmin");
322
+ sessionStorage.setItem('displayState', JSON.stringify({
323
+ apiConnectors: api_connectors_link.style.display,
324
+ knowledgeBase: knowledgebase_link.style.display ,
325
+ dataConnectors: data_connectors_link.style.display
326
+
327
+ }));
328
+ updateLinkVisibility(siderole);
329
+ }
330
+
331
+ }).fail(function () {
332
+ alert("Error retrieving company details.");
333
+ });
334
+
335
+ }
336
+ document.getElementById('sidebarToggle').addEventListener('click', function() {
337
+ const sidebar = document.getElementById('sidebarPanel');
338
+ const contentWrapper = document.getElementById('content-wrapper');
339
+
340
+ // Toggle sidebar width and content margin
341
+ sidebar.classList.toggle('toggled');
342
+ contentWrapper.classList.toggle('toggled');
343
+ });
344
+ </script>
345
+
346
+ </head>
347
+ <!-- </html> -->
vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"filename": "DPS_School_Content.docx", "document_name": "DSP school Doc", "document_description": "We are elaburate the DSP school details form this doc", "department": "Primary section department", "version": "1234567890", "last_updated": "23-06-2024", "hash": "1dcd3827e8e5f7a08a9c5233de3c47cc", "upload_date": "2024-06-23T14:52:44.654077", "file_path": "/home/rajesh/redmind/python/code/redmindgen/vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.vectorstore", "file_size": 233747, "content_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}
vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.vectorstore/index.faiss ADDED
Binary file (6.19 kB). View file
 
vectordb/openai_dbstore/Future of Digital Freight Forwarders - BLOG.pdf_a3cfd1d6c83cfcd45146ec7c13b1d98d.metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"filename": "Future of Digital Freight Forwarders - BLOG.pdf", "document_name": "Digital Freight Forwarders", "document_description": "Future of Digital Freight Forwarders", "department": "Freight", "version": "1.0", "last_updated": "20/06/2024", "hash": "a3cfd1d6c83cfcd45146ec7c13b1d98d", "upload_date": "2024-06-24T08:05:41.007505", "file_path": "/home/rajesh/redmind/python/code/redmindgen/vectordb/openai_dbstore/Future of Digital Freight Forwarders - BLOG.pdf_a3cfd1d6c83cfcd45146ec7c13b1d98d.vectorstore", "file_size": 100197, "content_type": "application/pdf"}
vectordb/openai_dbstore/Future of Digital Freight Forwarders - BLOG.pdf_a3cfd1d6c83cfcd45146ec7c13b1d98d.vectorstore/index.faiss ADDED
Binary file (6.19 kB). View file
 
vectordb/openai_dbstore/documents/Inbound.pdf_1dd51058ba4a11db1c9773ce16dfc175.metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"filename": "Inbound.pdf", "document_name": "inbound", "document_description": "inbound", "department": "warehouse", "version": "1", "last_updated": "01.01.2025", "hash": "1dd51058ba4a11db1c9773ce16dfc175", "upload_date": "2024-07-22T12:52:08.315686", "file_path": "C:/lakshmi/RedmindGPT/Fastapi_sample/vectordb/openai_dbstore/documents\\Inbound.pdf_1dd51058ba4a11db1c9773ce16dfc175.vectorstore", "file_size": 161577, "content_type": "application/pdf"}
vectordb/openai_dbstore/documents/Inbound.pdf_1dd51058ba4a11db1c9773ce16dfc175.vectorstore/index.faiss ADDED
Binary file (6.19 kB). View file
 
vectordb/openai_dbstore/documents/NewAge (1).pdf_e4fb1ef3fb0aed5f99dbf218f2aa62af.metadata.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"filename": "NewAge (1).pdf", "document_name": "newage", "document_description": "newage", "department": "warehouse", "version": "1", "last_updated": "01.01.2023", "hash": "e4fb1ef3fb0aed5f99dbf218f2aa62af", "upload_date": "2024-07-22T12:50:44.009785", "file_path": "C:/lakshmi/RedmindGPT/Fastapi_sample/vectordb/openai_dbstore/documents\\NewAge (1).pdf_e4fb1ef3fb0aed5f99dbf218f2aa62af.vectorstore", "file_size": 1044446, "content_type": "application/pdf"}
vectordb/openai_dbstore/documents/NewAge (1).pdf_e4fb1ef3fb0aed5f99dbf218f2aa62af.vectorstore/index.faiss ADDED
Binary file (30.8 kB). View file