Redmind commited on
Commit
294253d
·
verified ·
1 Parent(s): 3307563

Upload 55 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. app.py +1509 -0
  2. config/__pycache__/settings.cpython-310.pyc +0 -0
  3. config/__pycache__/settings.cpython-311.pyc +0 -0
  4. config/__pycache__/settings.cpython-312.pyc +0 -0
  5. config/settings.py +4 -0
  6. logs/redmindgen.log +0 -0
  7. requirements.txt +78 -0
  8. services/__pycache__/chat_service.cpython-310.pyc +0 -0
  9. services/__pycache__/chat_service.cpython-311.pyc +0 -0
  10. services/__pycache__/chat_service.cpython-312.pyc +0 -0
  11. services/__pycache__/file_upload_service.cpython-310.pyc +0 -0
  12. services/__pycache__/file_upload_service.cpython-312.pyc +0 -0
  13. services/__pycache__/multidoc_files_upload.cpython-310.pyc +0 -0
  14. services/__pycache__/multidoc_files_upload.cpython-311.pyc +0 -0
  15. services/chat_service.py +137 -0
  16. services/file_upload_service.py +141 -0
  17. static/css/API_connectors.css +91 -0
  18. static/css/company_profile.css +207 -0
  19. static/css/dashboard.css +1410 -0
  20. static/css/dashboard.css.map +7 -0
  21. static/css/dashboard1.css +90 -0
  22. static/css/data_connectors.css +213 -0
  23. static/css/index.css +273 -0
  24. static/css/knowledgebase.css +141 -0
  25. static/css/perfect-scrollbar.css +116 -0
  26. static/css/prompt_template.css +94 -0
  27. static/css/sidepane.css +93 -0
  28. static/css/style.css +0 -0
  29. static/css/style.css.map +0 -0
  30. static/img/AI.jpg +0 -0
  31. static/img/redmindlogo3.jpg +0 -0
  32. static/logos/avatar.svg +10 -0
  33. static/logos/calendar-silhouette.svg +4 -0
  34. static/logos/dots.svg +22 -0
  35. static/logos/email.svg +4 -0
  36. templates/API_connectors.html +523 -0
  37. templates/chatbot.html +84 -0
  38. templates/company_profile.html +525 -0
  39. templates/dashboard.html +274 -0
  40. templates/data_connectors.html +453 -0
  41. templates/footer.html +24 -0
  42. templates/index.html +96 -0
  43. templates/knowledgebase.html +566 -0
  44. templates/prompt_template.html +548 -0
  45. templates/redmindlogo2.jpg +0 -0
  46. templates/redmindlogo3.jpg +0 -0
  47. templates/sidepane.html +180 -0
  48. vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.metadata.json +1 -0
  49. vectordb/openai_dbstore/DPS_School_Content.docx_1dcd3827e8e5f7a08a9c5233de3c47cc.vectorstore/index.faiss +0 -0
  50. vectordb/openai_dbstore/Future of Digital Freight Forwarders - BLOG.pdf_a3cfd1d6c83cfcd45146ec7c13b1d98d.metadata.json +1 -0
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(xtzb0z_P8wRkowkDGQe@167.71.75.10:3306/collegedb"
logs/redmindgen.log ADDED
The diff for this file is too large to render. See raw diff
 
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/API_connectors.css ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .form-group {
2
+ margin-top: -10px;
3
+ }
4
+
5
+ .card {
6
+ padding: 0;
7
+ margin-top: -15px;
8
+ margin-left: -40px;
9
+ }
10
+
11
+ .header-row {
12
+ display: flex;
13
+ justify-content: space-between;
14
+ align-items: center;
15
+ }
16
+
17
+
18
+ .table-container {
19
+ width: 100%;
20
+ overflow-x: auto;
21
+ }
22
+
23
+ .wrapper {
24
+ display: flex;
25
+ flex-direction: column;
26
+ height: 100vh;
27
+ }
28
+
29
+ .content-wrapper {
30
+ flex: 1;
31
+ overflow-y: auto;
32
+ }
33
+
34
+ .content-header {
35
+ padding: 5px;
36
+ }
37
+
38
+ th,
39
+ td {
40
+ white-space: nowrap;
41
+ }
42
+
43
+ th:nth-child(1),
44
+ td:nth-child(1) {
45
+ /* Sno column */
46
+ width: 5%;
47
+ }
48
+
49
+ div.dataTables_wrapper div.dataTables_length select {
50
+ width: 60px;
51
+ display: inline-block;
52
+ }
53
+
54
+ th:nth-child(2),
55
+ td:nth-child(2) {
56
+ /* API Name column */
57
+ width: 20%;
58
+ }
59
+
60
+ th:nth-child(3),
61
+ td:nth-child(3) {
62
+ /* API Endpoint column */
63
+ width: 40%;
64
+ }
65
+
66
+ th:nth-child(4),
67
+ td:nth-child(4) {
68
+ /* Auth/Bearer token column */
69
+ width: 5%;
70
+ }
71
+
72
+ th:nth-child(5),
73
+ td:nth-child(5) {
74
+ /* View column */
75
+ width: 5%;
76
+ }
77
+
78
+ th:nth-child(6),
79
+ td:nth-child(6) {
80
+ /* View column */
81
+ width: 5%;
82
+ }
83
+
84
+ .reduced-width {
85
+ width: 25%;
86
+ }
87
+
88
+ div.dataTables_wrapper div.dataTables_length select {
89
+ width: 60px;
90
+ display: inline-block;
91
+ }
static/css/company_profile.css ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #add {
2
+ display: inline-block;
3
+ margin-right: 15px !important;
4
+ /* Optional: Adjust margin if needed */
5
+ }
6
+
7
+ body {
8
+ background-color: transparent !important;
9
+ }
10
+
11
+ .card {
12
+ padding: 0;
13
+ margin-top: 10px;
14
+ margin-left: -50px;
15
+ }
16
+
17
+ /* Ensure the DataTable wrapper takes the full width */
18
+ .dataTables_wrapper {
19
+ width: 100%;
20
+ }
21
+
22
+ /* Ensure the DataTable wrapper takes the full width */
23
+ .dataTables_wrapper {
24
+ width: 100%;
25
+ }
26
+
27
+
28
+
29
+ /* Style for the custom dropdown */
30
+ .custom-dropdown {
31
+ position: relative;
32
+ display: inline-block;
33
+ margin-left: 10px;
34
+ /* Space between label and dropdown */
35
+ }
36
+
37
+ .dropdown-button {
38
+ background-color: white;
39
+ color: black;
40
+ padding: 5px;
41
+ border: 1px solid black;
42
+ border-radius: 4px;
43
+ cursor: pointer;
44
+ text-align: left;
45
+ width: 60px;
46
+ /* Adjust width as needed */
47
+ }
48
+
49
+ .dropdown-content {
50
+ display: none;
51
+ position: absolute;
52
+ background-color: #f9f9f9;
53
+ min-width: 80px;
54
+ /* Adjust width as needed */
55
+ box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
56
+ z-index: 1;
57
+ border: 1px solid #ddd;
58
+ top: 100%;
59
+ /* Position below the button */
60
+ left: 0;
61
+ }
62
+
63
+ .dropdown-content a {
64
+ padding: 10px;
65
+ text-decoration: none;
66
+ display: block;
67
+ color: #333;
68
+ }
69
+
70
+ .dropdown-content a:hover {
71
+ background-color: #ddd;
72
+ }
73
+
74
+ .content-wrapper {
75
+ background-color: transparent !important;
76
+ text-align: center;
77
+ }
78
+
79
+ .wrapper {
80
+ background-color: transparent !important;
81
+ }
82
+
83
+ .modal-content {
84
+ background-color: #fff;
85
+ }
86
+
87
+ h1 {
88
+ text-align: center;
89
+ margin-bottom: 30px;
90
+ }
91
+
92
+
93
+ .table-responsive {
94
+ width: 95%;
95
+ overflow-x: none;
96
+ }
97
+
98
+ .table {
99
+ width: 100%;
100
+ }
101
+
102
+ .text-wrap {
103
+ white-space: normal !important;
104
+ word-break: break-word;
105
+ }
106
+
107
+ div.dataTables_wrapper div.dataTables_length select {
108
+ width: 60px;
109
+ display: inline-block;
110
+ }
111
+
112
+ .center-align {
113
+ padding-top: 20px;
114
+ display: flex;
115
+ justify-content: center;
116
+ align-items: center;
117
+ width: 100%;
118
+ }
119
+
120
+ .reduced-width {
121
+ width: 50%;
122
+ }
123
+
124
+ th,
125
+ td {
126
+ white-space: nowrap;
127
+ }
128
+
129
+ .select2-container--bootstrap4 {
130
+ z-index: 1050;
131
+ /* Higher than the modal's z-index */
132
+ }
133
+
134
+ .select2-container--open {
135
+ z-index: 1060;
136
+ /* Ensure the dropdown is above the modal */
137
+ }
138
+
139
+ th:nth-child(1),
140
+ td:nth-child(1) {
141
+ width: 5%;
142
+ }
143
+
144
+ th:nth-child(2),
145
+ td:nth-child(2) {
146
+ width: 20%;
147
+ }
148
+
149
+ th:nth-child(3),
150
+ td:nth-child(3) {
151
+ width: 20%;
152
+ }
153
+
154
+ th:nth-child(4),
155
+ td:nth-child(4) {
156
+ width: 20%;
157
+ }
158
+
159
+ th:nth-child(5),
160
+ td:nth-child(5) {
161
+ width: 10%;
162
+ }
163
+
164
+ th:nth-child(6),
165
+ td:nth-child(6) {
166
+ width: 10%;
167
+ }
168
+
169
+ th:nth-child(7),
170
+ td:nth-child(7) {
171
+ width: 10%;
172
+ }
173
+
174
+ th:nth-child(8),
175
+ td:nth-child(8) {
176
+ width: 10%;
177
+ }
178
+
179
+ .alert {
180
+ position: relative;
181
+ padding: 15px;
182
+ margin-bottom: 20px;
183
+ border: 1px solid transparent;
184
+ border-radius: 4px;
185
+ }
186
+
187
+ .alert-success {
188
+ color: #3c763d;
189
+ background-color: #dff0d8;
190
+ border-color: #d6e9c6;
191
+ }
192
+
193
+ .alert-danger {
194
+ color: #a94442;
195
+ background-color: #f2dede;
196
+ border-color: #ebccd1;
197
+ }
198
+
199
+ .close2 {
200
+ position: absolute;
201
+ bottom: 10px;
202
+ right: 10px;
203
+ border: none;
204
+ background: none;
205
+ font-size: 16px;
206
+ cursor: pointer;
207
+ }
static/css/dashboard.css ADDED
@@ -0,0 +1,1410 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ /*
21
+ 0 - 600: Phone
22
+ 600 - 900: Tablet portrait
23
+ 900 - 1200: Tablet landscape
24
+ 1200 - 1800: Normal styles
25
+ 1800+ : Big Desktop
26
+ 1em = 16px
27
+ The smaller device rules always should write below the bigger device rules
28
+ Fixing Order => Base + Typography >> General Layout + Grid >> Page Layout + Component
29
+ */
30
+ .event-chart {
31
+ margin: -10px 0px;
32
+ }
33
+
34
+ .default-select.style-1 {
35
+ border: 0;
36
+ font-size: 12px;
37
+ padding: 5px;
38
+ }
39
+
40
+ .default-select.style-1 option {
41
+ background: #fff;
42
+ box-shadow: 0 10px 40px 0 rgba(32, 28, 69, 0.1);
43
+ }
44
+
45
+ .event-table {
46
+ border-radius: 1.25rem;
47
+ }
48
+
49
+ .event-table thead th {
50
+ color: #000;
51
+ font-size: 18px;
52
+ white-space: nowrap;
53
+ font-weight: 600;
54
+ padding: 20px 10px;
55
+ }
56
+
57
+ .event-table tbody td {
58
+ font-size: 14px;
59
+ padding: 20px 10px;
60
+ }
61
+
62
+ @media only screen and (max-width: 1400px) {
63
+ .event-table thead th {
64
+ color: #000;
65
+ font-size: 15px;
66
+ white-space: nowrap;
67
+ font-weight: 600;
68
+ }
69
+
70
+ .event-table tbody td {
71
+ padding: 12px 15px;
72
+ }
73
+ }
74
+
75
+ .dropdown-no-icon .dropdown-toggle:after {
76
+ content: none;
77
+ }
78
+
79
+ .detault-daterange .dashboard-select.mat-form-field-appearance-fill .mat-form-field-flex {
80
+ padding: 0em 1em 0 1em;
81
+ }
82
+
83
+ .detault-daterange .mat-form-field-prefix,
84
+ .detault-daterange .mat-form-field-suffix {
85
+ top: 5px;
86
+ }
87
+
88
+ .dashboard-select {
89
+ font-size: 16px;
90
+ }
91
+
92
+ .dashboard-select .mat-form-field-wrapper,
93
+ .dashboard-select .mat-form-field-appearance-fill .mat-form-field-flex {
94
+ padding: 0;
95
+ background: transparent;
96
+ }
97
+
98
+ .dashboard-select .mat-form-field-underline {
99
+ display: none;
100
+ }
101
+
102
+ .dashboard-select .mat-form-field-infix {
103
+ border: 0;
104
+ }
105
+
106
+ .dashboard-select.mat-form-field-appearance-fill .mat-select-arrow-wrapper {
107
+ transform: translateY(-10%);
108
+ }
109
+
110
+ .dashboard-select.mat-form-field-appearance-fill .mat-form-field-flex {
111
+ padding: 1em 1em 0 1em;
112
+ background-color: #fff;
113
+ }
114
+
115
+ .dashboard-select.mat-form-field-appearance-fill .mat-form-field-infix {
116
+ padding: .25em 0 1em 0;
117
+ }
118
+
119
+ .dashboard-select .mat-select-arrow,
120
+ .dashboard-select .mat-select-value {
121
+ color: #40189D;
122
+ }
123
+
124
+ .dashboard-select.style-1 {
125
+ font-size: 16px;
126
+ border: 1px solid #f0f1f5;
127
+ border-radius: 3rem;
128
+ }
129
+
130
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-infix {
131
+ padding: 6px 0 18px 0;
132
+ }
133
+
134
+ .dashboard-select.style-1 .mat-form-field-infix {
135
+ padding: 15px 15px;
136
+ width: auto;
137
+ }
138
+
139
+ .dashboard-select.style-1 .mat-select-value {
140
+ max-width: unset;
141
+ padding-right: 6px;
142
+ }
143
+
144
+ .dashboard-select.style-1 .mat-select-arrow,
145
+ .dashboard-select.style-1 .mat-select-value {
146
+ color: #000;
147
+ }
148
+
149
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-flex {
150
+ border-radius: 3rem;
151
+ background-color: #fff;
152
+ padding: 12px 20px 0;
153
+ }
154
+
155
+ @media only screen and (max-width: 1400px) {
156
+ .dashboard-select.style-1 {
157
+ font-size: 0.813rem;
158
+ }
159
+
160
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-infix {
161
+ padding: 6px 0 12px 0;
162
+ }
163
+
164
+ .dashboard-select.style-1 .mat-form-field-infix {
165
+ padding: 11px 15px;
166
+ width: auto;
167
+ }
168
+
169
+ .dashboard-select.style-1.mat-form-field-appearance-fill .mat-form-field-flex {
170
+ padding: 8px 15px 0;
171
+ }
172
+ }
173
+
174
+ .compose-content .dropzone {
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: center;
178
+ }
179
+
180
+ .latest-salebx {
181
+ height: 630px;
182
+ }
183
+
184
+ @media only screen and (max-width: 1199px) {
185
+ .latest-salebx {
186
+ height: 350px;
187
+ }
188
+ }
189
+
190
+ .about-company {
191
+ border-top: 1px solid #EEEEEE;
192
+ }
193
+
194
+ @media only screen and (max-width: 1199px) {
195
+ .about-company {
196
+ border-top: 0;
197
+ border-left: 1px solid #EEEEEE;
198
+ }
199
+ }
200
+
201
+ @media only screen and (max-width: 767px) {
202
+ .about-company {
203
+ border-left: 0;
204
+ border-top: 1px solid #EEEEEE;
205
+ }
206
+ }
207
+
208
+ .post-input .btn-social {
209
+ margin-right: 4px;
210
+ }
211
+
212
+ .rating-widget .ng-star-inserted {
213
+ color: #40189D;
214
+ font-size: 30px;
215
+ }
216
+
217
+ .default-accordion {
218
+ box-shadow: none;
219
+ margin-bottom: 1.25rem;
220
+ height: unset;
221
+ border-radius: 5px;
222
+ }
223
+
224
+ .default-accordion .card-header {
225
+ padding: 0;
226
+ border: 0;
227
+ }
228
+
229
+ .default-accordion .card-header button {
230
+ border-radius: 5px;
231
+ background: #40189D;
232
+ color: #fff;
233
+ display: block;
234
+ border: 0;
235
+ width: 100%;
236
+ text-align: left;
237
+ padding-right: 40px;
238
+ }
239
+
240
+ .default-accordion .card-header button.collapsed {
241
+ background: rgba(64, 24, 157, 0.15);
242
+ color: #000;
243
+ }
244
+
245
+ .default-accordion .card-header button.collapsed:after {
246
+ content: "\e61a";
247
+ }
248
+
249
+ .default-accordion .card-header button:focus {
250
+ box-shadow: none;
251
+ }
252
+
253
+ .default-accordion .card-header button:after {
254
+ position: absolute;
255
+ font-family: 'themify';
256
+ top: 50%;
257
+ content: "\e622";
258
+ transform: translateY(-50%);
259
+ right: 20px;
260
+ }
261
+
262
+ .custom-header-accordion {
263
+ border: 1px solid #EEEEEE;
264
+ box-shadow: none;
265
+ margin-bottom: 0;
266
+ height: unset;
267
+ }
268
+
269
+ .custom-header-accordion .card-header button:focus {
270
+ box-shadow: none;
271
+ }
272
+
273
+ .prevent-accordion {
274
+ box-shadow: none;
275
+ margin-bottom: 1.25rem;
276
+ height: unset;
277
+ border-radius: 5px;
278
+ }
279
+
280
+ .prevent-accordion .card-header {
281
+ padding: 0;
282
+ border: 0;
283
+ }
284
+
285
+ .prevent-accordion .card-header button {
286
+ background: #40189D;
287
+ border-radius: 5px;
288
+ color: #fff;
289
+ display: block;
290
+ border: 0;
291
+ width: 100%;
292
+ text-align: left;
293
+ padding-right: 40px;
294
+ }
295
+
296
+ .prevent-accordion .card-header button.collapsed {
297
+ background: rgba(64, 24, 157, 0.15);
298
+ color: #000;
299
+ }
300
+
301
+ .prevent-accordion .card-header button.collapsed:after {
302
+ content: "\e61a";
303
+ }
304
+
305
+ .prevent-accordion .card-header button:focus {
306
+ box-shadow: none;
307
+ }
308
+
309
+ .prevent-accordion .card-header button:after {
310
+ position: absolute;
311
+ font-family: 'themify';
312
+ top: 50%;
313
+ content: "\e622";
314
+ transform: translateY(-50%);
315
+ right: 20px;
316
+ }
317
+
318
+ .default-nestable {
319
+ /* .nestable-row{
320
+ display:flex;
321
+ }
322
+ .ngx-nestable{
323
+ width:50%;
324
+ }*/
325
+ }
326
+
327
+ .default-nestable .dd-dragel .ngx-nestable-hidden,
328
+ .default-nestable .dd-dragel button {
329
+ visibility: hidden;
330
+ }
331
+
332
+ .default-nestable .dd-list .dd-item .nestable-item-container {
333
+ background: #e6defa;
334
+ color: #000;
335
+ position: relative;
336
+ display: flex;
337
+ flex-direction: row;
338
+ align-items: center;
339
+ min-height: 32px;
340
+ font-size: 16px;
341
+ font-family: Roboto, sans-serif;
342
+ cursor: pointer;
343
+ outline: 0;
344
+ border-radius: 5px;
345
+ margin-bottom: 3px;
346
+ padding: 10px 10px;
347
+ -webkit-transition: all 0.5s;
348
+ -ms-transition: all 0.5s;
349
+ transition: all 0.5s;
350
+ }
351
+
352
+ .default-nestable .dd-list .dd-item .nestable-item-container:hover {
353
+ background: #40189D;
354
+ color: #fff;
355
+ }
356
+
357
+ .default-nestable .dd-list .dd-item .nestable-item-container:hover button {
358
+ color: #fff;
359
+ }
360
+
361
+ .default-nestable .dd-list .dd-item .nestable-item-container button {
362
+ font-family: 'Material Icons';
363
+ font-weight: normal;
364
+ font-style: normal;
365
+ outline: 0;
366
+ border: 0;
367
+ font-size: 24px;
368
+ line-height: 1;
369
+ letter-spacing: normal;
370
+ text-transform: none;
371
+ margin-right: 10px;
372
+ background: transparent;
373
+ color: #000;
374
+ display: inline-block;
375
+ white-space: nowrap;
376
+ word-wrap: normal;
377
+ direction: ltr;
378
+ -webkit-font-feature-settings: 'liga';
379
+ -webkit-font-smoothing: antialiased;
380
+ }
381
+
382
+ @media only screen and (max-width: 575px) {
383
+ .default-nestable .dd-list .dd-item .nestable-item-container {
384
+ padding: 0;
385
+ }
386
+ }
387
+
388
+ .default-nestable .result-bx textarea {
389
+ height: 100%;
390
+ width: 100%;
391
+ }
392
+
393
+ @media only screen and (max-width: 991px) {
394
+ .default-nestable .result-bx {
395
+ margin-top: 30px;
396
+ }
397
+
398
+ .default-nestable .result-bx textarea {
399
+ height: 600px;
400
+ width: 100%;
401
+ }
402
+ }
403
+
404
+ .alert-dismissible .close {
405
+ height: 100%;
406
+ font-size: 30px;
407
+ }
408
+
409
+ .alert-dismissible .close span {
410
+ font-weight: 400;
411
+ }
412
+
413
+ .calendar-responsive {
414
+ overflow: auto;
415
+ display: block;
416
+ }
417
+
418
+ .default-calendar ngb-datepicker {
419
+ border: 0;
420
+ background: #f3f3f3;
421
+ }
422
+
423
+ .default-calendar .form-group .input-group .form-control {
424
+ color: #000;
425
+ }
426
+
427
+ .default-calendar .form-group .input-group .input-group-append button {
428
+ background-image: none !important;
429
+ padding: 0px;
430
+ border-color: #40189D;
431
+ background: #40189D;
432
+ width: 45px;
433
+ text-align: center;
434
+ }
435
+
436
+ .default-calendar .form-group .input-group .input-group-append button:after {
437
+ color: #fff;
438
+ content: "\f133";
439
+ font-family: 'Line Awesome Free';
440
+ padding: 0;
441
+ font-size: 26px;
442
+ }
443
+
444
+ .default-calendar .form-group .input-group .input-group-append button:hover {
445
+ background: #40189D;
446
+ }
447
+
448
+ .default-calendar .form-group .input-group .input-group-append button:hover:after {
449
+ color: #fff;
450
+ }
451
+
452
+ .default-calendar .form-group .input-group .input-group-append button:focus {
453
+ box-shadow: none;
454
+ }
455
+
456
+ .default-calendar .weekend {
457
+ background-color: #40189D;
458
+ }
459
+
460
+ .default-calendar .ngb-dp-header {
461
+ background: #40189D;
462
+ padding: 8px 5px;
463
+ }
464
+
465
+ .default-calendar .ngb-dp-header .ngb-dp-navigation-chevron {
466
+ border-color: #fff;
467
+ }
468
+
469
+ .default-calendar .ngb-dp-header .custom-select {
470
+ color: #fff;
471
+ background: #40189D;
472
+ border-radius: 5px;
473
+ margin: 0 5px;
474
+ padding: 0 20px;
475
+ }
476
+
477
+ .default-calendar .ngb-dp-weekdays {
478
+ border: 1px solid rgba(64, 24, 157, 0.25);
479
+ background: #fff;
480
+ }
481
+
482
+ .default-calendar .ngb-dp-weekdays .ngb-dp-weekday {
483
+ color: #40189D;
484
+ font-weight: 600;
485
+ font-size: 15px;
486
+ font-style: unset;
487
+ }
488
+
489
+ .default-calendar .ngb-dp-day,
490
+ .default-calendar .ngb-dp-week-number,
491
+ .default-calendar .ngb-dp-weekday {
492
+ max-height: 40px;
493
+ max-width: 40px;
494
+ height: 40px;
495
+ width: 35px;
496
+ line-height: 40px;
497
+ }
498
+
499
+ .default-calendar [ngbDatepickerDayView] {
500
+ max-height: 40px;
501
+ max-width: 40px;
502
+ width: 35px;
503
+ height: 40px;
504
+ line-height: 40px;
505
+ }
506
+
507
+ .default-calendar [ngbDatepickerDayView]:active {
508
+ background-color: #40189D !important;
509
+ color: white !important;
510
+ }
511
+
512
+ .default-calendar .ngb-dp-navigation-select {
513
+ flex: unset;
514
+ }
515
+
516
+ .default-calendar .custom-day {
517
+ height: 40px !important;
518
+ line-height: 40px;
519
+ padding: 0px !important;
520
+ width: 100% !important;
521
+ }
522
+
523
+ .default-calendar .custom-day.range,
524
+ .default-calendar .custom-day:hover {
525
+ height: 40px;
526
+ background-color: #40189D !important;
527
+ }
528
+
529
+ .default-calendar .ngb-dp-month-name {
530
+ padding: 8px 0px;
531
+ height: auto;
532
+ }
533
+
534
+ .dashboard-full-calendar.fc .fc-button-primary {
535
+ background-color: #40189D;
536
+ color: #fff;
537
+ border: 0;
538
+ }
539
+
540
+ .dashboard-full-calendar.fc .fc-button-primary:hover,
541
+ .dashboard-full-calendar.fc .fc-button-primary.fc-button-active,
542
+ .dashboard-full-calendar.fc .fc-button-primary:active {
543
+ background-color: #1c0a45 !important;
544
+ }
545
+
546
+ .dashboard-full-calendar.fc .fc-button-primary:focus {
547
+ box-shadow: none !important;
548
+ }
549
+
550
+ .dashboard-full-calendar.fc-theme-standard td,
551
+ .dashboard-full-calendar.fc-theme-standard th,
552
+ .dashboard-full-calendar.fc-theme-standard .fc-scrollgrid,
553
+ .dashboard-full-calendar.fc-theme-standard .fc-list {
554
+ border-color: #ECF0F3;
555
+ }
556
+
557
+ .dashboard-full-calendar .fc-daygrid-day.fc-day-today {
558
+ background-color: #e6defa !important;
559
+ }
560
+
561
+ .dashboard-full-calendar .fc-daygrid-dot-event {
562
+ background: #fff;
563
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
564
+ }
565
+
566
+ .dashboard-full-calendar.fc-theme-standard th {
567
+ padding: 0.75rem 0.5rem;
568
+ font-size: 1rem;
569
+ font-weight: 500;
570
+ }
571
+
572
+ .dashboard-full-calendar.fc-theme-standard th a {
573
+ color: #B5B5C3;
574
+ }
575
+
576
+ .dashboard-full-calendar .fc-h-event,
577
+ .dashboard-full-calendar .fc-v-event {
578
+ background-color: #40189D;
579
+ border-color: #40189D;
580
+ }
581
+
582
+ .dashboard-full-calendar .fc-daygrid-event-dot,
583
+ .dashboard-full-calendar .fc-list-event-dot {
584
+ border-color: #40189D !important;
585
+ }
586
+
587
+ @media only screen and (max-width: 767px) {
588
+ .dashboard-full-calendar.fc .fc-toolbar {
589
+ display: block;
590
+ text-align: center;
591
+ }
592
+
593
+ .dashboard-full-calendar.fc .fc-toolbar .fc-toolbar-title {
594
+ margin: 10px;
595
+ }
596
+ }
597
+
598
+ .calendar-list {
599
+ margin-bottom: 10px;
600
+ }
601
+
602
+ .calendar-list .list-group-item {
603
+ background: #f4f6fa;
604
+ color: #40189D;
605
+ border: 0;
606
+ margin-bottom: 5px;
607
+ border-radius: 6px;
608
+ position: relative;
609
+ border-left: 4px solid #40189D;
610
+ }
611
+
612
+ .calendar-checkbox {
613
+ border-radius: 6px;
614
+ background: #e6defa;
615
+ padding: 10px 15px;
616
+ margin-bottom: 5px;
617
+ color: #000;
618
+ }
619
+
620
+ .calendar-checkbox label {
621
+ margin-bottom: 0;
622
+ }
623
+
624
+ .calendar-checkbox input[type=checkbox],
625
+ .calendar-checkbox input[type=radio] {
626
+ margin-right: 6px;
627
+ }
628
+
629
+ .calendar-description h2 {
630
+ margin-top: 30px;
631
+ font-size: 25px;
632
+ font-weight: 600;
633
+ color: #000;
634
+ }
635
+
636
+ .calendar-description ul li {
637
+ font-size: 15px;
638
+ color: #000;
639
+ }
640
+
641
+ .default-carousel .carousel-caption {
642
+ background: rgba(0, 0, 0, 0.5);
643
+ bottom: 45px;
644
+ padding: 15px 15px;
645
+ }
646
+
647
+ .default-carousel .carousel-caption h3 {
648
+ color: #fff;
649
+ }
650
+
651
+ @media only screen and (max-width: 575px) {
652
+ .default-carousel .carousel-caption {
653
+ width: 90%;
654
+ left: 50%;
655
+ transform: translatex(-50%);
656
+ }
657
+ }
658
+
659
+ .default-carousel .carousel-indicators li {
660
+ -webkit-transition: all 0.5s;
661
+ -ms-transition: all 0.5s;
662
+ transition: all 0.5s;
663
+ height: 13px;
664
+ width: 13px;
665
+ border: 0;
666
+ border-radius: 13px;
667
+ background: #40189D;
668
+ }
669
+
670
+ .default-carousel .carousel-indicators li.active {
671
+ width: 30px;
672
+ }
673
+
674
+ @media only screen and (max-width: 575px) {
675
+ .default-carousel .carousel-item img {
676
+ height: 280px;
677
+ }
678
+ }
679
+
680
+ .default-rating span {
681
+ font-size: 35px;
682
+ }
683
+
684
+ .pagination-responsive {
685
+ overflow: auto;
686
+ }
687
+
688
+ .pagination .page-item .page-link span {
689
+ color: #B1B1B1;
690
+ }
691
+
692
+ .pagination .page-item .page-link:hover span {
693
+ color: #fff;
694
+ }
695
+
696
+ .progress {
697
+ height: 16px;
698
+ }
699
+
700
+ .form-select.mat-form-field {
701
+ display: block;
702
+ }
703
+
704
+ .form-select .mat-form-field-infix {
705
+ border-top: 0;
706
+ }
707
+
708
+ .form-select .mat-form-field-underline {
709
+ display: none;
710
+ }
711
+
712
+ .form-select.mat-form-field-appearance-fill .mat-form-field-flex {
713
+ border-radius: 1.25rem;
714
+ padding: 15px 15px 8px;
715
+ background: transparent;
716
+ border: 1px solid #EEEEEE;
717
+ }
718
+
719
+ .form-select.mat-form-field-appearance-fill .mat-select-arrow-wrapper {
720
+ transform: translateY(0%);
721
+ }
722
+
723
+ /** Material Scsss start**/
724
+ /* auto compelete */
725
+ .default-autocomplete {
726
+ /* .mat-autocomplete-trigger{
727
+ margin: 1px;
728
+ border:1px solid $border-color;
729
+ border-radius:5px;
730
+ width:100%;
731
+ padding: 15px 20px;
732
+ } */
733
+ /* .mat-form-field-appearance-legacy .mat-form-field-infix{
734
+ padding:0;
735
+ .mat-input-element{
736
+ margin: 1px;
737
+ border:1px solid $border-color;
738
+ border-radius:5px;
739
+ padding: 15px 20px;
740
+ }
741
+ } */
742
+ /* .mat-form-field-appearance-legacy .mat-form-field-label{
743
+ color:rgba($black,0.5);
744
+ left: 15px;
745
+ top: 30px;
746
+ } */
747
+ }
748
+
749
+ .default-autocomplete .mat-form-field {
750
+ width: 100%;
751
+ }
752
+
753
+ .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,
754
+ .default-autocomplete .mat-form-field-appearance-legacy.mat-form-field-can-float.mat-form-field-should-float .mat-form-field-label,
755
+ .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 {
756
+ /* transform: translateY(-2rem) scale(0.85) perspective(100px) translateZ(0.001px);
757
+ -ms-transform: translateY(-2rem) scale(0.85); */
758
+ color: #40189D;
759
+ }
760
+
761
+ .default-autocomplete .mat-form-field.mat-focused .mat-form-field-ripple {
762
+ background-color: #40189D;
763
+ }
764
+
765
+ /* badge */
766
+ .mat-flat-button.mat-primary,
767
+ .mat-raised-button.mat-primary,
768
+ .mat-fab.mat-primary,
769
+ .mat-mini-fab.mat-primary,
770
+ .mat-badge-content {
771
+ background-color: #40189D;
772
+ }
773
+
774
+ .mat-badge-accent .mat-badge-content {
775
+ background: #8BC740;
776
+ color: #fff;
777
+ }
778
+
779
+ /* Bottom Sheet */
780
+ .mat-bottom-sheet-container {
781
+ max-height: 80vh;
782
+ overflow: auto;
783
+ }
784
+
785
+ .mat-bottom-sheet-container ul li a {
786
+ padding: 15px 15px;
787
+ display: block;
788
+ }
789
+
790
+ .mat-bottom-sheet-container ul li a:hover,
791
+ .mat-bottom-sheet-container ul li a:focus {
792
+ background: rgba(0, 0, 0, 0.04);
793
+ }
794
+
795
+ .mat-bottom-sheet-container ul li a span {
796
+ color: #000;
797
+ display: block;
798
+ font-size: 16px;
799
+ }
800
+
801
+ .mat-bottom-sheet-container ul li a span:last-child {
802
+ font-size: 14px;
803
+ }
804
+
805
+ /* button */
806
+ .default-mt-btn .mat-button.mat-primary,
807
+ .default-mt-btn .mat-icon-button.mat-primary,
808
+ .default-mt-btn .mat-stroked-button.mat-primary {
809
+ color: #40189D;
810
+ }
811
+
812
+ .default-mt-btn .example-label {
813
+ font-size: 1rem !important;
814
+ color: #000;
815
+ }
816
+
817
+ .default-mt-btn .example-button-row {
818
+ width: auto !important;
819
+ }
820
+
821
+ .default-mt-btn .example-button-row .mat-button-base {
822
+ margin: 15px 15px 15px 0 !important;
823
+ }
824
+
825
+ .default-mt-btn .mat-flat-button.mat-accent,
826
+ .default-mt-btn .mat-raised-button.mat-accent,
827
+ .default-mt-btn .mat-fab.mat-accent,
828
+ .default-mt-btn .mat-mini-fab.mat-accent {
829
+ background-color: #8BC740;
830
+ }
831
+
832
+ .default-mt-btn .mat-flat-button.mat-accent,
833
+ .default-mt-btn .mat-raised-button.mat-accent,
834
+ .default-mt-btn .mat-fab.mat-accent,
835
+ .default-mt-btn .mat-mini-fab.mat-accent {
836
+ color: #fff;
837
+ }
838
+
839
+ .default-mt-btn .mat-button.mat-accent,
840
+ .default-mt-btn .mat-icon-button.mat-accent,
841
+ .default-mt-btn .mat-stroked-button.mat-accent {
842
+ color: #8BC740;
843
+ }
844
+
845
+ .default-mt-btn .mat-button.mat-accent .mat-button-focus-overlay,
846
+ .default-mt-btn .mat-icon-button.mat-accent .mat-button-focus-overlay,
847
+ .default-mt-btn .mat-stroked-button.mat-accent .mat-button-focus-overlay {
848
+ background-color: #8BC740;
849
+ }
850
+
851
+ .default-mt-btn .mat-button,
852
+ .default-mt-btn .mat-raised-button,
853
+ .default-mt-btn .mat-stroked-button,
854
+ .default-mt-btn .mat-flat-button {
855
+ padding: 0 25px;
856
+ line-height: 55px;
857
+ border-radius: 1.25rem;
858
+ font-size: 1rem;
859
+ }
860
+
861
+ @media only screen and (max-width: 1400px) {
862
+ .default-mt-btn .example-button-row {
863
+ width: auto !important;
864
+ }
865
+
866
+ .default-mt-btn .example-button-row .mat-button-base {
867
+ margin: 10px 10px 10px 0 !important;
868
+ }
869
+
870
+ .default-mt-btn .mat-button,
871
+ .default-mt-btn .mat-raised-button,
872
+ .default-mt-btn .mat-stroked-button,
873
+ .default-mt-btn .mat-flat-button {
874
+ padding: 0 15px;
875
+ line-height: 40px;
876
+ font-size: 14px;
877
+ }
878
+ }
879
+
880
+ @media only screen and (max-width: 575px) {
881
+ .default-mt-btn .btn-list-group {
882
+ display: block !important;
883
+ padding: 10px 0px;
884
+ }
885
+
886
+ .default-mt-btn .btn-list-group .example-label {
887
+ display: block !important;
888
+ }
889
+
890
+ .default-mt-btn .example-button-row {
891
+ width: auto !important;
892
+ }
893
+
894
+ .default-mt-btn .example-button-row .mat-button-base {
895
+ margin: 5px 10px 5px 0 !important;
896
+ }
897
+
898
+ .default-mt-btn .example-button-container {
899
+ width: 80px !important;
900
+ }
901
+ }
902
+
903
+ /* card */
904
+ .default-mt-card .mat-card {
905
+ border-radius: 1.25rem;
906
+ }
907
+
908
+ /* checkbox */
909
+ .default-mt-checkbox .example-section {
910
+ margin: 0 !important;
911
+ }
912
+
913
+ .mat-checkbox-checked:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element,
914
+ .mat-checkbox:active:not(.mat-checkbox-disabled).mat-primary .mat-ripple-element {
915
+ background: #40189D;
916
+ }
917
+
918
+ .mat-checkbox-indeterminate.mat-primary .mat-checkbox-background,
919
+ .mat-checkbox-checked.mat-primary .mat-checkbox-background {
920
+ background-color: #40189D;
921
+ }
922
+
923
+ .mat-primary .mat-pseudo-checkbox-checked,
924
+ .mat-primary .mat-pseudo-checkbox-indeterminate {
925
+ background: #40189D;
926
+ }
927
+
928
+ .mat-primary .mat-option.mat-selected:not(.mat-option-disabled) {
929
+ color: #40189D;
930
+ }
931
+
932
+ .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,
933
+ .mat-checkbox-checked.mat-accent .mat-checkbox-background {
934
+ background-color: #8BC740;
935
+ }
936
+
937
+ .mat-checkbox-checked:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element,
938
+ .mat-checkbox:active:not(.mat-checkbox-disabled).mat-accent .mat-ripple-element {
939
+ background: #8BC740;
940
+ }
941
+
942
+ .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle {
943
+ border-color: #8BC740;
944
+ }
945
+
946
+ .mat-radio-button.mat-accent .mat-radio-inner-circle,
947
+ .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),
948
+ .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,
949
+ .mat-radio-button.mat-accent:active .mat-radio-persistent-ripple,
950
+ .mat-radio-button.mat-accent .mat-radio-inner-circle,
951
+ .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element:not(.mat-radio-persistent-ripple),
952
+ .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-persistent-ripple,
953
+ .mat-radio-button.mat-accent:active .mat-radio-persistent-ripple {
954
+ background-color: #8BC740;
955
+ }
956
+
957
+ .mat-pseudo-checkbox-checked,
958
+ .mat-pseudo-checkbox-indeterminate,
959
+ .mat-accent .mat-pseudo-checkbox-checked,
960
+ .mat-accent .mat-pseudo-checkbox-indeterminate {
961
+ background: #8BC740;
962
+ }
963
+
964
+ /* chips */
965
+ .default-mt-chips .mat-input-element {
966
+ color: rgba(0, 0, 0, 0.6);
967
+ }
968
+
969
+ .default-mt-chips .mat-chip.mat-standard-chip,
970
+ .default-mt-chips .mat-chip.mat-standard-chip.mat-chip-selected.mat-primary {
971
+ background-color: #40189D;
972
+ color: #fff;
973
+ }
974
+
975
+ .default-mt-chips .mat-form-field-appearance-legacy .mat-form-field-label,
976
+ .default-mt-chips .mat-form-field-appearance-legacy .mat-hint,
977
+ .default-mt-chips input.mat-chip-input::placeholder {
978
+ color: rgba(0, 0, 0, 0.54);
979
+ }
980
+
981
+ .default-mt-chips .mat-form-field.mat-focused .mat-form-field-label {
982
+ color: #40189D;
983
+ }
984
+
985
+ .default-mt-chips .mat-form-field.mat-focused .mat-form-field-ripple {
986
+ background-color: #40189D;
987
+ }
988
+
989
+ .default-mt-chips .mat-chip.mat-standard-chip .mat-chip-remove {
990
+ opacity: 1;
991
+ color: rgba(255, 255, 255, 0.8);
992
+ }
993
+
994
+ .default-mt-chips .mat-form-field-appearance-legacy .mat-form-field-underline {
995
+ background-color: rgba(0, 0, 0, 0.42);
996
+ }
997
+
998
+ .default-mt-chips .mat-form-field-infix {
999
+ width: 100%;
1000
+ color: #fff;
1001
+ }
1002
+
1003
+ .default-mt-chips .mat-chip.mat-standard-chip.mat-chip-selected.mat-accent {
1004
+ background-color: #8BC740;
1005
+ color: #fff;
1006
+ }
1007
+
1008
+ /* datepicker */
1009
+ .default-mt-datepicker .mat-form-field-appearance-fill .mat-form-field-flex {
1010
+ background-color: rgba(64, 24, 157, 0.1);
1011
+ }
1012
+
1013
+ .default-mt-datepicker .mat-form-field-label {
1014
+ color: rgba(0, 0, 0, 0.6);
1015
+ }
1016
+
1017
+ .default-mt-datepicker .mat-date-range-input-inner,
1018
+ .default-mt-datepicker .mat-calendar-body-cell-content,
1019
+ .default-mt-datepicker .mat-date-range-input-separator {
1020
+ color: #000;
1021
+ }
1022
+
1023
+ .default-mt-datepicker .mat-icon-button svg path {
1024
+ fill: rgba(0, 0, 0, 0.7);
1025
+ }
1026
+
1027
+ .default-mt-datepicker .mat-form-field.mat-focused .mat-form-field-ripple {
1028
+ background: #40189D;
1029
+ }
1030
+
1031
+ .default-mt-datepicker .mat-form-field.mat-focused .mat-form-field-label {
1032
+ color: #40189D;
1033
+ }
1034
+
1035
+ .default-mt-datepicker .mat-form-field-appearance-fill.mat-form-field-disabled .mat-form-field-label {
1036
+ color: rgba(0, 0, 0, 0.5);
1037
+ }
1038
+
1039
+ .default-mt-datepicker .mat-form-field-appearance-fill .mat-form-field-underline:before {
1040
+ background-color: rgba(0, 0, 0, 0.42);
1041
+ }
1042
+
1043
+ .default-mt-datepicker .mat-input-element:disabled,
1044
+ .default-mt-datepicker .mat-form-field-type-mat-native-select.mat-form-field-disabled .mat-form-field-infix::after {
1045
+ color: #000;
1046
+ }
1047
+
1048
+ .mat-calendar-body-comparison-identical,
1049
+ .mat-calendar-body-in-comparison-range::before {
1050
+ background: rgba(139, 199, 64, 0.2);
1051
+ }
1052
+
1053
+ .mat-calendar-body-selected {
1054
+ background-color: #40189D;
1055
+ }
1056
+
1057
+ .mat-calendar-body-in-range::before {
1058
+ background: rgba(64, 24, 157, 0.1);
1059
+ }
1060
+
1061
+ .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),
1062
+ .cdk-keyboard-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical),
1063
+ .cdk-program-focused .mat-calendar-body-active>.mat-calendar-body-cell-content:not(.mat-calendar-body-selected):not(.mat-calendar-body-comparison-identical) {
1064
+ background-color: rgba(64, 24, 157, 0.3);
1065
+ }
1066
+
1067
+ .mat-datepicker-content-container .example-header button {
1068
+ height: 35px;
1069
+ width: 35px;
1070
+ outline: none;
1071
+ border: 0;
1072
+ border-radius: 35px;
1073
+ font-size: 18px;
1074
+ margin: 0 2px;
1075
+ }
1076
+
1077
+ /* dialog */
1078
+ /* divider */
1079
+ /* expansion */
1080
+ .default-mt-expansion .mat-expansion-panel-header-description {
1081
+ justify-content: space-between;
1082
+ align-items: center;
1083
+ }
1084
+
1085
+ .default-mt-expansion .mat-accordion .mat-expansion-panel:first-of-type {
1086
+ border-top-right-radius: 1.25rem;
1087
+ border-top-left-radius: 1.25rem;
1088
+ }
1089
+
1090
+ .default-mt-expansion .mat-accordion .mat-expansion-panel:last-of-type {
1091
+ border-bottom-right-radius: 1.25rem;
1092
+ border-bottom-left-radius: 1.25rem;
1093
+ }
1094
+
1095
+ .default-mt-expansion .mat-expansion-panel-header {
1096
+ height: auto;
1097
+ padding: 15px 20px !important;
1098
+ }
1099
+
1100
+ /* form-field */
1101
+ .default-mt-formfield .mat-form-field {
1102
+ width: 100%;
1103
+ }
1104
+
1105
+ .default-mt-formfield .mat-form-field-appearance-outline.mat-focused .mat-form-field-outline-thick {
1106
+ color: #40189D;
1107
+ }
1108
+
1109
+ .default-mt-formfield .example-container .mat-form-field+.mat-form-field {
1110
+ margin-left: 0 !important;
1111
+ }
1112
+
1113
+ /* input */
1114
+ .default-mt-input .example-form {
1115
+ width: 100% !important;
1116
+ min-width: 150px;
1117
+ max-width: 100% !important;
1118
+ }
1119
+
1120
+ /* progress */
1121
+ .default-mt-progress .mat-progress-bar-buffer {
1122
+ background-color: #e6defa;
1123
+ }
1124
+
1125
+ .default-mt-progress .mat-progress-bar-fill::after {
1126
+ background-color: #40189D;
1127
+ }
1128
+
1129
+ .default-mt-progress .mat-progress-bar {
1130
+ height: 8px;
1131
+ border-radius: 8px;
1132
+ }
1133
+
1134
+ .default-mt-progress .mat-progress-bar pattern circle {
1135
+ fill: #e6defa;
1136
+ }
1137
+
1138
+ .default-mt-progress .example-section {
1139
+ height: auto !important;
1140
+ }
1141
+
1142
+ .default-mt-progress .mat-progress-bar.mat-accent .mat-progress-bar-fill::after {
1143
+ background-color: #8BC740;
1144
+ }
1145
+
1146
+ .default-mt-progress .mat-progress-bar.mat-accent .mat-progress-bar-background {
1147
+ fill: #8BC740;
1148
+ }
1149
+
1150
+ .default-mt-progress .mat-progress-bar.mat-accent .mat-progress-bar-buffer {
1151
+ background-color: #8BC740;
1152
+ }
1153
+
1154
+ .mat-accent .mat-slider-track-fill,
1155
+ .mat-accent .mat-slider-thumb,
1156
+ .mat-accent .mat-slider-thumb-label {
1157
+ background-color: #8BC740;
1158
+ }
1159
+
1160
+ /* spinner */
1161
+ .mat-progress-spinner.mat-accent circle,
1162
+ .mat-spinner.mat-accent circle {
1163
+ stroke: #8BC740;
1164
+ }
1165
+
1166
+ .mat-progress-spinner circle,
1167
+ .mat-spinner circle {
1168
+ stroke: #40189D;
1169
+ }
1170
+
1171
+ .default-mt-spinner .example-margin {
1172
+ margin: 0 10px;
1173
+ }
1174
+
1175
+ /* select */
1176
+ .default-mt-select .mat-form-field.mat-focused .mat-form-field-label {
1177
+ color: #40189D;
1178
+ }
1179
+
1180
+ /* sidenav */
1181
+ .default-mt-sidenav .example-container {
1182
+ margin: 0 !important;
1183
+ width: 100% !important;
1184
+ height: 350px !important;
1185
+ box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
1186
+ border: 0 !important;
1187
+ }
1188
+
1189
+ .default-mt-sidenav .mat-drawer-content {
1190
+ padding: 25px !important;
1191
+ }
1192
+
1193
+ /* slidetoggle */
1194
+ .default-mt-slidetoggle .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-bar {
1195
+ background-color: #e6defa;
1196
+ }
1197
+
1198
+ .default-mt-slidetoggle .mat-slide-toggle.mat-primary.mat-checked .mat-slide-toggle-thumb {
1199
+ background-color: #40189D;
1200
+ }
1201
+
1202
+ .default-mt-slidetoggle .example-section {
1203
+ height: auto !important;
1204
+ }
1205
+
1206
+ .mat-slide-toggle.mat-checked .mat-slide-toggle-bar {
1207
+ background-color: rgba(139, 199, 64, 0.5);
1208
+ }
1209
+
1210
+ .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb {
1211
+ background-color: #8BC740;
1212
+ }
1213
+
1214
+ .mat-slide-toggle.mat-checked .mat-ripple-element {
1215
+ background-color: #8BC740;
1216
+ }
1217
+
1218
+ /* slider */
1219
+ .default-mt-slider .example-section {
1220
+ display: block !important;
1221
+ height: auto !important;
1222
+ }
1223
+
1224
+ /* sort */
1225
+ /* stepper */
1226
+ .default-mt-stepper .mat-step-header .mat-step-icon-selected,
1227
+ .default-mt-stepper .mat-step-header .mat-step-icon-state-done,
1228
+ .default-mt-stepper .mat-step-header .mat-step-icon-state-edit {
1229
+ background-color: #40189D;
1230
+ }
1231
+
1232
+ @media only screen and (max-width: 575px) {
1233
+ .default-mt-stepper .mat-horizontal-stepper-header-container {
1234
+ display: block;
1235
+ }
1236
+
1237
+ .default-mt-stepper .mat-horizontal-stepper-header-container .mat-horizontal-stepper-header {
1238
+ padding: 0;
1239
+ height: 60px;
1240
+ margin-bottom: 10px;
1241
+ margin-top: 10px;
1242
+ }
1243
+
1244
+ .default-mt-stepper .mat-horizontal-content-container {
1245
+ padding: 0;
1246
+ }
1247
+
1248
+ .default-mt-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child)::before,
1249
+ .default-mt-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child)::before,
1250
+ .default-mt-stepper .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:last-child)::after,
1251
+ .default-mt-stepper [dir=rtl] .mat-stepper-label-position-bottom .mat-horizontal-stepper-header:not(:first-child)::after {
1252
+ content: none;
1253
+ }
1254
+
1255
+ .default-mt-stepper .mat-stepper-label-position-bottom .mat-stepper-horizontal-line {
1256
+ top: 0;
1257
+ }
1258
+ }
1259
+
1260
+ /* table */
1261
+ .default-mt-table .mat-elevation-z8 {
1262
+ box-shadow: none;
1263
+ }
1264
+
1265
+ .default-mt-table .table-responsive {
1266
+ border-radius: 1.25rem;
1267
+ position: relative;
1268
+ z-index: 1;
1269
+ }
1270
+
1271
+ .default-mt-table .mat-header-cell {
1272
+ color: #000;
1273
+ padding: 0 10px;
1274
+ font-size: 16px;
1275
+ font-weight: 500;
1276
+ }
1277
+
1278
+ .default-mt-table .mat-footer-cell {
1279
+ padding: 0 10px;
1280
+ }
1281
+
1282
+ .default-mt-table .mat-cell {
1283
+ padding: 0 10px;
1284
+ }
1285
+
1286
+ .default-mt-table .example-element-diagram {
1287
+ min-width: 100px !important;
1288
+ font-weight: 400 !important;
1289
+ height: 130px !important;
1290
+ }
1291
+
1292
+ .default-mt-table mat-row,
1293
+ .default-mt-table mat-header-row,
1294
+ .default-mt-table mat-footer-row,
1295
+ .default-mt-table th.mat-header-cell,
1296
+ .default-mt-table td.mat-cell,
1297
+ .default-mt-table td.mat-footer-cell {
1298
+ border-color: #EEEEEE;
1299
+ }
1300
+
1301
+ .default-mt-table .stickyColumns-table .mat-table-sticky {
1302
+ background: #40189D !important;
1303
+ }
1304
+
1305
+ .default-mt-table .stickyColumns-table .mat-table-sticky .mat-header-cell {
1306
+ color: #fff;
1307
+ }
1308
+
1309
+ .default-mt-table .stickyColumns-table .mat-table-sticky .mat-cell {
1310
+ color: #fff;
1311
+ }
1312
+
1313
+ .default-mt-table .stickyColumns-table .mat-table-sticky .mat-footer-cell {
1314
+ color: #fff;
1315
+ }
1316
+
1317
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-left,
1318
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-right,
1319
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-bottom,
1320
+ .default-mt-table .stickyColumns-table .mat-table-sticky-border-elem-top {
1321
+ border-color: #fff;
1322
+ color: #fff;
1323
+ }
1324
+
1325
+ .default-mt-table .stickyColumns-table .mat-column-filler {
1326
+ font-size: 12px;
1327
+ }
1328
+
1329
+ .default-mt-table .stickyColumns-table mat-cell:first-of-type,
1330
+ .default-mt-table .stickyColumns-table mat-header-cell:first-of-type,
1331
+ .default-mt-table .stickyColumns-table mat-footer-cell:first-of-type {
1332
+ padding-right: 10px;
1333
+ }
1334
+
1335
+ .default-mt-table .stickyColumns-table mat-cell:last-of-type,
1336
+ .default-mt-table .stickyColumns-table mat-header-cell:last-of-type,
1337
+ .default-mt-table .stickyColumns-table mat-footer-cell:last-of-type {
1338
+ padding-left: 10px;
1339
+ }
1340
+
1341
+ .default-mt-table .stickyColumns-table .mat-header-cell,
1342
+ .default-mt-table .stickyColumns-table .mat-footer-cell,
1343
+ .default-mt-table .stickyColumns-table .mat-cell {
1344
+ min-width: 100px !important;
1345
+ }
1346
+
1347
+ .default-mt-table .stickyColumns-table .mat-header-row,
1348
+ .default-mt-table .stickyColumns-table .mat-footer-row,
1349
+ .default-mt-table .stickyColumns-table .mat-row {
1350
+ min-width: 2300px !important;
1351
+ }
1352
+
1353
+ /* tabs */
1354
+ .default-mt-tabs .mat-tab-group.mat-primary .mat-ink-bar,
1355
+ .default-mt-tabs .mat-tab-nav-bar.mat-primary .mat-ink-bar {
1356
+ background-color: #40189D;
1357
+ }
1358
+
1359
+ .default-mt-tabs .mat-tab-body-content {
1360
+ padding: 10px 15px;
1361
+ }
1362
+
1363
+ .default-mt-tabs .mat-tab-group.mat-background-primary>.mat-tab-header,
1364
+ .default-mt-tabs .mat-tab-group.mat-background-primary>.mat-tab-link-container,
1365
+ .default-mt-tabs .mat-tab-group.mat-background-primary>.mat-tab-header-pagination,
1366
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-primary>.mat-tab-header,
1367
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-primary>.mat-tab-link-container,
1368
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-primary>.mat-tab-header-pagination {
1369
+ background-color: #40189D;
1370
+ }
1371
+
1372
+ .default-mt-tabs .mat-tab-group.mat-background-accent>.mat-tab-header,
1373
+ .default-mt-tabs .mat-tab-group.mat-background-accent>.mat-tab-link-container,
1374
+ .default-mt-tabs .mat-tab-group.mat-background-accent>.mat-tab-header-pagination,
1375
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-accent>.mat-tab-header,
1376
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-accent>.mat-tab-link-container,
1377
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-accent>.mat-tab-header-pagination {
1378
+ background-color: #8BC740;
1379
+ }
1380
+
1381
+ .default-mt-tabs .mat-tab-group.mat-accent.mat-background-accent>.mat-tab-header .mat-ink-bar,
1382
+ .default-mt-tabs .mat-tab-group.mat-accent.mat-background-accent>.mat-tab-link-container .mat-ink-bar,
1383
+ .default-mt-tabs .mat-tab-nav-bar.mat-accent.mat-background-accent>.mat-tab-header .mat-ink-bar,
1384
+ .default-mt-tabs .mat-tab-nav-bar.mat-accent.mat-background-accent>.mat-tab-link-container .mat-ink-bar {
1385
+ background-color: #fff;
1386
+ }
1387
+
1388
+ .default-mt-tabs .mat-tab-group.mat-background-accent>.mat-tab-header .mat-tab-label,
1389
+ .default-mt-tabs .mat-tab-group.mat-background-accent>.mat-tab-link-container .mat-tab-link,
1390
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-accent>.mat-tab-header .mat-tab-label,
1391
+ .default-mt-tabs .mat-tab-nav-bar.mat-background-accent>.mat-tab-link-container .mat-tab-link {
1392
+ color: rgba(255, 255, 255, 0.8);
1393
+ }
1394
+
1395
+ /* tree */
1396
+ .default-mt-tree .mat-checkbox-layout {
1397
+ margin: 0;
1398
+ }
1399
+
1400
+ .default-mt-tree .mat-tree {
1401
+ background: rgba(0, 0, 0, 0.05);
1402
+ overflow: auto;
1403
+ }
1404
+
1405
+ /* toolbar */
1406
+ .default-mt-toolbar .mat-toolbar.mat-primary {
1407
+ background: #40189D;
1408
+ }
1409
+
1410
+ /*# 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/dashboard1.css ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .btn-primary {
2
+ background-color: #0d6efd;
3
+ border-radius: 5px;
4
+ border-color: #0d6efd;
5
+ }
6
+
7
+ #sidebarToggle {
8
+ border-radius: 4px;
9
+ margin-left: 250px;
10
+ }
11
+
12
+ .main-sidebar.toggled .menu-text {
13
+ display: none;
14
+ }
15
+
16
+ #selectedCompany.toggled .menu-text {
17
+ display: none;
18
+ }
19
+
20
+ .wrapper {
21
+ flex: 1;
22
+ padding: 10px;
23
+ margin-left: 250px;
24
+ /* Default sidebar width */
25
+ transition: margin-left 0.3s ease;
26
+ }
27
+
28
+ .main-header {
29
+ border-bottom: none;
30
+ border-top: none;
31
+ }
32
+
33
+ .card {
34
+ margin-bottom: 15px;
35
+ border-radius: 8px;
36
+ overflow: hidden;
37
+ transition: background-color 0.3s ease;
38
+ }
39
+
40
+ .card-body {
41
+ padding: 15px;
42
+ }
43
+
44
+ .feature-icon {
45
+ display: inline-flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ width: 50px;
49
+ height: 50px;
50
+ background: rgba(255, 255, 255, 0.1);
51
+ border-radius: 50%;
52
+ }
53
+
54
+ .sidebarPanel {
55
+ display: none;
56
+ }
57
+
58
+ .media-body {
59
+ text-align: right;
60
+ overflow: hidden;
61
+ }
62
+
63
+ .fs-30 {
64
+ font-size: 1.875rem;
65
+ }
66
+
67
+ .fs-48 {
68
+ font-size: 3rem;
69
+ }
70
+
71
+
72
+
73
+
74
+
75
+ @media screen and (max-width:1030px) {
76
+ .wrapper {
77
+ padding: 10px;
78
+ margin-left: 0px;
79
+ }
80
+
81
+
82
+ .fs-30 {
83
+ font-size: 1.3rem !important;
84
+ }
85
+
86
+ .fs-48 {
87
+ font-size: 2rem !important;
88
+ }
89
+
90
+ }
static/css/data_connectors.css ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #add {
2
+ display: none;
3
+ }
4
+
5
+
6
+
7
+ /* .container {
8
+ margin-top: 50px;
9
+ margin-left: 320px;
10
+ max-width: 800px;
11
+ padding: 10px;
12
+ border: 1px solid #ccc;
13
+ border-radius: 5px;
14
+ background-color: #fff;
15
+ position: relative;
16
+ z-index: 1;
17
+ } */
18
+
19
+ .form-group {
20
+ margin-bottom: 20px;
21
+ }
22
+
23
+ .form-group label {
24
+ font-weight: bold;
25
+ margin-top: -10px;
26
+ margin-left: -22px;
27
+ display: block;
28
+ }
29
+
30
+ .form-group input,
31
+ .form-group select,
32
+ .form-group textarea {
33
+ width: 100%;
34
+ margin-left: -22px;
35
+ padding: 2px;
36
+ border: 1px solid #ccc;
37
+ border-radius: 4px;
38
+ }
39
+
40
+ .btn-primary {
41
+ margin-right: 10px;
42
+ color: white;
43
+ font-size: 16px;
44
+ font-weight: bold;
45
+ }
46
+
47
+ /* .btn-container {
48
+ text-align: center;
49
+ margin-top: 20px;
50
+ margin-bottom: 10px;
51
+ } */
52
+ .btn-primary {
53
+ margin-right: 10px;
54
+ color: white;
55
+ font-size: 16px;
56
+ font-weight: bold;
57
+ }
58
+
59
+
60
+ .btn-container {
61
+ text-align: center;
62
+ margin-top: 30px;
63
+ margin-left: 20px;
64
+ margin-right: 0px;
65
+ margin-bottom: 10px;
66
+ /* color: white; */
67
+ }
68
+
69
+ .btn-container1 {
70
+ text-align: center;
71
+ margin-top: 50px;
72
+ margin-left: 30px;
73
+ margin-right: 30px;
74
+ margin-bottom: 10px;
75
+ color: white;
76
+ }
77
+
78
+ /* #selectedTables,
79
+ #labelselected {
80
+ display: none;
81
+ } */
82
+ .btn-primary:focus,
83
+ .btn-primary:active {
84
+ color: white;
85
+ background-color: #007bff;
86
+ border-color: #007bff;
87
+ box-shadow: none;
88
+ }
89
+
90
+ #saveBtn1 {
91
+
92
+ margin: 0 auto;
93
+ }
94
+
95
+ /* footer {
96
+ position: relative;
97
+ margin-top: auto;
98
+ width: 100%;
99
+ color: black;
100
+ text-align: right;
101
+ padding-right: 245px;
102
+ padding-top: 20px;
103
+ background-color: #f8f9fa;
104
+ border: none !important;
105
+ }
106
+ */
107
+ .small-select {
108
+ margin-top: 5px;
109
+ width: 200px;
110
+ /* Adjust the width as needed */
111
+ }
112
+
113
+ .custom-dropdown {
114
+ width: 250px;
115
+ /* Adjust the width as needed */
116
+ }
117
+
118
+ /* Ensure the new row aligns with the previous row */
119
+ #schema-table-section {
120
+
121
+ margin-left: -20px;
122
+ /* Adjust this if you need spacing between rows */
123
+ padding-top: 5px;
124
+ /* Adjust padding if needed */
125
+ }
126
+
127
+ .alert {
128
+ position: relative;
129
+ padding: 15px;
130
+ margin-bottom: 20px;
131
+ border: 1px solid transparent;
132
+ border-radius: 4px;
133
+ }
134
+
135
+ .alert-success {
136
+ color: #3c763d;
137
+ background-color: #dff0d8;
138
+ border-color: #d6e9c6;
139
+ }
140
+
141
+ .alert-danger {
142
+ color: #a94442;
143
+ background-color: #f2dede;
144
+ border-color: #ebccd1;
145
+ }
146
+
147
+ .close {
148
+ position: absolute;
149
+ bottom: 10px;
150
+ right: 10px;
151
+ border: none;
152
+ background: none;
153
+ font-size: 16px;
154
+ cursor: pointer;
155
+ }
156
+
157
+ .wrapper {
158
+ margin-left: 100px;
159
+ overflow: hidden;
160
+ padding: 0% !important;
161
+
162
+ }
163
+
164
+ .main-header {
165
+ width: 80%;
166
+ margin-top: 100px;
167
+ border: none;
168
+
169
+
170
+
171
+ }
172
+
173
+ @media screen and (max-width:990px) {
174
+ .wrapper {
175
+ margin-left: 0%;
176
+ overflow: none;
177
+ width: auto;
178
+ z-index: 1;
179
+
180
+ }
181
+
182
+
183
+ .main-header {
184
+ margin-top: 0%;
185
+ width: 100%;
186
+ padding: 10px;
187
+ border: none;
188
+ padding-left: 40px;
189
+
190
+ }
191
+
192
+
193
+ .form-group {
194
+ margin-top: 5px;
195
+ width: 100% !important;
196
+ justify-content: center !important;
197
+ column-gap: 50px;
198
+
199
+ }
200
+
201
+ }
202
+
203
+ @media screen and (max-width:770px) {
204
+ .form-group button {
205
+
206
+ margin-bottom: 10px !important;
207
+ margin-left: -40px;
208
+ margin-right: 45px !important;
209
+ width: 110%;
210
+
211
+ }
212
+
213
+ }
static/css/index.css ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ body {
6
+ background: #f6f5f7;
7
+ flex-direction: column;
8
+ font-family: 'Montserrat', sans-serif;
9
+ height: 100vh;
10
+ margin: 0;
11
+
12
+ }
13
+
14
+ h1 {
15
+ font-weight: bold;
16
+ margin: 0;
17
+ }
18
+
19
+ h2 {
20
+ text-align: center;
21
+ }
22
+
23
+ p {
24
+ font-size: 14px;
25
+ font-weight: 100;
26
+ line-height: 20px;
27
+ letter-spacing: 0.5px;
28
+ margin: 20px 0 30px;
29
+ }
30
+
31
+ a {
32
+ color: #333;
33
+ font-size: 14px;
34
+ text-decoration: none;
35
+ }
36
+
37
+ button {
38
+ border-radius: 20px;
39
+ border: 1px solid #1c6bae;
40
+ background-color: #1c6bae;
41
+ color: #FFFFFF;
42
+ font-size: 14px;
43
+ font-weight: bold;
44
+ padding: 12px 45px;
45
+ margin-top: 20px;
46
+ letter-spacing: 1px;
47
+ text-transform: uppercase;
48
+ cursor: pointer;
49
+ transition: all 0.3s ease;
50
+ }
51
+
52
+ button:hover {
53
+ background-color: #155a8b;
54
+ transform: scale(1.05);
55
+ }
56
+
57
+ form {
58
+ display: flex;
59
+ align-items: center;
60
+ justify-content: center;
61
+ flex-direction: column;
62
+ padding: 0 50px;
63
+ height: 100%;
64
+ text-align: center;
65
+ }
66
+
67
+ input {
68
+ background-color: #eee;
69
+ border: none;
70
+ padding: 12px 15px;
71
+ margin: 8px 0;
72
+ width: 100%;
73
+ border-radius: 5px;
74
+ }
75
+
76
+ .container {
77
+ background-color: #fff;
78
+ border-radius: 12px;
79
+ box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25),
80
+ 0 10px 10px rgba(0, 0, 0, 0.22);
81
+ position: relative;
82
+ width: 900px;
83
+ max-width: 100%;
84
+ min-height: 500px;
85
+ }
86
+
87
+ .form-container {
88
+ position: absolute;
89
+ top: 0;
90
+ height: 100%;
91
+ transition: all 0.6s ease-in-out;
92
+ width: 50%;
93
+ }
94
+
95
+ .sign-in-container {
96
+ left: 0;
97
+ z-index: 2;
98
+ }
99
+
100
+ .container.right-panel-active .sign-in-container {
101
+ transform: translateX(100%);
102
+ }
103
+
104
+ .sign-up-container {
105
+ left: 0;
106
+ opacity: 0;
107
+ z-index: 1;
108
+ }
109
+
110
+ .container.right-panel-active .sign-up-container {
111
+ transform: translateX(100%);
112
+ opacity: 1;
113
+ z-index: 5;
114
+ animation: show 0.6s;
115
+ }
116
+
117
+ @keyframes show {
118
+
119
+ 0%,
120
+ 49.99% {
121
+ opacity: 0;
122
+ z-index: 1;
123
+ }
124
+
125
+ 50%,
126
+ 100% {
127
+ opacity: 1;
128
+ z-index: 5;
129
+ }
130
+ }
131
+
132
+ .overlay-container {
133
+ position: absolute;
134
+ top: 0;
135
+ left: 50%;
136
+ width: 50%;
137
+ height: 100%;
138
+ overflow: hidden;
139
+ transition: transform 0.6s ease-in-out;
140
+ z-index: 100;
141
+ }
142
+
143
+ .container.right-panel-active .overlay-container {
144
+ transform: translateX(-100%);
145
+ }
146
+
147
+ .overlay {
148
+ background: linear-gradient(to right, #1c6bae, #1c6bae);
149
+ color: #FFFFFF;
150
+ position: relative;
151
+ left: -100%;
152
+ height: 100%;
153
+ width: 200%;
154
+ transform: translateX(0);
155
+ transition: transform 0.6s ease-in-out;
156
+ border-radius: 12px;
157
+
158
+ }
159
+
160
+ .container.right-panel-active .overlay {
161
+ transform: translateX(50%);
162
+ }
163
+
164
+ .overlay-panel {
165
+ position: absolute;
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: center;
169
+ flex-direction: column;
170
+ padding: 0 40px;
171
+ text-align: center;
172
+ top: 0;
173
+ height: 100%;
174
+ width: 50%;
175
+ transform: translateX(0);
176
+ transition: transform 0.6s ease-in-out;
177
+ }
178
+
179
+ .overlay-left {
180
+ transform: translateX(-20%);
181
+ }
182
+
183
+ .container.right-panel-active .overlay-left {
184
+ transform: translateX(0);
185
+ }
186
+
187
+ .overlay-right {
188
+ right: 0;
189
+ transform: translateX(0);
190
+ }
191
+
192
+ .container.right-panel-active .overlay-right {
193
+ transform: translateX(20%);
194
+ }
195
+
196
+ .social-container {
197
+ margin: 20px 0;
198
+ }
199
+
200
+ .social-container a {
201
+ border: 1px solid #DDDDDD;
202
+ border-radius: 50%;
203
+ display: inline-flex;
204
+ justify-content: center;
205
+ align-items: center;
206
+ margin: 0 5px;
207
+ height: 40px;
208
+ width: 40px;
209
+ }
210
+
211
+ .logo-container {
212
+ display: flex;
213
+ justify-content: center;
214
+ align-items: center;
215
+ margin-bottom: 20px;
216
+ }
217
+
218
+ .logo {
219
+ border-radius: 50%;
220
+ background-color: white;
221
+ padding: 20px;
222
+ width: 150px;
223
+ height: 150px;
224
+ object-fit: contain;
225
+ }
226
+
227
+ footer {
228
+ background-color: #222;
229
+ color: #fff;
230
+ font-size: 14px;
231
+ padding: 10px;
232
+ text-align: center;
233
+ position: absolute;
234
+ width: 100%;
235
+ bottom: 0;
236
+ left: 0;
237
+ height: 10dvh;
238
+ margin-top: 202px !important;
239
+ }
240
+
241
+ footer i {
242
+ color: red;
243
+ }
244
+
245
+ footer a {
246
+ color: #3c97bf;
247
+ text-decoration: none;
248
+ }
249
+ main{
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ height: 90dvh;
254
+ }
255
+
256
+ /* Responsive Adjustments */
257
+ @media screen and (max-width: 768px) {
258
+ .container {
259
+ width: 100%;
260
+ height: auto;
261
+ }
262
+
263
+ .form-container {
264
+ width: 100%;
265
+ }
266
+
267
+ .overlay-container {
268
+ display: none;
269
+ }
270
+ body{
271
+ padding: 0px 10px;
272
+ }
273
+ }
static/css/knowledgebase.css ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ background-color: transparent !important;
3
+ }
4
+
5
+ .content-wrapper {
6
+ flex: 1;
7
+ overflow-y: auto;
8
+ }
9
+
10
+ .wrapper {
11
+ display: flex;
12
+ flex-direction: column;
13
+ height: 100vh;
14
+ }
15
+
16
+
17
+ .modal-content {
18
+ background-color: #fff;
19
+ }
20
+
21
+ .content-header {
22
+ padding: 1rem;
23
+ }
24
+
25
+ h1 {
26
+ text-align: center;
27
+ margin-bottom: 30px;
28
+ }
29
+
30
+ .card {
31
+ padding: 0;
32
+ margin-top: -15px;
33
+ margin-left: -40px;
34
+ }
35
+
36
+ .table-responsive {
37
+ width: 100%;
38
+ overflow-x: auto;
39
+ /*overflow-y: scroll;*/
40
+ /* Allows horizontal scrolling if necessary */
41
+ }
42
+
43
+ .table,
44
+ .table-bordered {
45
+ width: 100%;
46
+ border-collapse: collapse;
47
+ margin-right: 7.5px;
48
+ }
49
+
50
+
51
+ .text-wrap {
52
+ white-space: normal !important;
53
+ word-break: break-word;
54
+ }
55
+
56
+ div.dataTables_wrapper div.dataTables_length select {
57
+ width: 60px;
58
+ display: inline-block;
59
+ }
60
+
61
+ th {
62
+ white-space: nowrap;
63
+ }
64
+
65
+ th:nth-child(1),
66
+ td:nth-child(1) {
67
+ /* Sno column */
68
+ width: 2%;
69
+ }
70
+
71
+ th:nth-child(2),
72
+ td:nth-child(2) {
73
+ /* Document Name column */
74
+ width: auto;
75
+ }
76
+
77
+ th:nth-child(3),
78
+ td:nth-child(3) {
79
+ /* Document Description column */
80
+ width: auto;
81
+ }
82
+
83
+ th:nth-child(4),
84
+ td:nth-child(4) {
85
+ /* Document Version column */
86
+ width: 20%;
87
+ }
88
+
89
+ th:nth-child(5),
90
+ td:nth-child(5) {
91
+ /* VectorDB Flag column */
92
+ width: auto;
93
+ }
94
+
95
+ th:nth-child(6),
96
+ td:nth-child(6) {
97
+ /* View column */
98
+ width: 10%;
99
+ }
100
+
101
+ th:nth-child(7),
102
+ td:nth-child(7) {
103
+ /* Edit column */
104
+ width: 10%;
105
+ }
106
+
107
+ th:nth-child(8),
108
+ td:nth-child(8) {
109
+ /* Delete column */
110
+ width: auto;
111
+ }
112
+
113
+ .alert {
114
+ position: relative;
115
+ padding: 15px;
116
+ margin-bottom: 20px;
117
+ border: 1px solid transparent;
118
+ border-radius: 4px;
119
+ }
120
+
121
+ .alert-success {
122
+ color: #3c763d;
123
+ background-color: #dff0d8;
124
+ border-color: #d6e9c6;
125
+ }
126
+
127
+ .alert-danger {
128
+ color: #a94442;
129
+ background-color: #f2dede;
130
+ border-color: #ebccd1;
131
+ }
132
+
133
+ /* .close {
134
+ position: absolute;
135
+ bottom: 10px;
136
+ right: 10px;
137
+ border: none;
138
+ background: none;
139
+ font-size: 16px;
140
+ cursor: pointer;
141
+ } */
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/prompt_template.css ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .header-row {
2
+ display: flex;
3
+ justify-content: space-between;
4
+ align-items: center;
5
+ }
6
+
7
+ .card {
8
+ padding: 0;
9
+ margin-top: -15px;
10
+ margin-left: -40px;
11
+ }
12
+
13
+ .table-container {
14
+ width: 100%;
15
+ overflow-x: auto;
16
+
17
+ }
18
+
19
+ .wrapper {
20
+ display: flex;
21
+ flex-direction: column;
22
+ height: 100vh;
23
+ }
24
+
25
+ .content-wrapper {
26
+ flex: 1;
27
+ overflow-y: auto;
28
+ }
29
+
30
+ .content-header {
31
+ padding: 5px;
32
+
33
+ }
34
+
35
+ div.dataTables_wrapper div.dataTables_length select {
36
+ width: 60px;
37
+ display: inline-block;
38
+ }
39
+
40
+ th,
41
+ td {
42
+ white-space: nowrap;
43
+ }
44
+
45
+ th:nth-child(1),
46
+ td:nth-child(1) {
47
+ /* Sno column */
48
+ width: 1%;
49
+ }
50
+
51
+ th:nth-child(2),
52
+ td:nth-child(2) {
53
+ /* API Name column */
54
+ width: 20%;
55
+ }
56
+
57
+ th:nth-child(3),
58
+ td:nth-child(3) {
59
+ /* API Endpoint column */
60
+ width: 45%;
61
+ }
62
+
63
+ th:nth-child(4),
64
+ td:nth-child(4) {
65
+ /* view column*/
66
+ width: 5%;
67
+ }
68
+
69
+ th:nth-child(5),
70
+ td:nth-child(5) {
71
+ /* view column*/
72
+ width: 5%;
73
+ }
74
+
75
+ th:nth-child(6),
76
+ td:nth-child(6) {
77
+ /* view column*/
78
+ width: 5%;
79
+ }
80
+
81
+ .reduced-width {
82
+ width: 25%;
83
+ }
84
+
85
+ .viewButton {
86
+ size: 2px;
87
+ }
88
+
89
+ div.dataTables_wrapper div.dataTables_length select {
90
+ width: 60px;
91
+ display: inline-block;
92
+ }
93
+
94
+
static/css/sidepane.css ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .main-sidebar {
2
+ background: #222;
3
+ color: #fff;
4
+ width: 250px;
5
+ height: 100vh;
6
+ overflow-y: auto;
7
+ position: fixed;
8
+ top: 0;
9
+ left: 0;
10
+ z-index: 10;
11
+ transition: all 0.3s ease;
12
+ padding-top: 150px;
13
+ }
14
+
15
+ .sidebar-header {
16
+ padding: 15px;
17
+ background: #333;
18
+ color: #fff;
19
+ margin-bottom: 15px;
20
+ display: flex;
21
+ align-items: center;
22
+ }
23
+
24
+ .sidebar-header .nav-icon {
25
+ margin-right: 10px;
26
+ }
27
+
28
+ .nav-link {
29
+ display: flex;
30
+ align-items: center;
31
+ color: #fff;
32
+ padding: 10px;
33
+ border-radius: 5px;
34
+ transition: background-color 0.3s ease;
35
+ text-decoration: none;
36
+ opacity: 0.5;
37
+
38
+ }
39
+
40
+ .nav-link:hover {
41
+ background-color: #F8BE12;
42
+ }
43
+
44
+ .toggle-section {
45
+ display: none;
46
+ /* Initially hidden */
47
+ }
48
+
49
+ .nav-item a i {
50
+ margin-right: 5px;
51
+ margin-top: -10px;
52
+ }
53
+ #addnewcompany{
54
+ margin-left: 25%;
55
+ max-width: 800px;
56
+
57
+ }
58
+
59
+ @media screen and (max-width: 1030px) {
60
+ .main-sidebar {
61
+ display: none;
62
+ }
63
+
64
+ #add,
65
+ #logout {
66
+ font-size: 12px !important;
67
+ }
68
+ #addnewcompany{
69
+ margin-left: 15px;
70
+
71
+
72
+ }
73
+
74
+
75
+ }
76
+
77
+ @media screen and (max-width: 990px) {
78
+
79
+ .logo {
80
+ display: none;
81
+ }
82
+ }
83
+
84
+ @media screen and (max-width: 530px) {
85
+
86
+ .title {
87
+ font-size: 18px;
88
+ }
89
+
90
+ #title {
91
+ display: none;
92
+ }
93
+ }
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,523 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
8
+ <!-- Include AdminLTE CSS -->
9
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1/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
+ <link rel="stylesheet" href="/static/css/API_connectors.css">
16
+
17
+ </head>
18
+
19
+ <body>
20
+ {% include 'sidepane.html' %}
21
+
22
+ <div class="wrapper">
23
+ <div class="main-header" style="border-bottom: none;">
24
+ <!-- Content Header (Page header) -->
25
+ <div class="content-header">
26
+ <div class="container-fluid">
27
+ <div class="container mt-2">
28
+ <div class="form-group left-align" id="company-select">
29
+ <h4 id="selectedCompany" style="margin-left: 300px;"></h4>
30
+
31
+ <!-- <div class="col-12 d-flex justify-content-end mb-3">
32
+ <button class="btn btn-primary"
33
+ style="margin-top: -40px;margin-right: -25px;position: fixed;" id="add">Add</button>
34
+ </div> -->
35
+ </div>
36
+ <div class="row">
37
+ <div id="message-container" style="margin-left: 200px; width:500px;"></div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <h3 id="company_name" style="margin-left: 400px;">{{company_name}}</h3>
43
+ <section class="content" id="contentSection" style="display: none;">
44
+ <div class="container-fluid">
45
+ <div class="form-group">
46
+ <!-- <label for="company_id">company_id</label>--->
47
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
48
+ </div>
49
+ </div>
50
+
51
+
52
+ <!-- Main content -->
53
+ <section class="content">
54
+ <div class="container-fluid">
55
+ <div class="row">
56
+ <div class="col-12">
57
+ <div class="card">
58
+ <div class="card-body table-container">
59
+ <table id="apiTable" class="table table-bordered table-striped">
60
+ <thead>
61
+ <tr>
62
+ <th>Sno</th>
63
+ <th>API Name</th>
64
+ <th>API Endpoint</th>
65
+ <th>View</th>
66
+ <th>Edit</th>
67
+ <th>Delete</th>
68
+ </tr>
69
+ </thead>
70
+ <tbody>
71
+ <!-- <tr>
72
+ <td>1</td>
73
+ <td>Warehouse</td>
74
+ <td>http://193.203.162.39:9090/nxt-wms/userWarehouse/fetchWarehouseForUserId
75
+ </td>
76
+ <td><button class="btn btn-primary viewButton">View</button></td>
77
+ </tr>
78
+ <tr>
79
+ <td>2</td>
80
+ <td>customer</td>
81
+ <td>http://193.203.162.39:9090/nxt-wms/userCustomer/fetchCustomerForUserId
82
+ </td>
83
+ <td><button class="btn btn-primary viewButton">View</button></td>
84
+ </tr>
85
+ <tr>
86
+ <td>3</td>
87
+ <td>SKU</td>
88
+ <td>http://193.203.162.39:9090/nxt-wms/sku/autoComplete?</td>
89
+ <td><button class="btn btn-primary viewButton">View</button></td>
90
+ </tr>
91
+ <tr>
92
+ <td>4</td>
93
+ <td>ASN</td>
94
+ <td>http://193.203.162.39:9090/nxt-wms/trnHeader</td>
95
+ <td><button class="btn btn-primary viewButton">View</button></td>
96
+ </tr> -->
97
+ </tbody>
98
+ </table>
99
+ </div>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </section>
105
+ </div>
106
+
107
+ </div>
108
+
109
+ <!-- Modal -->
110
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
111
+ aria-hidden="true">
112
+ <div class="modal-dialog" style="margin-top: -10px;" role="document">
113
+ <div class="modal-content">
114
+ <div class="modal-header">
115
+ <h5 class="modal-title" id="addModalLabel">Add API Details</h5>
116
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
117
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false">&times;</span>
118
+ </button>
119
+ </div>
120
+ <div class="modal-body">
121
+ <div class="form-group">
122
+ <!-- <label for="company_id">company_id</label>--->
123
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
124
+ </div>
125
+ <form id="documentForm">
126
+ <div class="form-group">
127
+ <label for="APIName">API Name <span class="text-danger">*</span></label>
128
+ <input type="text" class="form-control" id="APIName" name="APIName" required>
129
+ </div>
130
+ <div class="form-group">
131
+ <label for="APIEndpoint">API Endpoint <span class="text-danger">*</span></label>
132
+ <input type="text" class="form-control" id="APIEndpoint" name="APIEndpoint" required>
133
+ </div>
134
+ <div class="form-group">
135
+ <label for="Auth_Bearer">Auth/Bearer token <span class="text-danger">*</span></label>
136
+ <input type="text" class="form-control" id="Auth_Bearer" name="Auth_Bearer" required>
137
+ </div>
138
+ <div class="form-group">
139
+ <label for="Inputjson">Input parameter <span class="text-danger">*</span></label>
140
+ <input type="text" class="form-control" id="Inputjson" name="Inputjson" required>
141
+ </div>
142
+ <div class="form-group">
143
+ <label for="OutputJson">Output Json <span class="text-danger">*</span></label>
144
+ <input type="text" class="form-control" id="OutputJson" name="OutputJson" required>
145
+ </div>
146
+ <div class="form-group">
147
+ <label for="Description">Description <span class="text-danger">*</span></label>
148
+ <textarea class="form-control" id="Description" name="Description" rows="3"
149
+ required></textarea>
150
+ </div>
151
+ </form>
152
+ </div>
153
+ <div class="modal-footer">
154
+ <!-- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> -->
155
+ <button type="button" id="saveupdate" class="btn btn-primary" style="display: none;">Update</button>
156
+ <button type="button" id="save" onclick="save_file()" class="btn btn-primary">Save</button>
157
+ </div>
158
+ </div>
159
+ </div>
160
+ </div>
161
+
162
+ {%include 'footer.html'%}
163
+
164
+ <!-- Include DataTables JS and your custom script -->
165
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
166
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
167
+
168
+
169
+ <script>
170
+ $(document).ready(function () {
171
+ // Show modal function
172
+ $('#add').on('click', function () {
173
+ const modalTitle = document.getElementById('addModalLabel');
174
+ modalTitle.textContent = 'Add API Details';
175
+ clearFormFields();
176
+ $('#save').show();
177
+ $('#saveupdate').hide();
178
+ $('#message-container').empty(); // Clear the message container
179
+ $('#addModal').modal('show');
180
+ });
181
+ $('.modal-footer .btn-secondary, .modal-header .close').on('click', function () {
182
+ $('#addModal').modal('hide');
183
+ });
184
+ // $('#apiTable').DataTable({
185
+ // autoWidth: false
186
+ // });
187
+
188
+ });
189
+ var table = $('#apiTable').DataTable();
190
+ const role = sessionStorage.getItem('userRole');
191
+ console.log('Current role:', role); // Debug statement to check the role
192
+ const company_name = sessionStorage.getItem('company_name');
193
+ console.log("company_name", company_name);
194
+ // document.getElementById('company_name').textContent = company_name;
195
+ const passedCompanyName = sessionStorage.getItem('company_name')
196
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
197
+ const company_id = sessionStorage.getItem('company_id');
198
+ document.getElementById("company_id").value = company_id;
199
+
200
+ data_get_from_db(company_id);
201
+
202
+
203
+ const companySelect = document.getElementById('company');
204
+ const documentForm = document.getElementById('documentForm');
205
+
206
+
207
+ function moveToNextInput(inputs, currentIndex) {
208
+ const nextInput = inputs[currentIndex + 1];
209
+ if (nextInput) {
210
+ nextInput.focus();
211
+ } else {
212
+ // Optionally, submit the form or trigger the save button
213
+ document.getElementById("save").focus();
214
+ }
215
+ }
216
+
217
+
218
+ function displayErrorMessage(message) {
219
+ const messageContainer = document.getElementById('message-container');
220
+ if (messageContainer) {
221
+ messageContainer.innerHTML = `<div class='alert alert-danger'>${message}</div>`;
222
+ }
223
+ }
224
+
225
+
226
+
227
+
228
+ async function data_get_from_db(companyId) {
229
+ if (companyId) {
230
+ try {
231
+ console.log('comp_id', companyId)
232
+ const Response = await fetch(`/api/get_api_connectors?company_id=${companyId}`);
233
+ console.log("responce from api :==> ", Response)
234
+ const connectorsResponse = await Response.json();
235
+ console.log("knowledge data table after connecting to table", connectorsResponse);
236
+ console.log("api connector data table after connecting to table", connectorsResponse);
237
+ const table = $('#apiTable').DataTable(); // Initialize DataTable at the start
238
+ table.clear();
239
+ if (!Array.isArray(connectorsResponse)) {
240
+ throw new TypeError('Expected an array of companies');
241
+
242
+ displayErrorMessage("Data do not exist for this company. Please fill in the details by clicking add button.");
243
+ contentSection.style.display = 'none';
244
+ } else {
245
+
246
+ connectorsResponse.forEach((company, index) => {
247
+ table.row.add([
248
+ index + 1,
249
+ company.APIName,
250
+ company.APIEndpoint,
251
+ `<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>`,
252
+ `<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>`,
253
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
254
+ ]).draw(false);
255
+ });
256
+ contentSection.style.display = 'block';
257
+ }
258
+
259
+ } catch (error) {
260
+ console.error('Error fetching company documents:', error);
261
+ //displayEmptyTable();
262
+
263
+ displayErrorMessage("Data do not exist for this company. Please fill in the details by clicking add button.");
264
+ contentSection.style.display = 'none';
265
+ }
266
+ }
267
+ else {
268
+ // displayEmptyTable();
269
+
270
+ displayErrorMessage("Document details2 for knowledge do not exist for this company. Please fill in the details.");
271
+ }
272
+ }
273
+
274
+ function viewCompany(button) {
275
+ var companyId = $(button).data('kid-id');
276
+ const modalTitle = document.getElementById('addModalLabel');
277
+ modalTitle.textContent = 'View API Details';
278
+ if (companyId) {
279
+ $.getJSON(`/api/viewapiconnectors/${companyId}`, function (company) {
280
+
281
+ $('#APIName').val(company.api_name).attr('readonly', 'readonly');
282
+ $('#APIEndpoint').val(company.api_endpoint).attr('readonly', 'readonly');
283
+ $('#Auth_Bearer').val(company.auth_token).attr('readonly', 'readonly');
284
+ $('#Inputjson').val(company.input_param).attr('readonly', 'readonly');
285
+ $('#OutputJson').val(company.output_json).attr('readonly', 'readonly');
286
+ $('#Description').val(company.description).attr('readonly', 'readonly');
287
+ $('#save').hide();
288
+ $('#saveupdate').hide();
289
+ $('#addModal').modal('show');
290
+ }).fail(function () {
291
+ alert("Error retrieving API details.");
292
+ });
293
+ }
294
+ }
295
+ // Edit knowledge base details
296
+ function editCompany(button) {
297
+ var companyId = $(button).data('kid-id');
298
+ const modalTitle = document.getElementById('addModalLabel');
299
+ modalTitle.textContent = 'Edit API Details';
300
+ if (companyId) {
301
+ // Fetch company details by ID
302
+ $.getJSON(`/api/viewapiconnectors/${companyId}`, function (company) {
303
+
304
+ $('#APIName').val(company.api_name);
305
+ $('#APIEndpoint').val(company.api_endpoint);
306
+ $('#Auth_Bearer').val(company.auth_token);
307
+ $('#Inputjson').val(company.input_param);
308
+ $('#OutputJson').val(company.output_json);
309
+ $('#Description').val(company.description);
310
+
311
+ // Show/hide appropriate elements
312
+ $('#uploadFile').show(); // Hide the file upload field
313
+ $('#save').hide(); // Hide the default save button
314
+ $('#saveupdate').show(); // Show the update button
315
+
316
+ // Ensure fields are editable
317
+ $('#APIName').removeAttr('readonly');
318
+ $('#APIEndpoint').removeAttr('readonly');
319
+ $('#Auth_Bearer').removeAttr('readonly');
320
+ $('#Inputjson').removeAttr('readonly');
321
+ $('#OutputJson').removeAttr('readonly');
322
+ $('#Description').removeAttr('readonly');
323
+
324
+
325
+ // Show the modal
326
+ $('#addModal').modal('show');
327
+
328
+ // Set up the click event for the update button
329
+ $('#saveupdate').off('click').on('click', function () {
330
+ saveupdate(companyId); // Pass the company ID for updating
331
+ });
332
+ }).fail(function () {
333
+ alert("Error in retrieving API details.");
334
+ });
335
+ }
336
+ }
337
+
338
+ function saveupdate(companyId, filename) {
339
+ const formData = new FormData();
340
+
341
+ const company_id = document.getElementById("company_id").value;
342
+ formData.append("company_id", $('#company_id').val());
343
+ formData.append("APIName", $('#APIName').val());
344
+ formData.append("APIEndpoint", $('#APIEndpoint').val());
345
+ formData.append("Auth_Bearer", $('#Auth_Bearer').val());
346
+ formData.append("Inputjson", $('#Inputjson').val());
347
+ formData.append("OutputJson", $('#OutputJson').val());
348
+ formData.append("Description", $('#Description').val());
349
+ console.log("company_id to table refresh", company_id)
350
+ const messageContainer = document.getElementById('message-container');
351
+ $.ajax({
352
+ url: `/api/editapiconnectors/${companyId}`,
353
+ type: 'PUT',
354
+ data: formData,
355
+ processData: false, // Required for FormData
356
+ contentType: false, // Required for FormData
357
+ success: function (response) {
358
+ // alert('Knowledgebase details updated successfully.');
359
+
360
+ if (messageContainer)
361
+ messageContainer.innerHTML = `
362
+ <div class='alert alert-success'>
363
+ API Data Updated successfully
364
+ <button class='close' onclick='dismissMessage()'>OK</button>
365
+ </div>`;
366
+ $('#addModal').modal('hide'); // Close the modal after saving
367
+ fetchUpdatedDocuments(company_id);
368
+ },
369
+ error: function () {
370
+ alert('Form has no changes to update knowledge base details.');
371
+ }
372
+ });
373
+ }
374
+ function dismissMessage() {
375
+ const messageContainer = document.getElementById('message-container');
376
+ if (messageContainer) {
377
+ messageContainer.innerHTML = '';
378
+ }
379
+ }
380
+ async function fetchUpdatedDocuments(company_id) {
381
+ console.log("company_id:", company_id);
382
+
383
+ var table = $('#apiTable').DataTable();
384
+ try {
385
+ const response = await fetch(`/api/api_updatetable?company_id=${company_id}`);
386
+ const connectorsResponse = await response.json();
387
+
388
+ console.log("Fetched connectorsResponse:", connectorsResponse);
389
+
390
+ table.clear(); // Clear existing data in the table
391
+
392
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
393
+ displayErrorMessage("Knowledgebase details do not exist for this company. Please fill in the details.");
394
+ contentSection.style.display = 'none';
395
+ } else {
396
+ connectorsResponse.forEach((company, index) => {
397
+ table.row.add([
398
+ index + 1,
399
+ company.api_name,
400
+ company.api_endpoint,
401
+ `<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>`,
402
+ `<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>`,
403
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
404
+ company.row_id
405
+ ]);
406
+ });
407
+ table.draw(false); // Draw the table with the new data
408
+ contentSection.style.display = 'block';
409
+ }
410
+ } catch (error) {
411
+ console.error("Error fetching updated documents:", error);
412
+ displayErrorMessage("There was an error fetching the updated documents.");
413
+ }
414
+ }
415
+
416
+ // Delete company
417
+ function deleteCompany(button) {
418
+ var companyId = $(button).data('kid-id');
419
+ console.log("k_id deleted", companyId);
420
+ $.ajax({
421
+ type: "DELETE",
422
+ url: `/api/deleteapi/${companyId}`,
423
+ success: function () {
424
+ var table = $('#apiTable').DataTable();
425
+ table.row($(button).closest('tr')).remove().draw();
426
+ const messageContainer = document.getElementById('message-container');
427
+ if (messageContainer)
428
+ messageContainer.innerHTML = `
429
+ <div class='alert alert-danger'>
430
+ API Data Deleted successfully
431
+ <button class='close' onclick='dismissMessage()'>OK</button>
432
+ </div>`;
433
+ //alert("Company deleted successfully.");
434
+ fetchCompanies(); // Refresh the table
435
+ },
436
+ error: function (xhr) {
437
+ alert("Error deleting company: " + xhr.responseJSON.detail);
438
+ }
439
+ });
440
+ }
441
+
442
+ function save_file() {
443
+ const form = document.getElementById('documentForm');
444
+ const messageContainer = document.getElementById('message-container');
445
+ // Check if the form is valid
446
+ if (!form.checkValidity()) {
447
+ // If the form is invalid, show validation messages and stop the submission
448
+ form.reportValidity();
449
+ return;
450
+ }
451
+ const company_id = $('#company_id').val();
452
+ const APIName = $('#APIName').val();
453
+ const APIEndpoint = $('#APIEndpoint').val();
454
+ const Auth_Bearer = $('#Auth_Bearer').val();
455
+ const Inputjson = $('#Inputjson').val();
456
+ const OutputJson = $('#OutputJson').val();
457
+ const Description = $('#Description').val();
458
+
459
+ var formData = new FormData($('#documentForm')[0]);
460
+
461
+ formData.append("company_id", company_id),
462
+ formData.append("api_name", APIName),
463
+ formData.append("api_endpoint", APIEndpoint),
464
+ formData.append("auth_bearer", Auth_Bearer),
465
+ formData.append("input_json", Inputjson),
466
+ formData.append("output_json", OutputJson),
467
+ formData.append("description", Description)
468
+
469
+ //const formData = new FormData();
470
+ fetch('/api/save_api_details', {
471
+ method: 'POST',
472
+ body: formData
473
+ })
474
+ .then(response => {
475
+ if (!response.ok) {
476
+ throw new Error('Network response was not ok');
477
+ }
478
+ return response.json();
479
+ })
480
+ .then(data => {
481
+ row_id = data.row_id;
482
+ var table = $('#apiTable').DataTable();
483
+ var rowCount = table.rows().count();
484
+ 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>`;
485
+ 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>`;
486
+ 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>`;
487
+ table.row.add([
488
+ rowCount + 1,
489
+ APIName,
490
+ APIEndpoint,
491
+ view,
492
+ edit,
493
+ dele
494
+ ]).draw(false);
495
+
496
+ // alert('Document saved successfully');
497
+ if (messageContainer)
498
+ messageContainer.innerHTML = `
499
+ <div class='alert alert-success'>
500
+ API Data saved successfully
501
+ <button class='close' onclick='dismissMessage()'>OK</button>
502
+ </div>`;
503
+ $('#addModal').modal('hide');
504
+ document.getElementById('contentSection').style.display = 'block'; // Show the table section
505
+ })
506
+ .catch(error => console.error('Error:', error));
507
+ }
508
+
509
+
510
+ function clearFormFields() {
511
+ document.getElementById('APIName').value = "";
512
+ document.getElementById('APIEndpoint').value = "";
513
+ document.getElementById('Auth_Bearer').value = "";
514
+ document.getElementById('Inputjson').value = "";
515
+ document.getElementById('OutputJson').value = "";
516
+ document.getElementById('Description').value = "";
517
+ }
518
+
519
+
520
+ </script>
521
+ </body>
522
+
523
+ </html>
templates/chatbot.html ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # jinja2 html page with chatbot functionality using adminlte3 theme
2
+ <html>
3
+
4
+ <body>
5
+ <form id="myform">
6
+ <div class="content-wrapper">
7
+ <section class="content-header">
8
+ <div class="container-fluid">
9
+ <div class="row mb-2">
10
+ <div class="col-sm-6">
11
+ <h1>Chatbot</h1>
12
+ </div>
13
+ <div class="col-sm-6">
14
+ <ol class="breadcrumb float-sm-right">
15
+ <li class="breadcrumb-item"><a href="#">Home</a></li>
16
+ <li class="breadcrumb-item active">Chatbot</li>
17
+ </ol>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </section>
22
+
23
+ <section class="content">
24
+ <div class="container-fluid">
25
+ <div class="row">
26
+ <div class="col-md-8 offset-md-2">
27
+ <div class="card card-primary">
28
+ <div class="card-header">
29
+ <h3 class="card-title">Chat with our AI</h3>
30
+ </div>
31
+ <div class="card-body">
32
+ <div id="chat-container">
33
+ <div class="chat-messages">
34
+ <!-- Chat messages will be dynamically added here -->
35
+ </div>
36
+ <div class="chat-input">
37
+ <input type="text" id="user_question" placeholder="Type your message...">
38
+ <button id="send-button" onclick="clickform()">Send</button>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ </section>
47
+ </div>
48
+ </form>
49
+ <script>
50
+ const chatContainer = document.getElementById('chat-container');
51
+ const userInput = document.getElementById('user_question');
52
+ const sendButton = document.getElementById('send-button');
53
+
54
+ function clickform() {
55
+ alert('Please enter');
56
+ var formElement = document.getElementById('myForm');
57
+ var user_question = document.getElementById('user_question').value;
58
+ alert(user_question);
59
+ //var data = new FormData(formElement);
60
+ //alert(data);
61
+ fetch('/chat_with_agent', {
62
+ method: 'POST',
63
+ //body: data,
64
+ })
65
+ .then(resp => resp.text()) // or, resp.json(), etc.
66
+ .then(data => {
67
+ //document.getElementById("responseArea").innerHTML = data;
68
+ alert(data);
69
+ const chatMessage = document.createElement('div');
70
+ chatMessage.classList.add('chat-message');
71
+ chatMessage.innerHTML = '<strong>You:</strong> ${user_question}<br><strong>AI:</strong> ${data}';
72
+ chatContainer.appendChild(chatMessage);
73
+
74
+ userInput.value = '';
75
+ userInput.focus();
76
+ })
77
+ .catch(error => {
78
+ console.error(error);
79
+ });
80
+ }
81
+ </script>
82
+ </body>
83
+
84
+ </html>
templates/company_profile.html ADDED
@@ -0,0 +1,525 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
10
+ <!-- Include AdminLTE CSS -->
11
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1/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/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
15
+ <link href="https://cdn.jsdelivr.net/npm/@ttskch/select2-bootstrap4-theme@1.4.0/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
+ <link rel="stylesheet" href="/static/css/company_profile.css">
19
+ </head>
20
+
21
+ <body>
22
+ {% include 'sidepane.html' %}
23
+
24
+ <div class="wrapper">
25
+ <div class="content-wrapper">
26
+ <!-- Content Header (Page header) -->
27
+ <div class="content-header">
28
+ <div class="container-fluid">
29
+ <div class="row mb-2">
30
+ <!-- <div class="col-12">
31
+ <div class="col-12 d-flex justify-content-end mb-3">
32
+ <button class="btn btn-primary" style="margin-bottom:-30px;position:fixed" id="add">Add</button>
33
+ </div>
34
+ </div> -->
35
+ <input type="hidden" id="userRole" name="userRole" value={{role}}>
36
+ <div class="row">
37
+ <div id="message-container" style="margin-left: 200px;width:600px;"></div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <!-- Main content -->
43
+ <section class="content" id="startTable" style="display: none;">
44
+
45
+ <div class="row">
46
+ <div class="col-12">
47
+ <div class="card">
48
+ <div class="card-body table-container">
49
+ <div class="dataTables_wrapper">
50
+ <div class="row">
51
+ <div class="dataTables_length">
52
+ <label
53
+ style="display: inline-block;margin-right:800px; margin-bottom: -40px;">Show
54
+ entries:
55
+ <div class="custom-dropdown">
56
+ <button class="dropdown-button">5</button>
57
+ <div class="dropdown-content">
58
+ <a href="#" data-length="5">5</a>
59
+ <a href="#" data-length="10">10</a>
60
+ <a href="#" data-length="50">50</a>
61
+ <a href="#" data-length="100">100</a>
62
+ </div>
63
+ </div>
64
+ </label>
65
+ </div>
66
+ <table id="companyTable"
67
+ class="table display mb-4 dataTablesCard dataTable table-responsive-xl card-table">
68
+ <thead>
69
+ <tr>
70
+ <th>Sno</th>
71
+ <th>Company Name</th>
72
+ <th>Company code</th>
73
+ <th>Domain</th>
74
+ <th>LLM Tools</th>
75
+ <th>View</th>
76
+ <th>Edit</th>
77
+ <th>Delete</th>
78
+ </tr>
79
+ </thead>
80
+
81
+ </table>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ </section>
88
+ </div>
89
+ </div>
90
+ <!-- Modal -->
91
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
92
+ aria-hidden="true">
93
+ <div class="modal-dialog" role="document">
94
+ <div class="modal-content">
95
+ <div class="modal-header">
96
+ <h5 class="modal-title" id="addModalLabel">Add Company Profile</h5>
97
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
98
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false">&times;</span>
99
+ </button>
100
+ </div>
101
+ <div class="modal-body">
102
+ <form id="companyForm">
103
+ <div class="form-group">
104
+ <label for="companyName">Company Name<span class="text-danger">*</span></label>
105
+ <input type="text" class="form-control" id="company_name" name="company_name" required>
106
+ </div>
107
+ <div class="form-group">
108
+ <label for="companyCode">Company Code<span class="text-danger">*</span></label>
109
+ <input type="text" class="form-control" id="company_code" name="company_code" required>
110
+ </div>
111
+ <div class="form-group">
112
+ <label for="domain">Domain<span class="text-danger">*</span></label>
113
+ <input type="text" class="form-control" id="domain" name="domain" required>
114
+ </div>
115
+ <div class="form-group">
116
+ <label for="llm_tools">LLM Tools<span class="text-danger">*</span></label>
117
+ <select class="form-select" id="llm_tools" name="llm_tools[]" multiple required>
118
+ <option value="Database">Database</option>
119
+ <option value="Static Documents">Static Documents</option>
120
+ <option value="API">API</option>
121
+ </select>
122
+
123
+ <div class="invalid-feedback">
124
+ Please select at least one LLM tool.
125
+ </div>
126
+ </div>
127
+
128
+ <div class="form-group">
129
+ <label for="domain">UserName<span class="text-danger">*</span></label>
130
+ <input type="text" class="form-control" id="username" name="username" required>
131
+ </div>
132
+ </form>
133
+ </div>
134
+ <div class="modal-footer">
135
+ <button type="button" id="saveupdate" class="btn btn-primary" style="display: none;">Update</button>
136
+ <button type="button" id="save" onclick="saveProfile()" class="btn btn-primary">Save</button>
137
+ </div>
138
+ </div>
139
+ </div>
140
+ </div>
141
+ {%include 'footer.html'%}
142
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
143
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
144
+ <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
145
+ <script>
146
+ document.addEventListener('DOMContentLoaded', function () {
147
+
148
+ const role = sessionStorage.getItem('userRole');
149
+ const company_id = sessionStorage.getItem('company_id');
150
+ console.log('Current role:', role); // Debug statement to check the role
151
+ document.getElementById('userRole').value = role;
152
+ const passedCompanyName = sessionStorage.getItem('company_name')
153
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
154
+ $('#addModal').hide(); // Make sure this is called initially
155
+ function checkForAddButton() {
156
+ const addButton = document.getElementById('add');
157
+
158
+ if (addButton) {
159
+ // Stop checking once the element is found
160
+ clearInterval(checkInterval);
161
+ if (role === 'superadmin') {
162
+ console.log("insidse compamy profile super admin");
163
+
164
+ $('#startTable').show();
165
+ $('#addModal').hide();
166
+ $('#add').show();
167
+
168
+
169
+ } else {
170
+ console.log("insidse company profile admin");
171
+ $('#add').hide();
172
+ const modalTitle = document.getElementById('addModalLabel');
173
+ modalTitle.textContent = 'Company Details';
174
+ viewCompany(company_id);
175
+ }
176
+ }
177
+ }
178
+ const checkInterval = setInterval(checkForAddButton, 100); //
179
+ document.querySelector('.dropdown-button').addEventListener('click', function () {
180
+ const dropdownContent = document.querySelector('.dropdown-content');
181
+ dropdownContent.style.display = dropdownContent.style.display === 'block' ? 'none' : 'block';
182
+ });
183
+ fetchCompanies();
184
+ });
185
+ window.addEventListener('click', function (event) {
186
+ if (!event.target.matches('.dropdown-button')) {
187
+ const dropdownContents = document.querySelectorAll('.dropdown-content');
188
+ dropdownContents.forEach(function (content) {
189
+ content.style.display = 'none';
190
+ });
191
+ }
192
+ });
193
+ window.addEventListener('pageshow', function (event) {
194
+ if (event.persisted || (window.performance && window.performance.navigation.type === 2)) {
195
+ window.location.reload();
196
+ }
197
+ });
198
+
199
+
200
+ $(document).ready(function () {
201
+ // Initialize DataTable
202
+ //$('#companyTable').DataTable();
203
+ $('#companyTable').DataTable({
204
+
205
+ "paging": true,
206
+ "pageLength": 5,
207
+ "lengthChange": false,
208
+ "searching": true,
209
+ "ordering": true,
210
+ "info": true,
211
+ "autoWidth": false,
212
+ "responsive": true
213
+ });
214
+
215
+ // Initialize Select2
216
+ $('select').select2({
217
+ theme: 'bootstrap4',
218
+ placeholder: 'Select',
219
+ allowClear: true,
220
+ dropdownParent: $('#addModal')
221
+ });
222
+
223
+ // Show modal function
224
+ $('#add').on('click', function () {
225
+ const modalTitle = document.getElementById('addModalLabel');
226
+ modalTitle.textContent = 'Add Company Details';
227
+ console.log('Modal title after setting:', modalTitle.textContent); // This should log the new title
228
+ $('#company_name').removeAttr('readonly');
229
+ $('#company_code').removeAttr('readonly');
230
+ $('#domain').removeAttr('readonly');
231
+ $('select').prop('disabled', false);
232
+ $('#username').removeAttr('readonly');
233
+ $('#addModal').modal('show');
234
+ $('#save').show();
235
+ $('#saveupdate').hide();
236
+
237
+
238
+ clearmodal();
239
+ $('#save').prop('disabled', false); // Disable the "Save" button when the modal opens
240
+ });
241
+ $('.modal-footer .btn-secondary, .modal-header .close').on('click', function () {
242
+ $('#addModal').modal('hide');
243
+ });
244
+ $('#addModal').on('shown.bs.modal', function () {
245
+ $('#companyTable').DataTable().columns.adjust().draw();
246
+ // Initialize Select2 only if not already initialized
247
+ if (!$('#llm_tools').hasClass('select2-hidden-accessible')) {
248
+ $('select').select2({
249
+ theme: 'bootstrap4',
250
+ placeholder: 'Select LLM Tools',
251
+ allowClear: true,
252
+ dropdownParent: $('#addModal')
253
+ });
254
+ }
255
+ });
256
+
257
+ $(document).on('click', '.btn-view', function () {
258
+ const companyId = $(this).data('id');
259
+ console.log("company_id in view", companyId);
260
+ viewCompany(companyId);
261
+ });
262
+
263
+ // Edit company details
264
+ $(document).on('click', '.btn-edit', function () {
265
+ const companyId = $(this).data('id');
266
+ console.log("company_id in edit", companyId);
267
+ if (companyId) {
268
+ const modalTitle = document.getElementById('addModalLabel');
269
+ modalTitle.textContent = 'Edit Company Details';
270
+ console.log('Modal title:', modalTitle.textContent);
271
+
272
+ Editcompany(companyId);
273
+ }
274
+ });
275
+
276
+ // Delete company
277
+ $(document).on('click', '.btn-delete', function () {
278
+ const companyId = $(this).data('id'); // Get the company ID from the da
279
+ console.log("company_id in delete", companyId);
280
+ if (confirm("Are you sure you want to delete this company?")) {
281
+ deleteCompany(companyId); // Call the delete function with the company ID
282
+ }
283
+ });
284
+ });
285
+ // View company details
286
+ function viewCompany(companyId) {
287
+ const username = sessionStorage.getItem('username');
288
+ const modalTitle = document.getElementById('addModalLabel');
289
+ modalTitle.textContent = 'View Company Details';
290
+
291
+ // Fetch company details by ID
292
+ $.getJSON(`/api/getcompanydetails/${companyId}`, function (company) {
293
+ console.log("Fetched company details:", company);
294
+
295
+ // Set the company fields to readonly
296
+ $('#company_name').val(company.company_name).attr('readonly', 'readonly');
297
+ $('#company_code').val(company.company_code).attr('readonly', 'readonly');
298
+ $('#domain').val(company.domain).attr('readonly', 'readonly');
299
+ $('select').val(company.llm_tools.split(',')).trigger('change');
300
+ $('select').prop('disabled', true);
301
+ $('#username').val(username).attr('readonly', 'readonly');
302
+
303
+ // Show the modal
304
+ $('#saveupdate').hide();
305
+ $('#save').hide();
306
+ $('#addModal').modal('show');
307
+ }).fail(function () {
308
+ console.error("Error retrieving company details.");
309
+ });
310
+ }
311
+ // Edit company details
312
+ function Editcompany(companyId) {
313
+
314
+ const username = sessionStorage.getItem('username');
315
+ const modalTitle = document.getElementById('addModalLabel');
316
+ modalTitle.textContent = 'Edit Company Details';
317
+ console.log('Modal title after setting:', modalTitle.textContent); // Should log "Edit Company Details"
318
+ // Fetch company details by ID
319
+ $.getJSON(`/api/getcompanydetails/${companyId}`, function (company) {
320
+ $('#company_name').removeAttr('readonly');
321
+ $('#company_code').removeAttr('readonly');
322
+ $('#domain').removeAttr('readonly');
323
+ $('select').prop('disabled', false);
324
+ $('#save').hide();
325
+ $('#saveupdate').show();
326
+ // Populate the form with the company's details
327
+ $('#company_name').val(company.company_name);
328
+ $('#company_code').val(company.company_code);
329
+ $('#domain').val(company.domain);
330
+ $('select').val(company.llm_tools.split(',')).trigger('change');
331
+ $('#username').val(username).attr('readonly', 'readonly');// Disable the select input
332
+
333
+ //sessionStorage.setItem('llmTools', company.llm_tools); // Store as a string
334
+ $('#addModal').modal('show');
335
+
336
+ // Update the save button to save the edited company
337
+ $('#saveupdate').off('click').on('click', function () {
338
+
339
+ saveupdate(companyId); // Pass the company ID for updating
340
+ });
341
+ }).fail(function () {
342
+ alert("Error retrieving company details.");
343
+ });
344
+ }
345
+
346
+ // Delete company
347
+ function deleteCompany(companyId) {
348
+ console.log("company_id deleted", companyId);
349
+ $.ajax({
350
+ type: "DELETE",
351
+ url: `/api/delcompanydetails/${companyId}`,
352
+ success: function () {
353
+ // alert("Company deleted successfully.");
354
+ const messageContainer = document.getElementById('message-container');
355
+ if (messageContainer)
356
+ messageContainer.innerHTML = `
357
+ <div class='alert alert-danger'>
358
+ Company details deleted successfully.
359
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
360
+ </div>`;
361
+ fetchCompanies(); // Refresh the table
362
+ },
363
+ error: function (xhr) {
364
+ alert("Error deleting company: " + xhr.responseJSON.detail);
365
+ }
366
+ });
367
+ }
368
+ function saveupdate(companyId) {
369
+ console.log("company_id", companyId);
370
+ const llm_tools = $('#llm_tools').select2("val");
371
+ var formData = new FormData();
372
+ formData.append('company_name', $('#company_name').val());
373
+ formData.append('company_code', $('#company_code').val());
374
+ formData.append('domain', $('#domain').val());
375
+ formData.append('llm_tools', llm_tools); // Assuming llm_tools is a multi-select
376
+
377
+ console.log("company_data", formData);
378
+
379
+ $.ajax({
380
+ url: `/api/putcompanydetails/${companyId}`,
381
+ type: 'PUT',
382
+ data: formData,
383
+ processData: false, // Important for FormData
384
+ contentType: false,
385
+ success: function (response) {
386
+ // alert('Company details updated successfully.');
387
+ const messageContainer = document.getElementById('message-container');
388
+ if (messageContainer)
389
+ messageContainer.innerHTML = `
390
+ <div class='alert alert-success'>
391
+ Company Data Updated successfully
392
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
393
+ </div>`;
394
+ $('#addModal').modal('hide'); // Close the modal after saving
395
+ fetchCompanies();
396
+ },
397
+ error: function () {
398
+
399
+ const messageContainer = document.getElementById('message-container');
400
+ if (messageContainer)
401
+ messageContainer.innerHTML = `
402
+ <div class='alert alert-danger'>
403
+ No changes have been made to update company details.
404
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
405
+ </div>`;
406
+ $('#addModal').modal('hide');
407
+ //alert('No changes have been made to update company details.');
408
+ }
409
+ });
410
+ }
411
+
412
+ function saveProfile() {
413
+ const form = document.getElementById('companyForm');
414
+
415
+ // Check if the form is valid
416
+ if (!form.checkValidity()) {
417
+ // If the form is invalid, show validation messages and stop the submission
418
+ form.reportValidity();
419
+ return;
420
+ }
421
+
422
+ // Gather form data
423
+ const company_name = document.getElementById('company_name').value;
424
+ const company_code = document.getElementById('company_code').value;
425
+ const domain = document.getElementById('domain').value;
426
+ const llm_tools = $('#llm_tools').select2("val");
427
+ console.log("Selected LLM Tools:", llm_tools);
428
+ // console.log("llm_tools element:", document.getElementById('llm_tools'));
429
+ const username = $('#username').val();
430
+
431
+
432
+ // Prepare FormData
433
+ let formData = new FormData();
434
+ const password = "password";
435
+ const rolesave = "admin";
436
+ formData.append("company_name", company_name);
437
+ formData.append("company_code", company_code);
438
+ formData.append("domain", domain);
439
+ formData.append("llm_tools", llm_tools);
440
+ formData.append("username", username);
441
+ formData.append("password", password);
442
+ formData.append("role", rolesave);
443
+
444
+ $.ajax({
445
+ type: "POST",
446
+ url: "/submit_company_profile",
447
+ data: formData,
448
+ processData: false,
449
+ contentType: false,
450
+ success: function (response) {
451
+ // alert("Data saved successfully"); // Show success message
452
+ const messageContainer = document.getElementById('message-container');
453
+ if (messageContainer)
454
+ messageContainer.innerHTML = `
455
+ <div class='alert alert-success'>
456
+ Data saved successfully
457
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
458
+ </div>`;
459
+ fetchCompanies(); // Refresh table data
460
+
461
+ // Clear the form and close the modal
462
+ // $('#companyForm')[0].reset();
463
+ $('#addModal').modal('hide');
464
+ },
465
+ error: function (xhr) {
466
+ alert("An error occurred: " + xhr.responseJSON.detail); // Show error message
467
+ }
468
+ });
469
+ }
470
+ function dismissMessage() {
471
+ const messageContainer = document.getElementById('message-container');
472
+ if (messageContainer) {
473
+ messageContainer.innerHTML = '';
474
+ }
475
+ }
476
+ async function fetchCompanies() {
477
+ try {
478
+ console.log("Fetching companies...");
479
+ const response = await fetch(`/api/companydetails`);
480
+ const companies = await response.json();
481
+ console.log(companies); // Inspect the data here
482
+
483
+ if (!Array.isArray(companies)) {
484
+ throw new TypeError('Expected an array of companies');
485
+ }
486
+
487
+ const table = $('#companyTable').DataTable();
488
+ table.clear(); // Clear existing table data
489
+
490
+ companies.forEach((company, index) => {
491
+ table.row.add([
492
+ index + 1,
493
+ company.company_name,
494
+ company.company_code,
495
+ company.domain,
496
+ company.llm_tools, // Join array of tools into a string
497
+ `<a href='#' class='btn btn-info btn-sm'onclick='viewCompany(${company.company_id})'><i class='fas fa-eye'></i></a>`,
498
+ `<a href='#' class='btn btn-warning btn-sm'onclick='Editcompany(${company.company_id})'><i class='fas fa-edit'></i></a>`,
499
+ `<a href='#' class='btn btn-danger btn-sm' onclick='deleteCompany(${company.company_id})'><i class='fas fa-trash'></i></a>`
500
+
501
+ ])
502
+ }); table.draw(false);
503
+ } catch (error) {
504
+ console.error('Error fetching companies:', error);
505
+ }
506
+ }
507
+ function clearmodal() {
508
+ $('#companyForm')[0].reset(); // Reset all form fields
509
+ $('#llm_tools').val(null).trigger('change'); // Clear and reset the Select2 field without reinitializing
510
+ }
511
+
512
+ document.querySelectorAll('.dropdown-content a').forEach(function (item) {
513
+ item.addEventListener('click', function () {
514
+ const length = item.getAttribute('data-length');
515
+ // Set the DataTable page length
516
+ $('#companyTable').DataTable().page.len(parseInt(length)).draw();
517
+ document.querySelector('.dropdown-button').textContent = length;
518
+ });
519
+ });
520
+
521
+
522
+ </script>
523
+ </body>
524
+
525
+ </html>
templates/dashboard.html ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <link rel="stylesheet" href="/static/css/dashboard1.css">
14
+ <style>
15
+
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ {% set company_name = company_name %}
21
+ {% include 'sidepane.html' %}
22
+
23
+ <div class="wrapper">
24
+ <section class="main-header">
25
+ <div class="container-fluid">
26
+ <div id="company-block" class="form-group left-align" style="display: none;">
27
+ <label for="company" class="ml-3" style="display: inline-block; margin-right: 10px;">
28
+ Select the Company Name to view the details <span class="text-danger">*</span>
29
+ </label>
30
+ <select type="text" id="company" name="company" class="ml-3 form-control"
31
+ style="display: inline-block; width: 20%;" required>
32
+ <option value="" selected>Select</option>
33
+ </select>
34
+ </div>
35
+
36
+ <div class="row">
37
+ <div class="col-md-6">
38
+ <div class="card bg-primary">
39
+ <div class="card-body">
40
+ <div class="media align-items-center">
41
+ <span class="p-3 mr-3 feature-icon rounded">
42
+ <img src="../static/logos/calendar-silhouette.svg" />
43
+ </span>
44
+ <div class="media-body">
45
+ <p class="fs-30 text-white mb-2">KnowledgeBase</p>
46
+ <span id="knowledgeBaseCount"
47
+ class="fs-48 text-white font-w600">{{table_count_of_each_table.knowledge_base}}</span>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+ <div class="col-md-6">
54
+ <div class="card bg-info">
55
+ <div class="card-body">
56
+ <div class="media align-items-center">
57
+ <span class="p-3 mr-3 feature-icon rounded">
58
+ <img src="../static/logos/calendar-silhouette.svg" />
59
+ </span>
60
+ <div class="media-body">
61
+ <p class="fs-30 text-white mb-2">Data connectors</p>
62
+ <span id="dataConnectorsCount"
63
+ class="fs-48 text-white font-w600">{{table_count_of_each_table.data_connectors}}</span>
64
+ </div>
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ <div class="row">
71
+ <div class="col-md-6 ">
72
+ <div class="card bg-success">
73
+ <div class="card-body">
74
+ <div class="media align-items-center">
75
+ <span class="p-3 mr-3 feature-icon rounded">
76
+ <img src="../static/logos/email.svg" />
77
+ </span>
78
+ <div class="media-body">
79
+ <p class="fs-30 text-white mb-2">API Connectors</p>
80
+ <span id="apiConnectorsCount"
81
+ class="fs-48 text-white font-w600">{{table_count_of_each_table.api_connectors}}</span>
82
+ </div>
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ <div class="col-md-6 ">
88
+ <div class="card bg-secondary">
89
+ <div class="card-body">
90
+ <div class="media align-items-center">
91
+ <span class="p-3 mr-3 feature-icon rounded">
92
+ <img src="../static/logos/dots.svg" />
93
+ </span>
94
+ <div class="media-body">
95
+ <p class="fs-30 text-white mb-2">Prompt_Templates</p>
96
+ <span id="promptTemplatesCount"
97
+ class="fs-48 text-white font-w600">{{table_count_of_each_table.prompt_templates}}</span>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </section>
106
+ <input type="hidden" id="userRole" name="userRole" value={{role}}>
107
+ <input type="hidden" id="company_id" name="company_id" value={{company_id}}>
108
+ <input type="hidden" id="username" name="username" value={{username}}>
109
+ <input type="hidden" id="company_name" name="company_name" value={{company_name}}>
110
+
111
+ </div>
112
+
113
+
114
+ {% include 'footer.html' %}
115
+
116
+ <script src="https://cdn.jsdelivr.net/npm/admin-lte@3.1/dist/js/adminlte.min.js"></script>
117
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
118
+ <script>
119
+ document.getElementById("add").style.display = "none";
120
+
121
+ function updateCompanyName(newCompanyName) {
122
+ sessionStorage.setItem('company_name', newCompanyName);
123
+ document.getElementById('selectedCompany').innerText = `Company name: ${newCompanyName}`;
124
+ const sidePaneCompanyName = document.querySelector('.sidebar .company-name');
125
+ if (sidePaneCompanyName) {
126
+ sidePaneCompanyName.innerText = newCompanyName;
127
+ }
128
+ }
129
+ function updateSidepane(companyName) {
130
+ const sidepaneCompanyElement = document.getElementById('selectedCompany');
131
+ if (sidepaneCompanyElement) {
132
+ sidepaneCompanyElement.innerText = `Company Name: ${companyName}`;
133
+ }
134
+ }
135
+
136
+ window.addEventListener('pageshow', function (event) {
137
+ if (event.persisted || (window.performance && window.performance.navigation.type === 2)) {
138
+ window.location.reload();
139
+ }
140
+ });
141
+
142
+ document.addEventListener('DOMContentLoaded', function () {
143
+ var role1 = document.getElementById("userRole").value;
144
+ var company_id1 = document.getElementById("company_id").value;
145
+ var company_name1 = document.getElementById("company_name").value;
146
+ var username1 = document.getElementById("username").value;
147
+ console.log("companyid in dasshboard", username1);
148
+ sessionStorage.setItem('userRole', role1);
149
+ // sessionStorage.setItem('siderole',role1);
150
+ // sessionStorage.setItem('sidecompanyId',company_id1);
151
+ sessionStorage.setItem('company_id', company_id1);
152
+ sessionStorage.setItem('company_name', company_name1);
153
+ sessionStorage.setItem('username', username1);
154
+ const companyName = sessionStorage.getItem('company_name');
155
+ if (companyName) {
156
+
157
+ updateSidepane(companyName);
158
+ }
159
+ else {
160
+ document.getElementById(selectedCompany).value = "Select a company";
161
+ }
162
+
163
+
164
+ if (!role1) {
165
+ var roleFromInput = sessionStorage.getItem('userRole');
166
+ sessionStorage.setItem('userRole', roleFromInput);
167
+ console.log("Role set in sessionStorage:", roleFromInput);
168
+ } else {
169
+ sessionStorage.setItem('userRole', role1);
170
+ console.log("Retrieved user role from input:", role1); // Debugging
171
+ }
172
+ if (role1 === "superadmin") {
173
+ document.getElementById('company-block').style.display = 'block';
174
+ fetchCompanies();
175
+ }
176
+
177
+ });
178
+ document.getElementById('company').addEventListener('change', async function () {
179
+ const selectedCompany = this.value;
180
+ sessionStorage.setItem("company_name", selectedCompany);
181
+ // Update the sidepane immediately
182
+ updateSidepane(selectedCompany);
183
+ if (selectedCompany !== "Select") {
184
+ try {
185
+ const response = await fetch(`/api/company_id?company_name=${encodeURIComponent(selectedCompany)}`);
186
+ if (!response.ok) {
187
+ contentSection.style.display = 'none';
188
+ displayErrorMessage("Document details do not exist for this company. Please fill in the details.");
189
+ throw new Error('Network response was not ok');
190
+ }
191
+ const data = await response.json();
192
+ console.log('data returned', data);
193
+ const companyId = data.company_id;
194
+ sessionStorage.setItem("company_id", companyId);
195
+ console.log("company id for superadmin", company_id);
196
+ //document.getElementById('company_id').value = companyId;
197
+
198
+
199
+ if (companyId) {
200
+ try {
201
+ const countResponse = await fetch(`/api/company_record_count/${companyId}`);
202
+ if (!countResponse.ok) {
203
+ throw new Error('Network response was not ok');
204
+ }
205
+ const countData = await countResponse.json();
206
+ console.log('Count data:', countData); // Log the response data
207
+ updateRecordCounts(countData.table_counts);
208
+ } catch (error) {
209
+ console.error('Error fetching record counts:', error);
210
+ }
211
+ } else {
212
+ clearRecordCounts();
213
+ }
214
+ } catch (error) {
215
+ console.error('No details for this company ID or data documents:', error);
216
+ // displayEmptyTable();
217
+
218
+ displayErrorMessage("company details do not exist for this company.");
219
+
220
+ }
221
+ }
222
+ });
223
+
224
+ function updateRecordCounts(counts) {
225
+ // Update the counts displayed in the dashboard
226
+ document.getElementById('knowledgeBaseCount').textContent = counts.knowledge_base || 0;
227
+ document.getElementById('dataConnectorsCount').textContent = counts.data_connectors || 0;
228
+ document.getElementById('apiConnectorsCount').textContent = counts.api_connectors || 0;
229
+ document.getElementById('promptTemplatesCount').textContent = counts.prompt_templates || 0;
230
+ }
231
+
232
+ function clearRecordCounts() {
233
+ document.getElementById('knowledgeBaseCount').textContent = 0;
234
+ document.getElementById('dataConnectorsCount').textContent = 0;
235
+ document.getElementById('apiConnectorsCount').textContent = 0;
236
+ document.getElementById('promptTemplatesCount').textContent = 0;
237
+ }
238
+
239
+ async function fetchCompanies() {
240
+ try {
241
+ const response = await fetch('/api/companies');
242
+ if (!response.ok) {
243
+ throw new Error('Network response was not ok');
244
+ }
245
+ const data = await response.json();
246
+ displayCompanies(data.companies);
247
+ } catch (error) {
248
+ console.error('Error fetching companies:', error);
249
+ }
250
+ }
251
+
252
+ function displayCompanies(companies) {
253
+ const companySelect = document.getElementById('company');
254
+ companySelect.innerHTML = '<option value="" selected>Select</option>'; // Reset the dropdown
255
+ companies.forEach(company => {
256
+ const option = document.createElement('option');
257
+ option.value = company.name;
258
+ option.textContent = company.name;
259
+ companySelect.appendChild(option);
260
+ });
261
+ }
262
+ function clearFormFields() {
263
+ document.getElementById('APIName').value = "";
264
+ document.getElementById('APIEndpoint').value = "";
265
+ document.getElementById('Auth_Bearer').value = "";
266
+ document.getElementById('Inputjson').value = "";
267
+ document.getElementById('OutputJson').value = "";
268
+ document.getElementById('Description').value = "";
269
+ }
270
+
271
+ </script>
272
+ </body>
273
+
274
+ </html>
templates/data_connectors.html ADDED
@@ -0,0 +1,453 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
10
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1/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
+ <link rel="stylesheet" href="/static/css/data_connectors.css">
14
+ </head>
15
+
16
+ <body>
17
+
18
+ {% include 'sidepane.html' %}
19
+ <div class="wrapper" style="z-index: 1;">
20
+ <div class="main-header">
21
+ <!-- Content Header (Page header) -->
22
+ <!-- <div class="content-header">
23
+ <div class="container-fluid">
24
+ <div class="container mt-2"> -->
25
+ <!-- <div class="form-group left-align">
26
+ <label for="company" class="mr-1" style="margin-left:-60px;margin-top:-1px;">Company Name <span class="text-danger">*</span></label>
27
+ <select type="text" id="company" name="company" class="form-control "style="width: 20%;margin-left:-60px;margin-bottom:-35px" required>
28
+ <option value="" selected>Select</option>
29
+ </select>
30
+ </div> -->
31
+ <!-- <div class="row">
32
+ <div id="message-container"
33
+ style="padding:10px 10px;margin-left: 150px;width:500px;margin-bottom:-20px; margin-top: -30px;">
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ </div> -->
39
+
40
+ <form id="databaseconnectorForm" class="needs-validation" novalidate action="/save_data_connectors"
41
+ method="post">
42
+ <div class="form-group">
43
+ <!-- <label for="company_id">company_id</label>--->
44
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
45
+ </div>
46
+ <h4 id="selectedCompany" style="margin-left: 300px;margin-bottom: 50px;margin-top: -50px;"></h4>
47
+ <div class="row">
48
+ <div class="col-md-3">
49
+ <div class="form-group">
50
+ <label for="database">Database Type<span class="text-danger">*</span></label>
51
+ <select type="text" id="database" name="database" class="form-control" required>
52
+ <option value="" selected>Select</option>
53
+ <option value="Postgres">Postgres</option>
54
+ <option value="mysql">mysql</option>
55
+ </select>
56
+ </div>
57
+ </div>
58
+ <div class="col-md-3">
59
+ <div class="form-group">
60
+ <label for="server">Server IP <span class="text-danger">*</span></label>
61
+ <input type="text" id="server" name="server" class="form-control" required>
62
+ </div>
63
+ </div>
64
+ <div class="col-md-3">
65
+ <div class="form-group">
66
+ <label for="port">Port <span class="text-danger">*</span></label>
67
+ <input type="text" id="port" name="port" class="form-control" required>
68
+ </div>
69
+ </div>
70
+ <div class="col-md-3">
71
+ <div class="form-group">
72
+ <label for="databaseName">Database Name <span class="text-danger">*</span></label>
73
+ <input type="text" id="databaseName" name="databaseName" class="form-control" required>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ <div class="row">
78
+ <div class="col-md-3">
79
+ <div class="form-group">
80
+ <label for="userame">UserName <span class="text-danger">*</span></label>
81
+ <input type="text" id="username" name="username" class="form-control" required>
82
+ </div>
83
+ </div>
84
+ <div class="col-md-3">
85
+ <div class="form-group">
86
+ <label for="password">Password <span class="text-danger">*</span></label>
87
+ <input type="password" id="password" name="password" class="form-control" required>
88
+ </div>
89
+ </div>
90
+
91
+ <div class="col-md-6">
92
+ <div class="form-group d-flex justify-content-between">
93
+ <div class="form-group btn-container">
94
+ <button type="button" id="connectBtn" class="btn btn-primary">Connect</button>
95
+ <button type="reset" class="btn btn-primary">Clear</button>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ </div>
100
+
101
+ <div id="schema-table-section" style="display: none;">
102
+ <div class="row">
103
+ <div class="col-md-3">
104
+ <div class="form-group1">
105
+ <label for="schemas">Select Schemas <span class="text-danger">*</span></label>
106
+ <select type="text" id="schemas" name="schemas" class="form-control" required>
107
+ <option value="" selected>Select</option>
108
+ <option value="schema1">Lookup</option>
109
+ <option value="schema2">Public</option>
110
+ <option value="schema3" selected>tenant_default</option>
111
+ </select>
112
+ </div>
113
+ </div>
114
+
115
+ <div class="col-md-3">
116
+ <div class="form-group1">
117
+ <label for="tableschema" style="margin-left: 30px;margin-right: 30px;">Select Tables
118
+ <span class="text-danger">*</span></label>
119
+ <div class="dropdown custom-dropdown">
120
+ <button class="btn btn-secondary dropdown-toggle"
121
+ style="margin-left: 30px;margin-right: 0px;" type="button" id="tablesDropdown"
122
+ data-bs-toggle="dropdown" aria-expanded="false">
123
+ Select Tables
124
+ </button>
125
+ <ul class="dropdown-menu" aria-labelledby="tablesDropdown">
126
+ <li>
127
+ <select type="text" id="tableschema" name="tableschema" class="form-control"
128
+ multiple required>
129
+ <option value="customer_master">customer_master</option>
130
+ <option value="efs_company_master">efs_company_master</option>
131
+ <option value="efs_group_company_master">efs_group_company_master
132
+ </option>
133
+ <option value="efs_region_master">efs_region_master</option>
134
+ <option value="party_address_detail">party_address_detail</option>
135
+ <option value="wms_warehouse_master">wms_warehouse_master</option>
136
+ </select>
137
+ </li>
138
+ </ul>
139
+ </div>
140
+ </div>
141
+ </div>
142
+ <!-- <div class="col-md-3">
143
+ <div class="btn-container1">
144
+ <button type="button" id="saveBtn" class="btn btn-primary">Save</button>
145
+ </div>
146
+ </div>
147
+ </div>
148
+ <div class="row">-->
149
+ <div class="col-md-3">
150
+ <div class="form-group1">
151
+ <label for="selectedTables" id="labelselected">Selected Tables</label>
152
+ <textarea type="text" id="selectedTables" name="selectedTables" class="form-control"
153
+ rows="4" readonly></textarea>
154
+ </div>
155
+ </div>
156
+
157
+ <div class="col-md-3">
158
+ <div class="form-group">
159
+ <div class="btn-container1">
160
+ <button type="submit" id="saveBtn" class="btn btn-primary">Save</button>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </form>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ <footer class="footer">
171
+ {%include 'footer.html'%}
172
+ </footer>
173
+ <script>
174
+
175
+ document.addEventListener('DOMContentLoaded', function () {
176
+ // fetchCompanies();
177
+ // const companySelect = document.getElementById('company');
178
+ // const databaseconnectorForm = document.getElementById('databaseconnectorForm');
179
+ // database.addEventListener('change', async function () {
180
+ // $("#message-container").empty();
181
+ // });
182
+ // companySelect.addEventListener('change', async function () {
183
+ // $("#message-container").empty();
184
+ // const selectedCompanyName = companySelect.options[companySelect.selectedIndex].text;
185
+ // console.log(`Selected Company Name: ${selectedCompanyName}`);
186
+
187
+ // if (selectedCompanyName !== "Select") {
188
+ // $("#schema-table-section").hide();
189
+ // try {
190
+ // const response = await fetch(`/api/company_id?company_name=${encodeURIComponent(selectedCompanyName)}`);
191
+ // if (!response.ok) {
192
+ // throw new Error('Network response was not ok');
193
+ // }
194
+ // const data = await response.json();
195
+ // console.log(`Company ID: ${data.company_id}`);
196
+ // const companyId = data.company_id;
197
+ // document.getElementById('company_id').value = companyId;
198
+ var table = $('#databaseconnecorsform').show();
199
+ const role = sessionStorage.getItem('userRole');
200
+ const passedCompanyName = sessionStorage.getItem('company_name')
201
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
202
+ console.log('Current role:', role); // Debug statement to check the role
203
+ const storecompany_id = sessionStorage.getItem('company_id');
204
+ document.getElementById("company_id").value = storecompany_id;
205
+
206
+ data_get_from_db(storecompany_id, passedCompanyName);
207
+ });
208
+ async function data_get_from_db(storecompany_id, selectedCompanyName) {
209
+
210
+ if (storecompany_id) {
211
+ try {
212
+ const connectorsResponse = await fetch(`/api/check_data_connectors?company_id=${storecompany_id}&company_name=${selectedCompanyName}`);
213
+ if (!connectorsResponse.ok) {
214
+ throw new Error('data connector Network response was not ok');
215
+ }
216
+ const connectorsData = await connectorsResponse.json();
217
+ //setMultiSelectValues(document.getElementById('database'), connectorsData.databasetype); // Ensure this is an array
218
+ //setMultiSelectValues(document.getElementById('databaseName'), connectorsData.database_name); // Ensure this is an array
219
+ document.getElementById('database').value = connectorsData.databasetype;
220
+ document.getElementById('server').value = connectorsData.serverip; // document.getElementById('server').value = connectorsData.serverip;
221
+ document.getElementById('port').value = connectorsData.port;
222
+ document.getElementById('databaseName').value = connectorsData.database_name;
223
+ document.getElementById('username').value = connectorsData.username;
224
+ document.getElementById('password').value = connectorsData.password;
225
+ document.getElementById('selectedTables').value = connectorsData.dbtablename;
226
+ databaseconnectorForm.style.display = 'block';
227
+
228
+ } catch (error) {
229
+ document.getElementById('database').value = " ";
230
+ document.getElementById('server').value = " ";
231
+ document.getElementById('port').value = " ";
232
+ document.getElementById('databaseName').value = " ";
233
+ document.getElementById('username').value = " ";
234
+ document.getElementById('password').value = "";
235
+ document.getElementById('selectedTables').value = " ";
236
+ console.error('Error fetching data from data connectors:', error);
237
+ ("Company name does not exist. Please fill in the details.");
238
+
239
+ // Optionally, you can insert a message into the DOM
240
+ const messageContainer = document.getElementById('message-container');
241
+ if (messageContainer) {
242
+ messageContainer.innerHTML = "<div class='alert alert-danger'>Database details does not exist for this Company name.. Please fill in the details.</div>";
243
+ }
244
+
245
+
246
+ databaseconnectorForm.style.display = 'block';
247
+ }
248
+ } else {
249
+ console.log(`Company ID does not exist, you can create and save data: ${data.company_id}`);
250
+ databaseconnectorForm.style.display = 'none';
251
+ }
252
+ }
253
+
254
+ // } catch (error) {
255
+
256
+ // console.error('Error fetching company ID or data connectors:', error);
257
+ // databaseconnectorForm.style.display = 'none';
258
+ // }
259
+ // } else {
260
+ // databaseconnectorForm.style.display = 'none';
261
+ // }
262
+ // });
263
+
264
+ // document.getElementById("connectBtn").addEventListener("click", function (event) {
265
+ // var database = document.getElementById("database").value;
266
+ // var server = document.getElementById("server").value;
267
+ // var port = document.getElementById("port").value;
268
+ // var databaseName = document.getElementById("databaseName").value;
269
+ // var username = document.getElementById("username").value;
270
+ // var password = document.getElementById("password").value;
271
+
272
+ // if (!database || !server || !port || !databaseName || !username || !password) {
273
+ // alert("Please fill in all required fields.");
274
+ // return;
275
+ // }
276
+
277
+ // document.getElementById("schema-table-section").style.display = "block";
278
+ // });
279
+ $("#tableschema").change(function () {
280
+ var selectedTables = $(this).val();
281
+ var currentText = $("#selectedTables").val();
282
+ selectedTables.forEach(function (table) {
283
+ if (!currentText.includes(table)) {
284
+ if (currentText.length > 1) {
285
+ currentText += ", " + table;
286
+ } else {
287
+ currentText = table;
288
+ }
289
+ }
290
+ });
291
+ $("#selectedTables").val(currentText);
292
+ });
293
+ document.getElementById("connectBtn").addEventListener("click", function (event) {
294
+ var database = document.getElementById("database").value;
295
+ var server = document.getElementById("server").value;
296
+ var port = document.getElementById("port").value;
297
+ var databaseName = document.getElementById("databaseName").value;
298
+ var username = document.getElementById("username").value;
299
+ var password = document.getElementById("password").value || "";
300
+
301
+ if (!database || !server || !port || !databaseName || !username) {
302
+ alert("Please fill in all required fields.");
303
+ return;
304
+ }
305
+ // document.getElementById("schema-table-section").style.display = "block";
306
+ fetch("/api/connect", {
307
+ method: "POST",
308
+ headers: {
309
+ "Content-Type": "application/json"
310
+ },
311
+ body: JSON.stringify({
312
+ database_type: database,
313
+ server: server,
314
+ port: port,
315
+ databaseName: databaseName,
316
+ username: username,
317
+ password: password
318
+ })
319
+ })
320
+ .then(response => response.json())
321
+ .then(data => {
322
+ if (data.success) {
323
+ document.getElementById("schema-table-section").style.display = "block";
324
+ populateSchemaDropdown(data.schemas);
325
+ // Set default selection for tables
326
+ if (data.schemas.length > 0) {
327
+ updateTablesDropdown(data.schema_tables, data.schemas[0]);
328
+ schemas.addEventListener("change", function (event) {
329
+ var selectedSchema = event.target.value;
330
+ updateTablesDropdown(data.schema_tables, selectedSchema);
331
+ });
332
+ }
333
+ } else {
334
+ alert("Failed to connect to the database. Please check your credentials.");
335
+ document.getElementById("schema-table-section").style.display = "none";
336
+ }
337
+ })
338
+ .catch(error => {
339
+ console.error("Error:", error);
340
+ alert("An error occurred while connecting to the database.");
341
+ });
342
+ });
343
+
344
+ function populateSchemaDropdown(schemas) {
345
+ var schemaSelect = document.getElementById("schemas");
346
+ schemaSelect.innerHTML = ""; // Clear any existing options
347
+
348
+ schemas.forEach(function (schema) {
349
+ var option = document.createElement("option");
350
+ option.value = schema;
351
+ option.textContent = schema;
352
+ schemaSelect.appendChild(option);
353
+ });
354
+
355
+ }
356
+
357
+ function updateTablesDropdown(schemaTables, selectedSchema) {
358
+ var tableSchemaSelect = document.getElementById("tableschema");
359
+ tableSchemaSelect.innerHTML = ""; // Clear any existing options
360
+
361
+ if (schemaTables[selectedSchema]) {
362
+ schemaTables[selectedSchema].forEach(function (table) {
363
+ var option = document.createElement("option");
364
+ option.value = table;
365
+ option.textContent = table;
366
+ tableSchemaSelect.appendChild(option);
367
+ });
368
+ }
369
+ }
370
+
371
+ document.getElementById("saveBtn").addEventListener("click", async function (event) {
372
+ event.preventDefault(); // Prevent the default form submission
373
+
374
+ // Set the password value
375
+ //document.getElementById("password").value = "root";
376
+
377
+ const form = document.getElementById('databaseconnectorForm');
378
+ const formData = new FormData(form);
379
+ formData.append("company_id", document.getElementById('company_id').value);
380
+ try {
381
+ console.log("inside save", formData);
382
+ console.log("comaonyid", document.getElementById('company_id').value);
383
+ for (const [key, value] of formData.entries()) {
384
+ console.log(`${key}: ${value}`);
385
+ }
386
+ const response = await fetch(form.action, {
387
+ method: "POST",
388
+ body: formData
389
+ });
390
+
391
+ if (!response.ok) {
392
+ throw new Error('Network response was not ok');
393
+ }
394
+
395
+ const data = await response.json();
396
+
397
+ console.log("result", response);
398
+
399
+ const messageContainer = document.getElementById('message-container');
400
+ if (data.created) {
401
+ if (messageContainer) {
402
+ const messageType = data.created ? 'alert-success' : 'alert-danger';
403
+ messageContainer.innerHTML = `
404
+ <div class='alert ${messageType}'>
405
+ ${data.msg}
406
+ <button class='close'style='font-size:medium;margin-top:6px;'onclick='dismissMessage()'>OK</button>
407
+ </div>`;
408
+ }
409
+ }
410
+
411
+ } catch (error) {
412
+ console.error('Error saving data:', error);
413
+ const messageContainer = document.getElementById('message-container');
414
+ if (messageContainer) {
415
+ messageContainer.innerHTML = `
416
+ <div class='alert alert-danger'>
417
+ An error occurred while saving data in database.
418
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
419
+ </div>`;
420
+ }
421
+ }
422
+ });
423
+
424
+
425
+ function dismissMessage() {
426
+ const messageContainer = document.getElementById('message-container');
427
+ if (messageContainer) {
428
+ messageContainer.innerHTML = '';
429
+ }
430
+ }
431
+ function handleError() {
432
+ document.getElementById('database').value = " ";
433
+ document.getElementById('server').value = " ";
434
+ document.getElementById('port').value = " ";
435
+ document.getElementById('databaseName').value = " ";
436
+ document.getElementById('username').value = " ";
437
+ document.getElementById('password').value = " ";
438
+ }
439
+
440
+
441
+ function setMultiSelectValues(selectElement, values) {
442
+ // Ensure values is an array
443
+ if (!Array.isArray(values)) {
444
+ values = [values];
445
+ }
446
+ Array.from(selectElement.options).forEach(option => {
447
+ option.selected = values.includes(option.value);
448
+ });
449
+ }
450
+ </script>
451
+ </body>
452
+
453
+ </html>
templates/footer.html ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- footer
2
+ This is the HTML code for the footer section of a web page.
3
+ It displays the version number and copyright information.
4
+
5
+ HTML Structure:
6
+ - The footer element has a class of "main-footer".
7
+ - Inside the footer, there is a div element with classes "float-right" and "d-none d-sm-block".
8
+ - Inside the div, there is a bold tag (<b>) displaying the version number.
9
+ - After the div, there is a strong tag (<strong>) displaying the copyright information.
10
+ - The copyright information includes the year and a link to the company's website.
11
+
12
+ Example Usage:
13
+ <footer class="main-footer">
14
+ <div class="float-right d-none d-sm-block">
15
+ <b>Version</b> 3.0.5
16
+ </div>
17
+ <strong>&copy; 2023 <a href="https://yourcompany.com">Your Company</a>.</strong> All rights reserved.
18
+ </footer>
19
+
20
+ <footer class="main-footer" style="position: absolute; bottom: 0; width: 100%; color: black; text-align: right; padding-right:245px ;">
21
+ <div class="container-fluid">
22
+ <a href="https://redmindtechnologies.com" target="_blank" style="color: black; text-decoration: none;">Visit Redmind Technologies at https://redmindtechnologies.com</a>
23
+ </div>
24
+ </footer>
templates/index.html ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
+ <title>Sign In/Up Form</title>
9
+ <!-- Google Font -->
10
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:400,800" rel="stylesheet">
11
+ <!-- Font Awesome -->
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
13
+ <link rel="stylesheet" href="/static/css/index.css">
14
+ <style>
15
+
16
+ </style>
17
+ </head>
18
+
19
+ <body class="login-page" style="background-image: url('static/img/AI.jpg'); background-size: cover;">
20
+ <main>
21
+ <div class="container" id="container">
22
+ <div class="form-container sign-up-container">
23
+ <form action='/validate-user' name='signUpForm' method="post">
24
+ <h1>Create Account</h1>
25
+ <div class="social-container">
26
+ <a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
27
+ <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
28
+ <a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
29
+ </div>
30
+ <span>or use your email for registration</span>
31
+ <input type="text" placeholder="Name" required />
32
+ <input type="password" placeholder="Password" required />
33
+ <button type="submit">Sign Up</button>
34
+ </form>
35
+ </div>
36
+
37
+ <div class="form-container sign-in-container" id="form-container">
38
+ <form action='/validate-user' name='loginForm' method="post" onsubmit="return validateForm()">
39
+ <h1>Sign in</h1>
40
+ <div class="social-container">
41
+ <a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
42
+ <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
43
+ <a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
44
+ </div>
45
+ <span>or use your account</span>
46
+ <input type="text" name="username" placeholder="Username" required />
47
+ <input type="password" name="password" placeholder="Password" required />
48
+ <a href="#">Forgot your password?</a>
49
+ <button type="submit">Sign In</button>
50
+ </form>
51
+ </div>
52
+
53
+ <div class="overlay-container">
54
+ <div class="overlay">
55
+ <div class="overlay-panel overlay-left">
56
+ <h1>Welcome Back!</h1>
57
+ <p>To keep connected with us please login with your personal info</p>
58
+ <button type="submit" class="ghost" id="signIn">Sign In</button>
59
+ </div>
60
+ <div class="overlay-panel overlay-right">
61
+ <div class="logo-container">
62
+ <img src="/static/img/redmindlogo3.jpg" alt="Logo" class="logo">
63
+ </div>
64
+ <h1>RedMindGPT</h1>
65
+ <p> Start Journey With Us</p>
66
+ <button class="ghost" id="signUp">Sign Up</button>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </main>
72
+
73
+ <footer>
74
+ <p>Developed with <i class="fas fa-heart"></i> by <a href="#">RedMind</a></p>
75
+ </footer>
76
+
77
+ <script>
78
+ const signUpButton = document.getElementById('signUp');
79
+ const signInButton = document.getElementById('signIn');
80
+ const container = document.getElementById('container');
81
+ const formcontainer = document.getElementById('form-container');
82
+
83
+ signUpButton.addEventListener('click', () => {
84
+ container.classList.add("right-panel-active");
85
+ formcontainer.style.display = 'none'
86
+ });
87
+
88
+ signInButton.addEventListener('click', () => {
89
+ container.classList.remove("right-panel-active");
90
+ formcontainer.style.display = 'block'
91
+
92
+ });
93
+ </script>
94
+ </body>
95
+
96
+ </html>
templates/knowledgebase.html ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
8
+ <!-- Include AdminLTE CSS -->
9
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1/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/admin-lte@3.1/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
+ <link rel="stylesheet" href="/static/css/knowledgebase.css">
19
+ </head>
20
+
21
+ <body>
22
+ {% include 'sidepane.html' %}
23
+ <div class="wrapper">
24
+ <div class="main-header" style="border-bottom: none;">
25
+ <div class="container mt-2">
26
+ <div id="company-select" class="form-group left-align">
27
+ <!-- <label for="company" class="mr-1" style="margin-left:-40px; margin-top: 12px;">Company Name <span class="text-danger">*</span></label>
28
+ <select type="text" id="company" name="company" class="form-control" style="width:20%;margin-left:-40px;"required>
29
+ <option value="" selected>Select</option>
30
+ </select> -->
31
+ <!-- <div class="col-12 d-flex justify-content-end mb-3">
32
+ <button class="btn btn-primary" style="margin-top:10px;margin-right: -10px;position: fixed;"
33
+ id="add" data-action="add">Add</button>
34
+ </div> -->
35
+ </div>
36
+ </div>
37
+ <div class="row">
38
+ <div id="message-container" style="margin-left: 200px;width:600px;"></div>
39
+ </div>
40
+ <h3 id="company_name" style="margin-left: 400px;">{{company_name}}</h3>
41
+ <section class="content" id="contentSection" style="display: none;">
42
+ <div class="container-fluid">
43
+ <div>
44
+ <div class="form-group">
45
+ <!-- <label for="company_id">company_id</label>--->
46
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
47
+ </div>
48
+ <h4 id="selectedCompany" style="margin-left: 300px;"></h4>
49
+ <div class="row" style="margin-top: 50px;">
50
+ <div class="col-12">
51
+ <div class="card">
52
+ <div id="message-container">
53
+ <div class="card-body table-container">
54
+ <table id="knowledgeTable" class="table table-bordered table-striped">
55
+ <thead>
56
+ <tr>
57
+
58
+ <th>Sno</th>
59
+ <th>Document Name</th>
60
+ <th>Document Description</th>
61
+ <th>Document Version</th>
62
+ <th>VectorDB Flag</th>
63
+ <th>View</th>
64
+ <th>Edit</th>
65
+ <th>Delete</th>
66
+ <!-- <th style="display:none;">Company ID</th> -->
67
+ </tr>
68
+ </thead>
69
+ <tbody>
70
+
71
+ </tbody>
72
+ </table>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </section>
79
+ </div>
80
+
81
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
82
+ aria-hidden="true">
83
+ <div class="modal-dialog" role="document">
84
+ <div class="modal-content">
85
+ <div class="modal-header">
86
+ <h5 class="modal-title" id="addModalLabel">Add Document Details</h5>
87
+ <button type="button" class="btn-close" data-dismiss="modal">
88
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false"></span>
89
+ </button>
90
+ </div>
91
+ <div class="modal-body">
92
+ <div class="form-group">
93
+ <!-- <label for="company_id">company_id</label>--->
94
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
95
+ </div>
96
+ <form id="documentForm">
97
+ <div class="form-group">
98
+ <label for="uploadFile">Upload File<span class="text-danger">*</span></label>
99
+ <span id="file-name"></span>
100
+ <input type="hidden" id="file_name" name="file_name" class="form-control" required>
101
+ <input type="file" class="form-control-file" id="uploadFile" name="uploadFile" required
102
+ accept=".pdf,.doc,.docx">
103
+ <small class="form-text text-muted">Accepted formats: .pdf, .doc, .docx</small>
104
+ </div>
105
+ <div class="form-group">
106
+ <label for="documentName">Document Name<span class="text-danger">*</span></label>
107
+ <input type="text" class="form-control" id="documentName" name="documentName" required>
108
+ </div>
109
+ <div class="form-group">
110
+ <label for="documentDescription">Document Description<span
111
+ class="text-danger">*</span></label>
112
+ <textarea class="form-control" id="documentDescription" name="documentDescription"
113
+ rows="3" required></textarea>
114
+ </div>
115
+ <div class="form-group">
116
+ <label for="department">Department<span class="text-danger">*</span></label>
117
+ <input type="text" class="form-control" id="department" name="department" required>
118
+ </div>
119
+ <div class="form-group">
120
+ <label for="version">Version<span class="text-danger">*</span></label>
121
+ <input type="text" class="form-control" id="version" name="version" required>
122
+ </div>
123
+ <div class="form-group">
124
+ <label for="lastUpdated">Last Updated<span class="text-danger">*</span></label>
125
+ <input type="text" class="form-control" id="lastUpdated" name="lastUpdated" required>
126
+ </div>
127
+ </form>
128
+ </div>
129
+ <div class="modal-footer">
130
+ <!-- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> -->
131
+ <button type="button" id="saveupdate" class="btn btn-primary"
132
+ style="display: none;">Update</button>
133
+ <button type="button" id="save" onclick="save_file()" class="btn btn-primary">Save</button>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ </div>
139
+
140
+ {%include 'footer.html'%}
141
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
142
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
143
+
144
+ <script>
145
+ var table = $('#knowledgeTable').DataTable();
146
+ const role = sessionStorage.getItem('userRole');
147
+ const company_name = sessionStorage.getItem('company_name');
148
+ console.log("company_name", company_name);
149
+ // document.getElementById('company_name').textContent = company_name;
150
+
151
+ document.addEventListener("DOMContentLoaded", function () {
152
+ now = new Date().toISOString().replace('T', ' ').substr(0, 19);
153
+ document.getElementById('lastUpdated').value = now;
154
+ const inputs = document.querySelectorAll("#documentForm input, textarea");
155
+ inputs.forEach((input, index) => {
156
+ input.addEventListener("keydown", function (event) {
157
+ if (event.key === "Enter") {
158
+ event.preventDefault();
159
+ moveToNextInput(inputs, index);
160
+ }
161
+ });
162
+ });
163
+
164
+ const passedCompanyName = sessionStorage.getItem('company_name')
165
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
166
+ console.log('Current role:', role); // Debug statement to check the role
167
+ const company_id = sessionStorage.getItem('company_id');
168
+ document.getElementById("company_id").value = company_id;
169
+ console.log("inside knowledgebaae sessionstorage", company_id);
170
+ data_get_from_db(company_id);
171
+
172
+
173
+
174
+
175
+ const companySelect = document.getElementById('company');
176
+ const documentForm = document.getElementById('documentForm');
177
+
178
+
179
+ });
180
+ function moveToNextInput(inputs, currentIndex) {
181
+ const nextInput = inputs[currentIndex + 1];
182
+ if (nextInput) {
183
+ nextInput.focus();
184
+ } else {
185
+ // Optionally, submit the form or trigger the save button
186
+ document.getElementById("save").focus();
187
+ }
188
+ }
189
+
190
+ async function data_get_from_db(company_id) {
191
+ if (company_id) {
192
+ try {
193
+ const Response = await fetch(`/api/document_upload?company_id=${company_id}`);
194
+ console.log("responce from api :==> ", Response)
195
+ const connectorsResponse = await Response.json();
196
+ console.log("knowledge data table after connecting to table", connectorsResponse);
197
+ const table = $('#knowledgeTable').DataTable(); // Initialize DataTable at the start
198
+ table.clear();
199
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
200
+ // displayEmptyTable();
201
+ displayErrorMessage("Document details do not exist for this company. Please fill in the details.");
202
+ contentSection.style.display = 'none';
203
+ } else {
204
+ console.log('company data retrived succesfully ! .........')
205
+ connectorsResponse.forEach((company, index) => {
206
+ table.row.add([
207
+ index + 1,
208
+ company.document_name,
209
+ company.document_desc,
210
+ company.version,
211
+ company.vectorDBflag,
212
+ `<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>`,
213
+ `<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>`,
214
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
215
+ company.row_id
216
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>",
217
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
218
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
219
+ ]).draw(false);
220
+ });
221
+ contentSection.style.display = 'block';
222
+ }
223
+ } catch (error) {
224
+ console.error('Error fetching company documents:', error);
225
+ //displayEmptyTable();
226
+
227
+ displayErrorMessage("Document details1 do not exist for this company. Please fill in the details.");
228
+ contentSection.style.display = 'none';
229
+ }
230
+ } else {
231
+ // displayEmptyTable();
232
+
233
+ displayErrorMessage("Details for knowledgebase do not exist for this company. Please fill in the details.");
234
+ }
235
+
236
+ }
237
+
238
+ function displayErrorMessage(message) {
239
+ const messageContainer = document.getElementById('message-container');
240
+ if (messageContainer) {
241
+ messageContainer.innerHTML = `<div class='alert alert-danger'>${message}</div>`;
242
+ }
243
+ }
244
+
245
+
246
+
247
+ function clearFormFields() {
248
+ document.getElementById('file-name').textContent = ""
249
+ document.getElementById('uploadFile').value = "";
250
+ document.getElementById('documentName').value = "";
251
+ document.getElementById('documentDescription').value = "";
252
+ document.getElementById('department').value = "";
253
+ document.getElementById('version').value = "";
254
+ // document.getElementById('lastUpdated').value = "";
255
+ }
256
+
257
+
258
+ $(document).ready(function () {
259
+ // Show modal function
260
+ $('#add').on('click', function () {
261
+ $('#documentName').removeAttr('readonly');
262
+ $('#documentDescription').removeAttr('readonly');
263
+ $('#department').removeAttr('readonly');
264
+ $('#version').removeAttr('readonly');
265
+ $('#lastUpdated').removeAttr('readonly');
266
+ const modalTitle = document.getElementById('addModalLabel');
267
+ modalTitle.textContent = 'Add Document Details';
268
+ $('#save').show();
269
+ $('#uploadFile').show();
270
+ $('#saveupdate').hide();
271
+ clearFormFields();
272
+ $('#message-container').empty(); // Clear the message container
273
+ $('#addModal').modal('show');
274
+ });
275
+ $('.modal-footer .btn-secondary, .modal-header .btn-close').on('click', function () {
276
+ $('#addModal').modal('hide');
277
+ });
278
+ // $('#knowledgeTable').DataTable({
279
+ // autoWidth: false
280
+ // });
281
+
282
+ });
283
+ function viewCompany(button) {
284
+ var companyId = $(button).data('kid-id');
285
+ const modalTitle = document.getElementById('addModalLabel');
286
+ modalTitle.textContent = 'View Document Details';
287
+ if (companyId) {
288
+ $.getJSON(`/api/getknowledgebase/${companyId}`, function (company) {
289
+ $('#uploadFile').hide();
290
+ $('#file-name').text(company.file_path).attr('readonly', 'readonly');
291
+ $('#documentName').val(company.document_name).attr('readonly', 'readonly');
292
+ $('#documentDescription').val(company.document_desc).attr('readonly', 'readonly');
293
+ $('#department').val(company.department).attr('readonly', 'readonly');
294
+ $('#version').val(company.version).attr('readonly', 'readonly');
295
+ //$('#lastUpdated').val(company.last_updated).attr('readonly', 'readonly');
296
+ var lastUpdated = company.last_updated;
297
+ $('#lastUpdated').val(lastUpdated).attr('readonly', 'readonly');
298
+ $('#save').hide();// Disable the "Save" button when the modal opens
299
+ $('#addModal').modal('show');
300
+ }).fail(function () {
301
+ alert("Error retrieving knowledge base check the sidepane working.");
302
+ });
303
+ }
304
+ }
305
+
306
+ // Edit knowledge base details
307
+ function editCompany(button) {
308
+ var companyId = $(button).data('kid-id');
309
+
310
+ const modalTitle = document.getElementById('addModalLabel');
311
+ modalTitle.textContent = 'Edit Document Details';
312
+
313
+ // Fetch company details by ID
314
+ if (companyId) {
315
+ $.getJSON(`/api/getknowledgebase/${companyId}`, function (company) {
316
+
317
+ const fileName = company.file_path.split('/').pop();
318
+ const fileContent = new Blob([""], { type: 'text/plain' });
319
+ const file = new File([fileContent], fileName, { type: fileContent.type });
320
+ const dataTransfer = new DataTransfer();
321
+ dataTransfer.items.add(file);
322
+
323
+ // Set the file input's files property to the created file
324
+ const fileInput = document.getElementById('uploadFile');
325
+ fileInput.files = dataTransfer.files;
326
+
327
+ // Check if the input element is of type 'file'
328
+ if (fileInput.type === 'file') {
329
+ console.log("The input is of type 'file'.");
330
+ } else {
331
+ console.log("The input is NOT of type 'file'.");
332
+ }
333
+
334
+ // Check if the value is of type 'File'
335
+ const files = fileInput.files;
336
+ if (files.length > 0 && files[0] instanceof File) {
337
+ console.log("The value is of type 'File':", files[0].name);
338
+ } else {
339
+ console.log("No file is selected or the value is not of type 'File'.");
340
+ }
341
+
342
+ $('#uploadFileLabel').text(files[0].name);
343
+ $('#uploadFile').text(files[0].name)
344
+ $('#documentName').val(company.document_name);
345
+ $('#documentDescription').val(company.document_desc);
346
+ $('#department').val(company.department);
347
+ $('#version').val(company.version);
348
+ $('#lastUpdated').val(company.last_updated).attr('readonly', 'readonly');
349
+ $('#company_id').val(company.company_id);
350
+
351
+ // Show/hide appropriate elements
352
+ $('#uploadFile').show(); // Hide the file upload field
353
+ $('#save').hide(); // Hide the default save button
354
+ $('#saveupdate').show(); // Show the update button
355
+
356
+ // Ensure fields are editable
357
+ $('#documentName').removeAttr('readonly');
358
+ $('#documentDescription').removeAttr('readonly');
359
+ $('#department').removeAttr('readonly');
360
+ $('#version').removeAttr('readonly');
361
+ // $('#lastUpdated').removeAttr('readonly');
362
+ $('#company_id').val(company.company_id); // Ensure company_id is included if necessary
363
+
364
+ // Show the modal
365
+ $('#addModal').modal('show');
366
+
367
+ // Set up the click event for the update button
368
+ $('#saveupdate').off('click').on('click', function () {
369
+ saveupdate(companyId, files[0].name); // Pass the company ID for updating
370
+ });
371
+ }).fail(function () {
372
+ alert("Error retrieving knowledge base error 2 details.");
373
+ });
374
+ }
375
+ }
376
+
377
+ // Delete company
378
+ function deleteCompany(button) {
379
+ var companyId = $(button).data('kid-id');
380
+ console.log("k_id deleted", companyId);
381
+ $.ajax({
382
+ type: "DELETE",
383
+ url: `/api/delknowledgebase/${companyId}`,
384
+ success: function () {
385
+ var table = $('#knowledgeTable').DataTable();
386
+ table.row($(button).closest('tr')).remove().draw();
387
+ //alert("Company deleted successfully.");
388
+ const messageContainer = document.getElementById('message-container');
389
+ if (messageContainer)
390
+ messageContainer.innerHTML = `
391
+ <div class='alert alert-danger'>
392
+ Prompt details deleted successfully
393
+ <button class='close' onclick='dismissMessage()'>OK</button>
394
+ </div>`;
395
+ // fetchCompanies(); // Refresh the table
396
+ },
397
+ error: function (xhr) {
398
+ alert("Error deleting company: " + xhr.responseJSON.detail);
399
+ }
400
+ });
401
+ }
402
+ function saveupdate(companyId, filename) {
403
+ const formData = new FormData();
404
+ const fileInput = document.getElementById("uploadFile");
405
+ const uploadFile = fileInput.files[0]; // Get the file object
406
+ const company_id = document.getElementById("company_id").value;
407
+ formData.append("company_id", $('#company_id').val());
408
+ formData.append("documentName", $('#documentName').val());
409
+ formData.append("documentDescription", $('#documentDescription').val());
410
+ formData.append("department", $('#department').val());
411
+ formData.append("version", $('#version').val());
412
+ formData.append("vectorDBFlag", 'NO');
413
+ formData.append("lastUpdated", $('#lastUpdated').val());
414
+ console.log("company_id to table refresh", company_id)
415
+ // Append the file only if it exists, otherwise, append the filename
416
+ if (uploadFile) {
417
+ formData.append("file_path", uploadFile); // Append the file object
418
+ } else {
419
+ formData.append("file_path", filename); // Append the existing filename
420
+ }
421
+
422
+ $.ajax({
423
+ url: `/api/putknowledgebase/${companyId}`,
424
+ type: 'PUT',
425
+ data: formData,
426
+ processData: false, // Required for FormData
427
+ contentType: false, // Required for FormData
428
+ success: function (response) {
429
+ // alert('Knowledgebase details updated successfully.');
430
+ const messageContainer = document.getElementById('message-container');
431
+ if (messageContainer)
432
+ messageContainer.innerHTML = `
433
+ <div class='alert alert-success'>
434
+ Data saved successfully
435
+ <button class='close' onclick='dismissMessage()'>OK</button>
436
+ </div>`;
437
+ $('#addModal').modal('hide'); // Close the modal after saving
438
+ fetchUpdatedDocuments(company_id);
439
+ },
440
+ error: function () {
441
+ alert('Form has no changes to update knowledge base details.');
442
+ }
443
+ });
444
+ }
445
+
446
+ async function fetchUpdatedDocuments(company_id) {
447
+ console.log("company_id", company_id);
448
+ var table = $('#knowledgeTable').DataTable();
449
+ const Response = await fetch(`/api/document_update?company_id=${company_id}`);
450
+ const connectorsResponse = await Response.json();
451
+ console.log("knowledge data table after connecting to table", connectorsResponse);
452
+ table.clear();
453
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
454
+ //displayEmptyTable();
455
+
456
+ displayErrorMessage("Document details do not exist for this company. Please fill in the details.");
457
+ contentSection.style.display = 'none';
458
+ } else {
459
+
460
+ connectorsResponse.forEach((company, index) => {
461
+ table.row.add([
462
+ index + 1,
463
+ company.document_name,
464
+ company.document_desc,
465
+ company.version,
466
+ company.vectorDBflag,
467
+ `<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>`,
468
+ `<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>`,
469
+ //`<a href='#' class='btn btn-danger btn-sm' onclick='deleteCompany(${company.company_id})'><i class='fas fa-trash'></i></a>`,
470
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
471
+ company.row_id
472
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>",
473
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
474
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
475
+ ]).draw(false);
476
+ });
477
+ contentSection.style.display = 'block';
478
+ }
479
+ }
480
+
481
+ function save_file() {
482
+ const form = document.getElementById('documentForm');
483
+
484
+ // Check if the form is valid
485
+ if (!form.checkValidity()) {
486
+ // If the form is invalid, show validation messages and stop the submission
487
+ form.reportValidity();
488
+ return;
489
+ }
490
+ const uploadFile = document.getElementById("uploadFile").files[0];
491
+ const documentName = document.getElementById("documentName").value;
492
+ const documentDescription = document.getElementById("documentDescription").value;
493
+ const department = document.getElementById("department").value;
494
+ const version = document.getElementById("version").value;
495
+ const lastUpdated = document.getElementById("lastUpdated").value;
496
+ const company_id = document.getElementById("company_id").value;
497
+
498
+ //const formData = new FormData();
499
+ var formData = new FormData($('#documentForm')[0]);
500
+ const vectorDBFlag = "NO"; // Example value
501
+ // const view = "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>";
502
+ // const edit = "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>";
503
+ // const dele= "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></a>";
504
+
505
+
506
+ formData.append("uploadFile", uploadFile);
507
+ formData.append("documentName", documentName);
508
+ formData.append("documentDescription", documentDescription);
509
+ formData.append("department", department);
510
+ formData.append("version", version);
511
+ formData.append("lastUpdated", lastUpdated);
512
+ formData.append("vectorDBflag", vectorDBFlag);
513
+ formData.append("company_id", company_id);
514
+ console.log("formdata", formData);
515
+ fetch('/upload_document', {
516
+ method: 'POST',
517
+ body: formData
518
+ })
519
+ .then(response => {
520
+ if (!response.ok) {
521
+ throw new Error('Network response was not ok');
522
+ }
523
+ return response.json();
524
+ })
525
+ .then(data => {
526
+ const row_id = data.row_id;
527
+ var table = $('#knowledgeTable').DataTable();
528
+ var rowCount = table.rows().count();
529
+ 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>`;
530
+ 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>`;
531
+ 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>`;
532
+ table.row.add([
533
+ rowCount + 1,
534
+ documentName,
535
+ documentDescription,
536
+ version,
537
+ vectorDBFlag,
538
+ view,
539
+ edit,
540
+ dele
541
+ ]).draw(false);
542
+
543
+ const messageContainer = document.getElementById('message-container');
544
+ if (messageContainer)
545
+ messageContainer.innerHTML = `
546
+ <div class='alert alert-success'>
547
+ Knowledgebase Data saved successfully
548
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
549
+ </div>`;
550
+ // alert('Document saved successfully');
551
+ $('#addModal').modal('hide');
552
+ document.getElementById('contentSection').style.display = 'block'; // Show the table section
553
+ })
554
+ .catch(error => console.error('Error:', error));
555
+ }
556
+ function dismissMessage() {
557
+ const messageContainer = document.getElementById('message-container');
558
+ if (messageContainer) {
559
+ messageContainer.innerHTML = '';
560
+ }
561
+ }
562
+
563
+ </script>
564
+ </body>
565
+
566
+ </html>
templates/prompt_template.html ADDED
@@ -0,0 +1,548 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
8
+ <!-- Include AdminLTE CSS -->
9
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/admin-lte@3.1/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
+
16
+ </head>
17
+
18
+ <body>
19
+ {% include 'sidepane.html' %}
20
+
21
+ <div class="wrapper">
22
+ <div class="main-header" style="border-bottom: none;">
23
+ <!-- Content Header (Page header) -->
24
+ <div class="content-header">
25
+ <div class="container-fluid">
26
+ <div class="container mt-2">
27
+ <div class="form-group left-align" id="company-select">
28
+ <!-- <label for="company" class="mr-1" style="margin-left:-60px;margin-top:-11px;">Company Name
29
+ <span class="text-danger">*</span></label>
30
+ <select type="text" id="company" name="company" class="form-control "
31
+ style="width: 20%;margin-left:-60px;" required>
32
+ <option value="" selected>Select</option>
33
+ </select> -->
34
+ <h4 id="selectedCompany" style="margin-left: 300px;"></h4>
35
+ <!-- <div class="col-12 d-flex justify-content-end mb-2">
36
+ <button class="btn btn-primary"
37
+ style="margin-top:-40px;margin-right: -25px;position: fixed;" id="add">Add</button>
38
+
39
+
40
+ </div> -->
41
+ </div>
42
+ <div class="row">
43
+ <div id="message-container" style="margin-left: 150px;width:500px;"></div>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ <section class="content" id="contentSection" style="display: none;">
49
+ <div class="container-fluid">
50
+ <div class="form-group">
51
+ <!-- <label for="company_id">company_id</label>--->
52
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
53
+ </div>
54
+ </div>
55
+
56
+
57
+ <!-- Main content-->
58
+ <section class="content">
59
+ <div class="container-fluid">
60
+ <div class="row">
61
+ <div class="col-12">
62
+ <div class="card">
63
+ <div class="card-body table-container">
64
+ <table id="promptTable" class="table table-bordered table-striped">
65
+ <thead>
66
+ <tr>
67
+ <th>Sno</th>
68
+ <th>Datasource</th>
69
+ <th>Sample Prompt</th>
70
+ <th>View</th>
71
+ <th>Edit</th>
72
+ <th>Delete</th>
73
+ </tr>
74
+ </thead>
75
+ <tbody>
76
+ <!-- <tr>
77
+ <td>1</td>
78
+ <td>API</td>
79
+ <td>What are the details of ASN24080200002?</td>
80
+ <td><button class="btn btn-primary viewButton">View</button></td>
81
+ </tr>
82
+ <tr>
83
+ <td>2</td>
84
+ <td>API</td>
85
+ <td>What is the expected receiving date of ASN24080200002</td>
86
+ <td><button class="btn btn-primary viewButton">View</button></td>
87
+ </tr>
88
+ <tr>
89
+ <td>3</td>
90
+ <td>Document</td>
91
+ <td>Explain Pre-Receiving Yard Management</td>
92
+ <td><button class="btn btn-primary viewButton">View</button></td>
93
+ </tr>
94
+ <tr>
95
+ <td>4</td>
96
+ <td>Document</td>
97
+ <td>Can you explain the process of unloading a vehicle in more detail?</td>
98
+ <td><button class="btn btn-primary viewButton">View</button></td>
99
+ </tr>
100
+ <tr>
101
+ <td>5</td>
102
+ <td>Visual Analysis</td>
103
+ <td>I want to analyze item name and quantity in a bar chart in warehouse Allcargo Logistics</td>
104
+ <td><button class="btn btn-primary viewButton">View</button></td>
105
+ </tr>
106
+ <tr>
107
+ <td>6</td>
108
+ <td>Visual Analysis</td>
109
+ <td>Can you generate a pie chart with item names and quantities in warehouse Allcargo Logistics</td>
110
+ <td><button class="btn btn-primary viewButton">View</button></td>
111
+ </tr>
112
+ <tr>
113
+ <td>7</td>
114
+ <td>Database</td>
115
+ <td>What are the active warehouses available</td>
116
+ <td><button class="btn btn-primary viewButton">View</button></td>
117
+ </tr>
118
+ <tr>
119
+ <td>8</td>
120
+ <td>Database</td>
121
+ <td>What are the warehouses available</td>
122
+ <td><button class="btn btn-primary viewButton">View</button></td>
123
+ </tr>
124
+ -->
125
+ </tbody>
126
+ </table>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </section>
133
+ </section>
134
+ </div>
135
+
136
+ </div>
137
+
138
+ <!-- Modal -->
139
+ <div class="modal fade" id="addModal" tabindex="-1" role="dialog" aria-labelledby="addModalLabel"
140
+ aria-hidden="true">
141
+ <div class="modal-dialog" role="document">
142
+ <div class="modal-content">
143
+ <div class="modal-header">
144
+ <h5 class="modal-title" id="addModalLabel">Add Prompt templates</h5>
145
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"></button>
146
+ <span aria-hidden="true" data-backdrop="static" data-keyboard="false">&times;</span>
147
+ </div>
148
+ <div class="modal-body">
149
+ <div class="form-group">
150
+ <!-- <label for="company_id">company_id</label>--->
151
+ <input type="hidden" id="company_id" name="company_id" class="form-control" required>
152
+ </div>
153
+ <form id="addPromptForm">
154
+ <div class="form-group">
155
+ <label for="scenario">Scenario <span class="text-danger">*</span></label>
156
+ <input type="text" class="form-control" id="scenario" name="scenario" required>
157
+ </div>
158
+ <div class="form-group">
159
+ <label for="prompt">Sample Prompt <span class="text-danger">*</span></label>
160
+ <input type="text" class="form-control" id="prompt" name="sampleprompt" required>
161
+ </div>
162
+ <div class="form-group">
163
+ <label for="comments">Comments <span class="text-danger">*</span></label>
164
+ <input type="text" class="form-control" id="comments" name="comments" required>
165
+ </div>
166
+ </form>
167
+ </div>
168
+ <div class="modal-footer">
169
+ <button type="button" id="saveupdate" class="btn btn-primary" style="display: none;">Update</button>
170
+ <!-- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> -->
171
+ <button type="button" id="save" onclick="save_file()" class="btn btn-primary">Save</button>
172
+ </div>
173
+ </div>
174
+ </div>
175
+ </div>
176
+
177
+ { %include 'footer.html'%}
178
+ <!-- Include DataTables JS and your custom script -->
179
+ <script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
180
+ <script src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap4.min.js"></script>
181
+ <script>
182
+
183
+ var table = $('#promptTable').DataTable();
184
+ const role = sessionStorage.getItem('userRole');
185
+ console.log('Current role:', role); // Debug statement to check the role
186
+ const passedCompanyName = sessionStorage.getItem('company_name')
187
+ document.getElementById('selectedCompany').innerText = `Company Name: ${passedCompanyName}`;
188
+ const company_id = sessionStorage.getItem('company_id');
189
+ document.getElementById("company_id").value = company_id;
190
+
191
+ data_get_from_db(company_id);
192
+
193
+ // if (role === 'superadmin') {
194
+ // const storecompany_id = sessionStorage.getItem('company_id');
195
+ // data_get_from_db(storecompany_id);
196
+ // document.getElementById('company-select').style.display = 'block';
197
+ // //var companyId = getCookie('company_id')
198
+ // //console.log("company id for superadmin",storecompany_id);
199
+ // fetchCompanies();
200
+
201
+ // } else {
202
+ // document.getElementById('company-select').style.display = 'block';
203
+ // const storecompany_id = sessionStorage.getItem('company_id');
204
+ // console.log('Current company_id:', storecompany_id); // Debug statement to check the role
205
+ // data_get_from_db(storecompany_id);
206
+ // }
207
+
208
+ function moveToNextInput(inputs, currentIndex) {
209
+ const nextInput = inputs[currentIndex + 1];
210
+ if (nextInput) {
211
+ nextInput.focus();
212
+ } else {
213
+ // Optionally, submit the form or trigger the save button
214
+ document.getElementById("save").focus();
215
+ }
216
+ }
217
+
218
+ const companySelect = document.getElementById('company');
219
+ const addPromptForm = document.getElementById('addPromptForm');
220
+
221
+
222
+
223
+
224
+ async function data_get_from_db(companyId) {
225
+
226
+ if (companyId) {
227
+ try {
228
+ const Response = await fetch(`/api/get_prompt_templates?company_id=${companyId}`);
229
+ console.log("responce from api :==> ", Response)
230
+ const connectorsResponse = await Response.json();
231
+ console.log("knowledge data table after connecting to table", connectorsResponse);
232
+ console.log("prompt template data table after connecting to table", connectorsResponse);
233
+ const table = $('#promptTable').DataTable(); // Initialize DataTable at the start
234
+ table.clear();
235
+ if (!Array.isArray(connectorsResponse)) {
236
+ throw new TypeError('Expected an array of companies');
237
+ displayErrorMessage("prompt template details do not exist for this company. Please fill in the details.");
238
+ contentSection.style.display = 'none';
239
+ } else {
240
+
241
+ connectorsResponse.forEach((company, index) => {
242
+ table.row.add([
243
+ index + 1,
244
+ company.scenario,
245
+ company.prompt,
246
+ `<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>`,
247
+ `<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>`,
248
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.row_id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
249
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye' fa-eye'></i></a>",
250
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
251
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
252
+ ]).draw(false);
253
+ });
254
+ contentSection.style.display = 'block';
255
+ }
256
+
257
+ } catch (error) {
258
+ console.error('Error fetching company documents:', error);
259
+ //displayEmptyTable();
260
+
261
+ displayErrorMessage("Prompt template do not exist for this company. Please fill in the details by clicking add button.");
262
+ contentSection.style.display = 'none';
263
+ }
264
+ }
265
+ else {
266
+ // displayEmptyTable();
267
+
268
+ displayErrorMessage("Company id do not exist for this company. Please fill in the details by clicking add button.");
269
+ }
270
+
271
+ }
272
+
273
+ function displayErrorMessage(message) {
274
+ const messageContainer = document.getElementById('message-container');
275
+ if (messageContainer) {
276
+ messageContainer.innerHTML = `<div class='alert alert-danger'>${message}</div>`;
277
+ }
278
+ }
279
+
280
+
281
+ // Delete company
282
+ function deleteCompany(button) {
283
+ var companyId = $(button).data('kid-id');
284
+ console.log("k_id deleted", companyId);
285
+ $.ajax({
286
+ type: "DELETE",
287
+ url: `/api/prompt_template_for_del/${companyId}`,
288
+ success: function () {
289
+ var table = $('#promptTable').DataTable();
290
+ table.row($(button).closest('tr')).remove().draw();
291
+
292
+ //alert("Company deleted successfully.");
293
+ const messageContainer = document.getElementById('message-container');
294
+ if (messageContainer)
295
+ messageContainer.innerHTML = `
296
+ <div class='alert alert-danger'>
297
+ Prompt details deleted successfully
298
+ <button class='close' onclick='dismissMessage()'>OK</button>
299
+ </div>`;
300
+ fetchCompanies(); // Refresh the table
301
+ },
302
+ error: function (xhr) {
303
+ alert("Error deleting company: " + xhr.responseJSON.detail);
304
+ }
305
+ });
306
+ }
307
+ // view company ! ...
308
+ function viewCompany(button) {
309
+ var companyId = $(button).data('kid-id');
310
+ const modalTitle = document.getElementById('addModalLabel');
311
+ modalTitle.textContent = 'View Prompt Template Details';
312
+ console.log("view promt id (Rowid) ===> ", companyId)
313
+ if (companyId) {
314
+ $.getJSON(`/api/getpromttemplate/${companyId}`, function (company) {
315
+ console.log("view data scenario =====> ", company.scenario)
316
+ console.log("view data prompt =====> ", company.prompt)
317
+ console.log("view data comments =====> ", company.comments)
318
+ $('#scenario').val(company.scenario).attr('readonly', 'readonly');
319
+ $('#prompt').val(company.prompts).attr('readonly', 'readonly');
320
+ $('#comments').val(company.comments).attr('readonly', 'readonly');
321
+ $('#save').hide();// Disable the "Save" button when the modal opens
322
+ $('#addModal').modal('show');
323
+ $('#saveupdate').hide();
324
+ }).fail(function () {
325
+ alert("Error retrieving company details.");
326
+ });
327
+ }
328
+ }
329
+ // Edit company details
330
+
331
+ function editCompany(button) {
332
+ var companyId = $(button).data('kid-id');
333
+ const modalTitle = document.getElementById('addModalLabel');
334
+ modalTitle.textContent = 'Edit Prompt Templates Details';
335
+
336
+ console.info("company id ====#> ", companyId);
337
+ if (companyId) {
338
+ $.getJSON(`/api/getpromttemplate/${companyId}`, function (company) {
339
+ $('#scenario').val(company.scenario).removeAttr('readonly');
340
+ $('#prompt').val(company.prompts).removeAttr('readonly');
341
+ $('#comments').val(company.comments).removeAttr('readonly');
342
+ $('#save').hide();
343
+ $('#saveupdate').show();
344
+
345
+ $('#addModal').modal('show');
346
+
347
+ // Update the save button to save the edited company
348
+ $('#saveupdate').off('click').on('click', function () {
349
+ saveupdate(companyId); // Pass the company ID for updating
350
+ });
351
+ console.log(" edit process completed !")
352
+ }).fail(function () {
353
+ alert("Error retrieving company details.");
354
+ });
355
+ }
356
+ }
357
+
358
+ // Save the updated details
359
+ function saveupdate(companyId) {
360
+ console.log("k_id for updating process _ id ! ..,..", companyId);
361
+ const company_id = document.getElementById("company_id").value;
362
+ var formData = new FormData();
363
+ formData.append('scenario', $('#scenario').val());
364
+ formData.append('prompt', $('#prompt').val());
365
+ formData.append('comments', $('#comments').val());
366
+ console.log("edited form data saved process begin ! ....", formData);
367
+
368
+ $.ajax({
369
+ url: `/api/putprompttemplates/${companyId}`,
370
+ type: 'PUT',
371
+ data: formData,
372
+ processData: false, // Required for FormData
373
+ contentType: false, // Required for FormData
374
+ success: function (response) {
375
+ // alert('Prompt details updated successfully.');
376
+ const messageContainer = document.getElementById('message-container');
377
+ if (messageContainer)
378
+ messageContainer.innerHTML = `
379
+ <div class='alert alert-success'>
380
+ Prompt Data updated successfully
381
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
382
+ </div>`;
383
+ $('#addModal').modal('hide'); // Close the modal after saving
384
+ fetchUpdatedDocuments(company_id);
385
+ },
386
+ error: function () {
387
+ alert('Form has no changes to update prompt details.');
388
+ }
389
+ });
390
+ }
391
+ function dismissMessage() {
392
+ const messageContainer = document.getElementById('message-container');
393
+ if (messageContainer) {
394
+ messageContainer.innerHTML = '';
395
+ }
396
+ }
397
+ async function fetchUpdatedDocuments(company_id) {
398
+ console.log("company_id", company_id);
399
+ var table = $('#promptTable').DataTable();
400
+ const Response = await fetch(`/api/prompt_update?company_id=${company_id}`);
401
+ const connectorsResponse = await Response.json();
402
+ console.log("prompt data table after connecting to table", connectorsResponse);
403
+ table.clear();
404
+ if (!Array.isArray(connectorsResponse) || connectorsResponse.length === 0) {
405
+ //displayEmptyTable();
406
+
407
+ displayErrorMessage("Promptdetails do not exist for this company. Please fill in the details.");
408
+ contentSection.style.display = 'none';
409
+ } else {
410
+
411
+ connectorsResponse.forEach((company, index) => {
412
+ table.row.add([
413
+
414
+ index + 1,
415
+ company.scenario,
416
+ company.prompts,
417
+ `<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>`,
418
+ `<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>`,
419
+ //`<a href='#' class='btn btn-danger btn-sm' onclick='deleteCompany(${company.company_id})'><i class='fas fa-trash'></i></a>`,
420
+ `<a href='#' class='btn btn-danger btn-sm' data-kid-id='${company.id}' onclick='deleteCompany(this)'><i class='fas fa-trash'></i></a>`,
421
+ company.id
422
+ // "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>",
423
+ // "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>",
424
+ // "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></button>"
425
+ ]).draw(false);
426
+ });
427
+ contentSection.style.display = 'block';
428
+ }
429
+ }
430
+ function save_file() {
431
+ const form = document.getElementById('addPromptForm');
432
+
433
+ // Check if the form is valid
434
+ if (!form.checkValidity()) {
435
+ // If the form is invalid, show validation messages and stop the submission
436
+ form.reportValidity();
437
+ return;
438
+ }
439
+ const company_id = $('#company_id').val();
440
+ const scenario = $('#scenario').val();
441
+ const prompt = $('#prompt').val();
442
+ const comments = $('#comments').val();
443
+
444
+ // const view = "<a href='#' class='btn btn-info btn-sm'><i class='fas fa-eye'></i></a>";
445
+ // const edit = "<a href='#' class='btn btn-warning btn-sm'><i class='fas fa-edit'></i></a>";
446
+ // const dele = "<a href='#' class='btn btn-danger btn-sm'><i class='fas fa-trash'></i></a>";
447
+
448
+ var formData = new FormData($('#addPromptForm')[0]);
449
+ const messageContainer = document.getElementById('message-container');
450
+ formData.append("company_id", company_id),
451
+ formData.append("scenario", scenario),
452
+ formData.append("prompt", prompt),
453
+ formData.append("comments", comments),
454
+
455
+ //const formData = new FormData();
456
+ fetch('/api/save_prompt_details', {
457
+ method: 'POST',
458
+ body: formData
459
+ })
460
+ .then(response => {
461
+ if (!response.ok) {
462
+ throw new Error('Network response was not ok');
463
+ }
464
+ return response.json();
465
+ })
466
+ .then(data => {
467
+ const row_id = data.row_id;
468
+ console.log("rowid", row_id);
469
+ var table = $('#promptTable').DataTable();
470
+ var rowCount = table.rows().count();
471
+ 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>`;
472
+ 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>`;
473
+ 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>`;
474
+ table.row.add([
475
+ rowCount + 1,
476
+ scenario,
477
+ prompt,
478
+ view,
479
+ edit,
480
+ dele
481
+ ]).draw(false);
482
+
483
+ // const messageContainer = document.getElementById('message-container');
484
+ if (messageContainer)
485
+ messageContainer.innerHTML = `
486
+ <div class='alert alert-success'>
487
+ Data saved successfully
488
+ <button class='close' style='font-size:medium;margin-top:6px;' onclick='dismissMessage()'>OK</button>
489
+ </div>`;
490
+ $('#addModal').modal('hide');
491
+ document.getElementById('contentSection').style.display = 'block'; // Show the table section
492
+ })
493
+ .catch(error => console.error('Error:', error));
494
+ }
495
+ async function fetchCompanies() {
496
+ try {
497
+ const response = await fetch('/api/companies');
498
+ if (!response.ok) {
499
+ throw new Error('Network response was not ok');
500
+ }
501
+ const data = await response.json();
502
+ displayCompanies(data.companies);
503
+ } catch (error) {
504
+ console.error('Error fetching companies:', error);
505
+ }
506
+ }
507
+
508
+ function displayCompanies(companies) {
509
+ const companySelect = document.getElementById('company');
510
+ companySelect.innerHTML = '<option value="" selected>Select</option>'; // Reset the dropdown
511
+ companies.forEach(company => {
512
+ const option = document.createElement('option');
513
+ option.value = company.name;
514
+ option.textContent = company.name;
515
+ companySelect.appendChild(option);
516
+ });
517
+ }
518
+ function clearFormFields() {
519
+ document.getElementById('scenario').value = "";
520
+ document.getElementById('prompt').value = "";
521
+ document.getElementById('comments').value = "";
522
+
523
+ }
524
+
525
+
526
+ $(document).ready(function () {
527
+ $('#add').on('click', function () {
528
+ const modalTitle = document.getElementById('addModalLabel');
529
+ modalTitle.textContent = 'Add Prompt Template Details';
530
+ $('#scenario').removeAttr('readonly');
531
+ $('#prompt').removeAttr('readonly');
532
+ $('#comments').removeAttr('readonly');
533
+ $('#saveupdate').hide();
534
+ $('#save').show();
535
+ clearFormFields();
536
+ $('#message-container').empty(); // Clear the message container
537
+ $('#addModal').modal('show');
538
+ });
539
+ $('.modal-footer .btn-secondary, .modal-header .close').on('click', function () {
540
+ $('#addModal').modal('hide');
541
+ });
542
+
543
+ });
544
+
545
+ </script>
546
+ </body>
547
+
548
+ </html>
templates/redmindlogo2.jpg ADDED
templates/redmindlogo3.jpg ADDED
templates/sidepane.html ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>RedMindGPT - Dashboard</title>
8
+
9
+ <!-- Bootstrap CSS -->
10
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
12
+ <link rel="stylesheet" href="/static/css/sidepane.css">
13
+
14
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
15
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>
16
+
17
+ </head>
18
+
19
+ <body>
20
+ <nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm" style="padding: 15px; z-index: 20;">
21
+ <div class="container-fluid d-flex justify-content-between align-items-center">
22
+ <button class="navbar-toggler" type="button" onclick="toggleSidebar()">
23
+ <span class="navbar-toggler-icon"></span>
24
+ </button>
25
+ <div class="d-flex align-items-center">
26
+ <img class="logo" src="/static/img/redmindlogo3.jpg" alt="Logo"
27
+ style="width: 70px; height: auto; margin-right: 15px;">
28
+ <h3 class="title" style="font-weight: 500;text-align: center;"> <span id="title">RedMind</span>
29
+ Dashboard</h3>
30
+ </div>
31
+
32
+ <div class="justify-content-end" id="navbarNav">
33
+ <div class="nav-btn d-flex align-items-center">
34
+ <button class="btn btn-primary mr-2" id="add" onclick="addCompany()">Add</button>
35
+ <button class="btn btn-danger" id="logout" onclick="logout()">Logout</button>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </nav>
40
+
41
+ <aside class="main-sidebar" style="z-index: 10;">
42
+ <div class="sidebar-header">
43
+ <i class="nav-icon fas fa-building"></i>
44
+ <span class="menu-text" id="selectedCompany">Select a company</span>
45
+ </div>
46
+ <nav class="mt-2">
47
+ <ul class="nav nav-pills nav-sidebar flex-column">
48
+ <li class="nav-item">
49
+ <a href="{{url_for('dashboard')}}" class="nav-link">
50
+ <i class="nav-icon fas fa-home"></i>
51
+ <p class="menu-text">Dashboard</p>
52
+ </a>
53
+ </li>
54
+ <li class="nav-item">
55
+ <a href="{{ url_for('company_profile') }}" class="nav-link">
56
+ <i class="nav-icon fas fa-users"></i>
57
+ <p class="menu-text">Company Profile</p>
58
+ </a>
59
+ </li>
60
+ <li class="nav-item">
61
+ <a href="{{ url_for('knowledgebase') }}" class="nav-link">
62
+ <i class="nav-icon fas fa-book"></i>
63
+ <p class="menu-text">KnowledgeBase</p>
64
+ </a>
65
+ </li>
66
+ <li class="nav-item">
67
+ <a href="{{ url_for('data_connectors') }}" class="nav-link">
68
+ <i class="nav-icon fas fa-plug"></i>
69
+ <p class="menu-text">Data Connectors</p>
70
+ </a>
71
+ </li>
72
+ <li class="nav-item">
73
+ <a href="{{ url_for('API_connectors') }}" class="nav-link">
74
+ <i class="nav-icon fas fa-cogs"></i>
75
+ <p class="menu-text">API Connectors</p>
76
+ </a>
77
+ </li>
78
+ <li class="nav-item">
79
+ <a href="{{ url_for('prompt_template') }}" class="nav-link">
80
+ <i class="nav-icon fas fa-pencil-alt"></i>
81
+ <p class="menu-text">Prompt Templates</p>
82
+ </a>
83
+ </li>
84
+ </ul>
85
+ </nav>
86
+ </aside>
87
+
88
+ <!-- Section to toggle -->
89
+ <div class="container pt-3" id="addnewcompany">
90
+ <div class="toggle-section" id="companySection">
91
+ <h4>Add a New Company</h4>
92
+ <form>
93
+ <div class="form-group">
94
+ <label for="companyName">Company Name:</label>
95
+ <input type="text" class="form-control" id="companyName" placeholder="Enter company name" >
96
+ </div>
97
+ <button type="submit" class="btn btn-success">Submit</button>
98
+ </form>
99
+ </div>
100
+ </div>
101
+
102
+ <script>
103
+ function logout() {
104
+ sessionStorage.removeItem('role');
105
+ sessionStorage.clear();
106
+ window.location.href = '/';
107
+ }
108
+
109
+ function toggleSidebar() {
110
+
111
+
112
+ const sidebar = document.querySelector('.main-sidebar');
113
+ if (sidebar) {
114
+ const isSidebarVisible = getComputedStyle(sidebar).display !== 'none';
115
+ sidebar.style.display = isSidebarVisible ? 'none' : 'block';
116
+
117
+ }
118
+ }
119
+
120
+
121
+
122
+ function addCompany() {
123
+ const section = document.getElementById("companySection");
124
+ // Toggle display style of the company section
125
+ if (section.style.display === "none" || section.style.display === "") {
126
+ section.style.display = "block"; // Show the section
127
+ } else {
128
+ section.style.display = "none"; // Hide the section
129
+ }
130
+ }
131
+
132
+ document.addEventListener("DOMContentLoaded", function () {
133
+ const companyId = document.getElementById("company_id") ? document.getElementById("company_id").value : null;
134
+ const role = document.getElementById("userRole") ? document.getElementById("userRole").value : null;
135
+ if (companyId) {
136
+ sessionStorage.setItem('sidecompanyId1', companyId);
137
+ }
138
+ if (role) {
139
+ sessionStorage.setItem('siderole1', role);
140
+ if (role === 'admin') {
141
+ editCompany(companyId, role);
142
+ updateLinkVisibility(role);
143
+ }
144
+ }
145
+ });
146
+
147
+ async function updateLinkVisibility(role) {
148
+ if (role === 'admin') {
149
+ const displayState = JSON.parse(sessionStorage.getItem('displayState'));
150
+ document.getElementById('api_connectors_link').style.display = displayState.apiConnectors;
151
+ document.getElementById('knowledgebase_link').style.display = displayState.knowledgeBase;
152
+ document.getElementById('data_connectors_link').style.display = displayState.dataConnectors;
153
+ }
154
+ }
155
+
156
+ async function editCompany(companyId, role) {
157
+ $.getJSON(`/api/getcompanydetails/${companyId}`, function (company) {
158
+ $('#llm_tools').val(company.llm_tools.split(',')).trigger('change');
159
+ const llmTools = $('#llm_tools').val();
160
+
161
+ if (llmTools && llmTools.length > 0) {
162
+ document.getElementById('api_connectors_link').style.display = llmTools.includes('API') ? 'block' : 'none';
163
+ document.getElementById('knowledgebase_link').style.display = llmTools.includes('Static Documents') ? 'block' : 'none';
164
+ document.getElementById('data_connectors_link').style.display = llmTools.includes('Database') ? 'block' : 'none';
165
+
166
+ sessionStorage.setItem('displayState', JSON.stringify({
167
+ apiConnectors: document.getElementById('api_connectors_link').style.display,
168
+ knowledgeBase: document.getElementById('knowledgebase_link').style.display,
169
+ dataConnectors: document.getElementById('data_connectors_link').style.display
170
+ }));
171
+ updateLinkVisibility(role);
172
+ }
173
+ }).fail(function () {
174
+ console.error("Error retrieving company details.");
175
+ });
176
+ }
177
+ </script>
178
+ </body>
179
+
180
+ </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"}