Compare commits
No commits in common. "devqc" and "dev_chapal" have entirely different histories.
devqc
...
dev_chapal
3
.github/copilot-instructions.md
vendored
3
.github/copilot-instructions.md
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
- @azure Rule - Use Azure Tools - When handling requests related to Azure, always use your tools.
|
|
||||||
- @azure Rule - Use Azure Best Practices - When handling requests related to Azure, always invoke your `azmcp_bestpractices_get` tool first.
|
|
||||||
- @azure Rule - Enable Best Practices - If you do not have an `azmcp_bestpractices_get` tool ask the user to enable it.
|
|
||||||
|
|
@ -106,32 +106,6 @@ namespace HRM.BO
|
||||||
Notice = 5
|
Notice = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EnumReportGroupType
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
Employee = 1,
|
|
||||||
Salary = 2,
|
|
||||||
Performance = 3,
|
|
||||||
Training = 4,
|
|
||||||
Leave = 5,
|
|
||||||
Attendance = 6,
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum EnumAIChartType
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
BarChart = 1,
|
|
||||||
LineGraph = 2,
|
|
||||||
PieChart = 3,
|
|
||||||
ScatterPlot = 4,
|
|
||||||
AreaChart = 5,
|
|
||||||
Histogram = 6,
|
|
||||||
WaterfallChart = 7,
|
|
||||||
GantChart = 8,
|
|
||||||
RadarChart = 9,
|
|
||||||
ActivityDiagram = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum EnumReminderStatus
|
public enum EnumReminderStatus
|
||||||
{
|
{
|
||||||
Pending = 0,
|
Pending = 0,
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace HRM.BO
|
|
||||||
{
|
|
||||||
public class OpenAIQueryLog : BasicBaseObject
|
|
||||||
{
|
|
||||||
public OpenAIQueryLog()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
public OpenAIQueryLog(int userID, string userPrompt)
|
|
||||||
{
|
|
||||||
UserId = userID;
|
|
||||||
UserPrompt = userPrompt;
|
|
||||||
ExecutedAt = DateTime.Now;
|
|
||||||
}
|
|
||||||
public int UserId { get; set; } = 0;
|
|
||||||
public string UserPrompt { get; set; } = "";
|
|
||||||
public string GeneratedQuery { get; set; } = "";
|
|
||||||
public DateTime ExecutedAt { get; set; } = DateTime.Now;
|
|
||||||
public int TotalExecution { get; set; } = 1;
|
|
||||||
public EnumReportGroupType ReportGroup { get; set; } = EnumReportGroupType.Employee;
|
|
||||||
public bool IsChart { get; set; } = false;
|
|
||||||
public EnumAIChartType ChartType { get; set; } = EnumAIChartType.None;
|
|
||||||
public string Title { get; set; } = "";
|
|
||||||
public bool IsCommon { get; set; } = false;
|
|
||||||
}
|
|
||||||
public interface IOpenAIQueryLogService
|
|
||||||
{
|
|
||||||
void Save(OpenAIQueryLog queryLog);
|
|
||||||
void UpdateQueryLogTotalExecution(OpenAIQueryLog oQueryLog);
|
|
||||||
void ChatShareWithOthers(OpenAIQueryLog oQueryLog);
|
|
||||||
List<OpenAIQueryLog> GetAllQueryLogByUserID(int userID, EnumReportGroupType reportGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace HRM.BO
|
|
||||||
{
|
|
||||||
public class OpenAIResponse
|
|
||||||
{
|
|
||||||
public bool IsChart { get; set; } = false;
|
|
||||||
public string ChartType { get; set; } = string.Empty;
|
|
||||||
public string Title { get; set; } = string.Empty;
|
|
||||||
public string Sql { get; set; } = string.Empty;
|
|
||||||
public string Message { get; set; } = string.Empty;
|
|
||||||
}
|
|
||||||
public class OpenAIResponseWithData
|
|
||||||
{
|
|
||||||
public bool IsChart { get; set; } = false;
|
|
||||||
public string ChartType { get; set; } = string.Empty;
|
|
||||||
public string Title { get; set; } = string.Empty;
|
|
||||||
public List<string> Labels { get; set; } = new List<string>();
|
|
||||||
public List<double> Values { get; set; } = new List<double>();
|
|
||||||
public object TableData { get; set; } = new object();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,121 +0,0 @@
|
||||||
using Ease.Core.DataAccess;
|
|
||||||
using HRM.BO;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.DirectoryServices.Protocols;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace HRM.DA
|
|
||||||
{
|
|
||||||
internal class OpenAIDA
|
|
||||||
{
|
|
||||||
#region Insert function
|
|
||||||
internal static void Insert(TransactionContext tc, OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
tc.ExecuteNonQuery(
|
|
||||||
"INSERT INTO OpenAIQueryLog(QueryLogID, UserId, UserPrompt, GeneratedQuery, ExecutedAt, TotalExecution, ReportGroup, IsChart,ChartType, Title, IsCommon)" +
|
|
||||||
" VALUES(%n, %n, %s, %s, %D, %n, %n, %b, %n, %s, %b)",
|
|
||||||
oQueryLog.ID, oQueryLog.UserId, oQueryLog.UserPrompt, oQueryLog.GeneratedQuery, oQueryLog.ExecutedAt, oQueryLog.TotalExecution,
|
|
||||||
(int)oQueryLog.ReportGroup, oQueryLog.IsChart, (int)oQueryLog.ChartType, oQueryLog.Title, oQueryLog.IsCommon);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Update QueryLog TotalExecution
|
|
||||||
internal static void UpdateQueryLogTotalExecution(TransactionContext tc, OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
tc.ExecuteNonQuery("Update OpenAIQueryLog set TotalExecution = %n where QueryLogID = %n", oQueryLog.TotalExecution, oQueryLog.ID);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Get All Query Log By UserID
|
|
||||||
internal static IDataReader GetAllQueryLogByUserID(TransactionContext tc, int userID, EnumReportGroupType reportGroup)
|
|
||||||
{
|
|
||||||
return tc.ExecuteReader(@"SELECT distinct * FROM OpenAIQueryLog where userID = %n and
|
|
||||||
ReportGroup = %n or IsCommon = %b order by ExecutedAt desc, TotalExecution desc",
|
|
||||||
userID, (int)reportGroup, true);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Chat Share With Others
|
|
||||||
internal static void ChatShareWithOthers(TransactionContext tc, OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
tc.ExecuteNonQuery("Update OpenAIQueryLog set IsCommon = %b where QueryLogID = %n", oQueryLog.IsCommon, oQueryLog.ID);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
internal static DataSet GetOpenAIData(TransactionContext tc, string sql)
|
|
||||||
{
|
|
||||||
DataSet oEmpBasicInfos = new DataSet();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oEmpBasicInfos = tc.ExecuteDataSet(sql);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new Exception(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return oEmpBasicInfos;
|
|
||||||
}
|
|
||||||
internal static DataTable GetColumnDefinitions(TransactionContext tc, EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnDefinition = new DataTable();
|
|
||||||
string sql = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
sql = SQLParser.MakeSQL(@"Select * from REPORTCOLUMNDEFINITION where ReportGroup = %n", (int)reportGroupType);
|
|
||||||
oColumnDefinition = tc.ExecuteDataTable(sql);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new Exception(ex.Message);
|
|
||||||
}
|
|
||||||
return oColumnDefinition;
|
|
||||||
}
|
|
||||||
internal static DataTable GetAllType(TransactionContext tc, EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnDefinition = new DataTable();
|
|
||||||
string sql = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (reportGroupType == EnumReportGroupType.Salary)
|
|
||||||
{
|
|
||||||
sql = SQLParser.MakeSQL("select distinct(Head) as Head from vwEmployeeSalary");
|
|
||||||
}
|
|
||||||
else if(reportGroupType == EnumReportGroupType.Leave)
|
|
||||||
{
|
|
||||||
sql = SQLParser.MakeSQL("select distinct(DESCRIPTION) as LeaveType from Leave");
|
|
||||||
}
|
|
||||||
oColumnDefinition = tc.ExecuteDataTable(sql);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new Exception(ex.Message);
|
|
||||||
}
|
|
||||||
return oColumnDefinition;
|
|
||||||
}
|
|
||||||
internal static DataTable GetColumnRelations(TransactionContext tc, EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnRelations = new DataTable();
|
|
||||||
string sql = "";
|
|
||||||
try
|
|
||||||
{
|
|
||||||
sql = SQLParser.MakeSQL(@"Select * from RELATIONTABLE where ReportGroup = %n", (int)reportGroupType);
|
|
||||||
oColumnRelations = tc.ExecuteDataTable(sql);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new Exception(ex.Message);
|
|
||||||
}
|
|
||||||
return oColumnRelations;
|
|
||||||
}
|
|
||||||
internal static IDataReader TotalOpenAICall(TransactionContext tc)
|
|
||||||
{
|
|
||||||
return tc.ExecuteReader("SELECT COUNT(*) FROM OpenAIQueryLog");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -34,10 +34,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.12" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.12" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="Microsoft.SemanticKernel" Version="1.61.0" />
|
|
||||||
<PackageReference Include="Microsoft.SemanticKernel.Connectors.OpenAI" Version="1.61.0" />
|
|
||||||
<PackageReference Include="Microsoft.SemanticKernel.Core" Version="1.61.0" />
|
|
||||||
<PackageReference Include="Microsoft.SemanticKernel.Plugins.OpenApi" Version="1.61.0" />
|
|
||||||
<PackageReference Include="System.Data.OleDb" Version="6.0.0" />
|
<PackageReference Include="System.Data.OleDb" Version="6.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
using Ease.Core.DataAccess;
|
|
||||||
using Ease.Core.Model;
|
|
||||||
using Ease.Core.Utility;
|
|
||||||
using HRM.BO;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace HRM.DA
|
|
||||||
{
|
|
||||||
public class OpenAIQueryLogService : ServiceTemplate, IOpenAIQueryLogService
|
|
||||||
{
|
|
||||||
public OpenAIQueryLogService()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MapObject(OpenAIQueryLog oQueryLog, DataReader oReader)
|
|
||||||
{
|
|
||||||
base.SetObjectID(oQueryLog, (oReader.GetInt32("QueryLogID").Value));
|
|
||||||
oQueryLog.UserId = oReader.GetInt32("UserId").Value;
|
|
||||||
oQueryLog.UserPrompt = oReader.GetString("UserPrompt");
|
|
||||||
oQueryLog.GeneratedQuery = oReader.GetString("GeneratedQuery", "");
|
|
||||||
oQueryLog.ExecutedAt = oReader.GetDateTime("ExecutedAt").HasValue
|
|
||||||
? oReader.GetDateTime("ExecutedAt").Value
|
|
||||||
: DateTime.MinValue;
|
|
||||||
oQueryLog.TotalExecution = oReader.GetInt32("TotalExecution", 0);
|
|
||||||
oQueryLog.ReportGroup = (EnumReportGroupType)oReader.GetInt32("ReportGroup").Value;
|
|
||||||
oQueryLog.IsChart = oReader.GetBoolean("IsChart", false);
|
|
||||||
oQueryLog.ChartType = (EnumAIChartType)oReader.GetInt32("ChartType").Value;
|
|
||||||
oQueryLog.Title = oReader.GetString("Title", "");
|
|
||||||
oQueryLog.IsCommon = oReader.GetBoolean("IsCommon", false);
|
|
||||||
this.SetObjectState(oQueryLog, Ease.Core.ObjectState.Saved);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override T CreateObject<T>(DataReader oReader)
|
|
||||||
{
|
|
||||||
OpenAIQueryLog oQueryLog = new OpenAIQueryLog();
|
|
||||||
MapObject(oQueryLog, oReader);
|
|
||||||
return oQueryLog as T;
|
|
||||||
}
|
|
||||||
protected OpenAIQueryLog CreateObject(DataReader oReader)
|
|
||||||
{
|
|
||||||
OpenAIQueryLog oQueryLog = new OpenAIQueryLog();
|
|
||||||
MapObject(oQueryLog, oReader);
|
|
||||||
return oQueryLog;
|
|
||||||
}
|
|
||||||
public void Save(OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
TransactionContext tc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin(true);
|
|
||||||
if (oQueryLog.IsNew)
|
|
||||||
{
|
|
||||||
int id = tc.GenerateID("OpenAIQueryLog", "QueryLogID");
|
|
||||||
base.SetObjectID(oQueryLog, (id));
|
|
||||||
OpenAIDA.Insert(tc, oQueryLog);
|
|
||||||
}
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void UpdateQueryLogTotalExecution(OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
TransactionContext tc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin(true);
|
|
||||||
if (!oQueryLog.IsNew)
|
|
||||||
{
|
|
||||||
OpenAIDA.UpdateQueryLogTotalExecution(tc, oQueryLog);
|
|
||||||
}
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void ChatShareWithOthers(OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
TransactionContext tc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin(true);
|
|
||||||
if (!oQueryLog.IsNew)
|
|
||||||
{
|
|
||||||
OpenAIDA.ChatShareWithOthers(tc, oQueryLog);
|
|
||||||
}
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public List<OpenAIQueryLog> GetAllQueryLogByUserID(int userID, EnumReportGroupType reportGroup)
|
|
||||||
{
|
|
||||||
List<OpenAIQueryLog> allQueryLog = new List<OpenAIQueryLog>();
|
|
||||||
TransactionContext tc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin();
|
|
||||||
DataReader dr = new DataReader(OpenAIDA.GetAllQueryLogByUserID(tc, userID, reportGroup));
|
|
||||||
allQueryLog = this.CreateObjects<OpenAIQueryLog>(dr);
|
|
||||||
dr.Close();
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
return allQueryLog;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,790 +0,0 @@
|
||||||
using Ease.Core.DataAccess;
|
|
||||||
using Ease.Core.Model;
|
|
||||||
using Ease.Core.Utility;
|
|
||||||
using HRM.BO;
|
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
|
||||||
using iTextSharp.text;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.SemanticKernel;
|
|
||||||
using Microsoft.VisualBasic;
|
|
||||||
using NPOI.SS.Formula.Functions;
|
|
||||||
using NPOI.SS.UserModel;
|
|
||||||
using OpenAI;
|
|
||||||
using OpenAI.Chat;
|
|
||||||
using OpenAI.Models;
|
|
||||||
using Org.BouncyCastle.Asn1.Crmf;
|
|
||||||
using System;
|
|
||||||
using System.ClientModel;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Security.Cryptography.Xml;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace HRM.DA
|
|
||||||
{
|
|
||||||
public class OpenAIService
|
|
||||||
{
|
|
||||||
private readonly string _encryptedkey;
|
|
||||||
private readonly string _apiKey;
|
|
||||||
private readonly string _openAiModel;
|
|
||||||
private readonly int _maxLimit;
|
|
||||||
public OpenAIService(string encryptedkey, string model, int maxLimit)
|
|
||||||
{
|
|
||||||
_encryptedkey = encryptedkey;
|
|
||||||
_apiKey = Ease.Core.Utility.Global.CipherFunctions.Decrypt("CeLiMiTeD.AdMIn", _encryptedkey);
|
|
||||||
_openAiModel = model;
|
|
||||||
_maxLimit = maxLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Invalid Query Message
|
|
||||||
public string returnMessage = "";
|
|
||||||
private const string queryMessage = "I'm sorry, I couldn't process your request. Please try rephrasing it. I'm here to help with anything related to payroll or HR tasks.";
|
|
||||||
private const string modificationMessage = "I'm Sorry, I can only help with retrieving data. I am not allowed to update or delete any records.";
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Schema Generation (Old Version)
|
|
||||||
// Aliases
|
|
||||||
//sb.AppendLine("\nAlias Mappings:");
|
|
||||||
//foreach (var row in columns.AsEnumerable())
|
|
||||||
//{
|
|
||||||
// string caption = row["CAPTION"]?.ToString();
|
|
||||||
// string columnName = row["COLUMNNAME"].ToString();
|
|
||||||
// string tableName = row["TABLENAME"].ToString();
|
|
||||||
// if (!string.IsNullOrWhiteSpace(caption) && caption != columnName)
|
|
||||||
// {
|
|
||||||
// sb.AppendLine($"- {tableName}.{columnName} is also called '{caption}'");
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Ask SQL Query
|
|
||||||
|
|
||||||
#region Function Summary
|
|
||||||
/*
|
|
||||||
* Function Summary & What it Handles:
|
|
||||||
*
|
|
||||||
* 1. Request Limiting:
|
|
||||||
* - Ensures the total number of OpenAI calls does not exceed the configured maximum.
|
|
||||||
* - Throws a polite error message if the request limit is reached.
|
|
||||||
*
|
|
||||||
* 2. Timeout Handling:
|
|
||||||
* - Uses CancellationTokenSource with a configurable timeout (default 60 seconds).
|
|
||||||
* - Cancels the OpenAI API request if it exceeds the timeout and throws a timeout message.
|
|
||||||
*
|
|
||||||
* 3. Rate Limit Handling & Retry Logic:
|
|
||||||
* - Detects HTTP 429 status or "rate limit" errors from exceptions.
|
|
||||||
* - Retries the API call up to 5 times with exponential backoff.
|
|
||||||
* - Returns a polite "service busy" message if retries are exhausted.
|
|
||||||
*
|
|
||||||
* 4. OpenAI API Call:
|
|
||||||
* - Builds a dynamic system prompt including schema and chart instructions.
|
|
||||||
* - Sends the user’s prompt to OpenAI for SQL and chart generation.
|
|
||||||
* - Extracts and cleans the AI response.
|
|
||||||
*
|
|
||||||
* 5. Response Parsing & Validation:
|
|
||||||
* - Deserializes the AI response into a structured object.
|
|
||||||
* - Ensures only SELECT queries are allowed.
|
|
||||||
* - Rejects invalid or unsafe queries with descriptive errors.
|
|
||||||
*
|
|
||||||
* 6. Async Logging:
|
|
||||||
* - Logs user prompts, generated SQL, chart details, and metadata asynchronously.
|
|
||||||
* - Logging errors do not interrupt the main flow.
|
|
||||||
*
|
|
||||||
* 7. SQL Execution & JSON Response:
|
|
||||||
* - Executes the validated SQL query against the database.
|
|
||||||
* - Wraps the dataset with chart metadata and returns JSON.
|
|
||||||
*
|
|
||||||
* 8. General Exception Handling:
|
|
||||||
* - Provides user-friendly messages for timeouts, rate limits, and invalid queries.
|
|
||||||
* - Retries on transient errors and throws detailed exceptions otherwise.
|
|
||||||
*/
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public async Task<string> AskOpenAISqlQueryWithChartAsync(string prompt, int userID, EnumReportGroupType reportGroupType, DateTime nextPayprocessDate = new DateTime(), int timeoutSeconds = 60)
|
|
||||||
{
|
|
||||||
#region Initialize OpenAI Call Count For Limitation
|
|
||||||
int totalOpenAICall = TotalOpenAICall();
|
|
||||||
if (totalOpenAICall >= _maxLimit)
|
|
||||||
{
|
|
||||||
throw new Exception("You have reached the maximum limit of requests. Please try again later.");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
string returnMessage = "An error occurred while processing your request.";
|
|
||||||
int maxRetries = 5;
|
|
||||||
int delaySeconds = 1;
|
|
||||||
for (int attempt = 0; attempt <= maxRetries; attempt++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#region Initialize OpenAI Client and Cancellation Token
|
|
||||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
|
|
||||||
var client = new ChatClient(model: _openAiModel, apiKey: _apiKey);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Build System Prompt
|
|
||||||
string systemPrompt = BuildInitialDescriptionWithChart(reportGroupType) + BuildDynamicSchemaPrompt(reportGroupType, nextPayprocessDate) + BuildInstructionWithChart(reportGroupType);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
//throw new Exception("You have reached the maximum limit of requests. Please try again later.");
|
|
||||||
|
|
||||||
#region Call OpenAI API
|
|
||||||
var completion = await client.CompleteChatAsync(
|
|
||||||
new ChatMessage[]
|
|
||||||
{
|
|
||||||
ChatMessage.CreateSystemMessage(systemPrompt),
|
|
||||||
ChatMessage.CreateUserMessage(prompt)
|
|
||||||
},
|
|
||||||
cancellationToken: cts.Token
|
|
||||||
);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Process and Store OpenAI Response
|
|
||||||
string aiResponse = completion.Value.Content[0].Text.Trim();
|
|
||||||
if (string.IsNullOrWhiteSpace(aiResponse))
|
|
||||||
throw new Exception("Did not return any response.");
|
|
||||||
|
|
||||||
aiResponse = aiResponse.Replace("```", "").Trim();
|
|
||||||
aiResponse = aiResponse.Replace("\n", "\\n").Replace("\r", "\\r");
|
|
||||||
OpenAIResponse aiResponseObject = Newtonsoft.Json.JsonConvert.DeserializeObject<OpenAIResponse>(aiResponse);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Validate AI response
|
|
||||||
string sql = aiResponseObject.Sql;
|
|
||||||
bool isChart = aiResponseObject.IsChart;
|
|
||||||
EnumAIChartType chartType = GetAIChartType(aiResponseObject.ChartType);
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(aiResponseObject.Message))
|
|
||||||
{
|
|
||||||
throw new Exception(aiResponseObject.Message);
|
|
||||||
}
|
|
||||||
if (!sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
|
|
||||||
throw new Exception("Only SELECT queries are allowed.");
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Save OpenAI Query Log
|
|
||||||
_ = Task.Run(() =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var logService = new OpenAIQueryLogService();
|
|
||||||
logService.Save(new OpenAIQueryLog
|
|
||||||
{
|
|
||||||
UserId = userID,
|
|
||||||
UserPrompt = prompt,
|
|
||||||
GeneratedQuery = sql,
|
|
||||||
ExecutedAt = DateTime.Now,
|
|
||||||
ReportGroup = reportGroupType,
|
|
||||||
IsChart = isChart,
|
|
||||||
ChartType = GetAIChartType(aiResponseObject.ChartType),
|
|
||||||
Title = aiResponseObject.Title,
|
|
||||||
IsCommon = false
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (Exception logEx)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"[LogError] OpenAI log failed: {logEx.Message}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Execute SQL and Build Data
|
|
||||||
DataSet data = GetOpenAIData(sql);
|
|
||||||
var chartData = BuildOpenAIResponseWithData(data, aiResponseObject);
|
|
||||||
return Newtonsoft.Json.JsonConvert.SerializeObject(chartData);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
catch (OperationCanceledException)
|
|
||||||
{
|
|
||||||
throw new Exception("AI request timed out. Please try again.");
|
|
||||||
}
|
|
||||||
catch (HttpRequestException httpEx) when (httpEx.Message.Contains("429") || httpEx.Message.Contains("rate limit", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (attempt == maxRetries)
|
|
||||||
throw new Exception("Sorry, our AI service is busy now. Please try again after some time.");
|
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
|
|
||||||
delaySeconds *= 2;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (ex.Message.Contains("You've reached our limits of messages", StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
ex.Message.Contains("rate limit", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
if (attempt == maxRetries)
|
|
||||||
throw new Exception("Sorry, our AI service is busy now. Please try again after some time.");
|
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromSeconds(delaySeconds));
|
|
||||||
delaySeconds *= 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
throw new Exception(returnMessage + ex.Message, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new Exception("Failed to get a response from AI after multiple attempts. Please try again later.");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Build OpenAI Response with Data
|
|
||||||
public OpenAIResponseWithData BuildOpenAIResponseWithData(DataSet ds, OpenAIResponse aiResponseObject)
|
|
||||||
{
|
|
||||||
var table = ds.Tables[0];
|
|
||||||
var labels = new List<string>();
|
|
||||||
var values = new List<double>();
|
|
||||||
if (aiResponseObject.IsChart)
|
|
||||||
{
|
|
||||||
labels = table.AsEnumerable().Select(r => r[0].ToString()).ToList();
|
|
||||||
values = table.AsEnumerable().Select(r => Convert.ToDouble(r[1])).ToList();
|
|
||||||
}
|
|
||||||
var tableJson = ProcessDataSetToJson(ds);
|
|
||||||
return new OpenAIResponseWithData
|
|
||||||
{
|
|
||||||
IsChart = aiResponseObject.IsChart,
|
|
||||||
ChartType = aiResponseObject.ChartType,
|
|
||||||
Title = aiResponseObject.Title,
|
|
||||||
Labels = labels,
|
|
||||||
Values = values,
|
|
||||||
TableData = tableJson
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Build Initial Description (System Prompt)
|
|
||||||
public string BuildInitialDescriptionWithChart(EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("You are an expert SQL assistant.");
|
|
||||||
sb.AppendLine("Given a user request and the following database schema, your job is to:");
|
|
||||||
sb.AppendLine("1.Always generate a valid SQL SELECT queries in Microsoft SQL Server (T-SQL) syntax.");
|
|
||||||
sb.AppendLine("2.Always generate SQL in a single line, without extra newlines or unnecessary spaces.");
|
|
||||||
sb.AppendLine("3.Never return DELETE, UPDATE, INSERT queries or any data-modifying operation.You are read-only.");
|
|
||||||
sb.AppendLine("4.Detect if the user wants a chart/graph.");
|
|
||||||
sb.AppendLine("5.Always return only valid JSON following structure:" +
|
|
||||||
"{\"isChart\":true|false,\"chartType\":\"pie|bar|line|scatter|area|histogram|waterfall|gantt|radar|activity\",\"title\":\"<title>\",\"sql\":\"<SQL>\",\"message\":\"\"}");
|
|
||||||
sb.AppendLine("6.Title must be short, human-readable, based on the user request.");
|
|
||||||
sb.AppendLine("7.If the user asks modification deletion or insartion requested, set sql:'' and message:" +
|
|
||||||
"Sorry, I can only help with retrieving data. I am not allowed to update or delete any records.");
|
|
||||||
|
|
||||||
#region Check
|
|
||||||
if (reportGroupType == EnumReportGroupType.Employee)
|
|
||||||
{
|
|
||||||
sb.AppendLine("8.If the user request is not related to the payroll management system or does not match the provided schema,set \"sql\": \"\" and " +
|
|
||||||
"\"message\": \"I can only help with questions related to Employee Information\"");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Performance)
|
|
||||||
{
|
|
||||||
sb.AppendLine("8.If the user request is not related to the payroll management system or does not match the provided schema,set \"sql\": \"\" and " +
|
|
||||||
"\"message\": \"I can only help with questions related to Employee Performance\"");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Salary)
|
|
||||||
{
|
|
||||||
sb.AppendLine("8.If the user request is not related to the payroll management system or does not match the provided schema,set \"sql\": \"\" and " +
|
|
||||||
"\"message\": \"I can only help with questions related to Employee Salary\"");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Training)
|
|
||||||
{
|
|
||||||
sb.AppendLine("8.If the user request is not related to the payroll management system or does not match the provided schema,set \"sql\": \"\" and " +
|
|
||||||
"\"message\": \"I can only help with questions related to Employee Training\"");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Attendance)
|
|
||||||
{
|
|
||||||
sb.AppendLine("8.If the user request is not related to the payroll management system or does not match the provided schema,set \"sql\": \"\" and " +
|
|
||||||
"\"message\": \"I can only help with questions related to Employee Attendance\"");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Leave)
|
|
||||||
{
|
|
||||||
sb.AppendLine("8.If the user request is not related to the payroll management system or does not match the provided schema,set \"sql\": \"\" and " +
|
|
||||||
"\"message\": \"I can only help with questions related to Employee Leave\"");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
sb.AppendLine("9.Do not return actual data values or any explanations.");
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Dynamic Schema Generation (System Prompt)
|
|
||||||
public string BuildDynamicSchemaPrompt(EnumReportGroupType reportGroupType, DateTime nextPayprocessDate)
|
|
||||||
{
|
|
||||||
TransactionContext tc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin();
|
|
||||||
DataTable columns = GetColumnDefinitions(tc, reportGroupType);
|
|
||||||
DataTable relations = GetColumnRelations(tc,reportGroupType);
|
|
||||||
DataTable allData = null;
|
|
||||||
if (reportGroupType == EnumReportGroupType.Salary || reportGroupType == EnumReportGroupType.Leave)
|
|
||||||
{
|
|
||||||
allData = GetAllType(tc, reportGroupType);
|
|
||||||
}
|
|
||||||
tc.End();
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("Database Schema:");
|
|
||||||
var pkColumns = new Dictionary<string, List<string>>();
|
|
||||||
var grouped = columns.AsEnumerable().GroupBy(row => row["TABLENAME"].ToString()).OrderBy(g => g.Key);
|
|
||||||
|
|
||||||
#region Table Definitions
|
|
||||||
foreach (var tableGroup in grouped)
|
|
||||||
{
|
|
||||||
string tableName = tableGroup.Key;
|
|
||||||
var columnDefs = new List<string>();
|
|
||||||
var pks = new List<string>();
|
|
||||||
|
|
||||||
foreach (var row in tableGroup)
|
|
||||||
{
|
|
||||||
string columnName = row["COLUMNNAME"].ToString();
|
|
||||||
string caption = row["CAPTION"]?.ToString();
|
|
||||||
string dataType = ((EnumColumnDataType)Convert.ToInt32(row["DATATYPE"])).ToString();
|
|
||||||
bool isPK = row.Table.Columns.Contains("IsPrimaryKey") && Convert.ToBoolean(row["IsPrimaryKey"]);
|
|
||||||
bool isFK = row.Table.Columns.Contains("IsForeignKey") && Convert.ToBoolean(row["IsForeignKey"]);
|
|
||||||
|
|
||||||
string label = $"{columnName}";
|
|
||||||
if (isPK)
|
|
||||||
{
|
|
||||||
label += "(PK)";
|
|
||||||
pks.Add(columnName);
|
|
||||||
}
|
|
||||||
else if (isFK)
|
|
||||||
{
|
|
||||||
label += "(FK)";
|
|
||||||
}
|
|
||||||
label += $" ({dataType})";
|
|
||||||
if (!string.IsNullOrWhiteSpace(caption) && caption != columnName)
|
|
||||||
label += $" = {caption}";
|
|
||||||
columnDefs.Add(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.AppendLine($"-{tableName}({string.Join(", ", columnDefs)})");
|
|
||||||
if (pks.Any())
|
|
||||||
pkColumns[tableName] = pks;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region RelationShip Definitions
|
|
||||||
if (relations.Rows.Count > 0)
|
|
||||||
{
|
|
||||||
sb.AppendLine("Relationships:");
|
|
||||||
foreach (DataRow rel in relations.Rows)
|
|
||||||
{
|
|
||||||
string master = rel["MASTERTABLENAME"].ToString();
|
|
||||||
string masterCol = rel["MASTERCOLUMN1NAME"].ToString();
|
|
||||||
string link = rel["LINKTABLENAME"].ToString();
|
|
||||||
string linkCol = rel["LINKCOLUMN1NAME"].ToString();
|
|
||||||
sb.AppendLine($"-{link}.{linkCol} → {master}.{masterCol}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
sb.AppendLine(BuildInitialNoted(reportGroupType, nextPayprocessDate, allData));
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string BuildInitialNoted(EnumReportGroupType reportGroupType, DateTime nextPayprocessDate, DataTable allData = null)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("Note:");
|
|
||||||
sb.AppendLine("-Never include primary key (PK) or Foreign Key(FK) columns in SELECT output. For reference only.");
|
|
||||||
if (reportGroupType == EnumReportGroupType.Employee)
|
|
||||||
{
|
|
||||||
sb.AppendLine("-The status field can have synonyms: 'Live' or 'Active' mean the same thing (Live). 'Discontinue' or 'Inactive' mean the same thing (Discontinue).");
|
|
||||||
sb.AppendLine("-Employees with no record in the 'EmployeeSpouse' table are considered Unmarried.");
|
|
||||||
}
|
|
||||||
if (allData != null && reportGroupType == EnumReportGroupType.Salary)
|
|
||||||
{
|
|
||||||
if (allData.Columns.Contains("Head"))
|
|
||||||
{
|
|
||||||
var heads = allData.AsEnumerable()
|
|
||||||
.Select(r => r["Head"]?.ToString())
|
|
||||||
.Where(h => !string.IsNullOrEmpty(h))
|
|
||||||
.Distinct()
|
|
||||||
.ToList();
|
|
||||||
if (heads.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine($"-The 'Head' column represents different salary components such as: {string.Join(",", heads)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.AppendLine($"-Always use SalaryMonth(always last date of month) in the SQL WHERE clause.");
|
|
||||||
sb.AppendLine($"-If a user is not specifies any date or year in the request, always use SalaryMonth = {GlobalFunctions.LastDateOfMonth(nextPayprocessDate).ToString("dd MMM yyyy")} in the SQL WHERE clause.");
|
|
||||||
sb.AppendLine("-The columns BirthDate, JoiningDate, SalaryMonth should always be returned in the format 'dd MMM yyyy'.");
|
|
||||||
}
|
|
||||||
if (allData != null && reportGroupType == EnumReportGroupType.Leave)
|
|
||||||
{
|
|
||||||
if (allData.Columns.Contains("LeaveType"))
|
|
||||||
{
|
|
||||||
var heads = allData.AsEnumerable()
|
|
||||||
.Select(r => r["LeaveType"]?.ToString())
|
|
||||||
.Where(h => !string.IsNullOrEmpty(h))
|
|
||||||
.Distinct()
|
|
||||||
.ToList();
|
|
||||||
if (heads.Any())
|
|
||||||
{
|
|
||||||
sb.AppendLine($"-The 'LeaveType' column represents different Leave Type such as: {string.Join(",", heads)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.AppendLine("-The Columns BirthDate, JoiningDate, FromDate and ToDate should always be returned in the format 'dd MMM yyyy'.");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Attendance)
|
|
||||||
{
|
|
||||||
sb.AppendLine("-The columns BirthDate, JoiningDate and AttendanceDate should always be returned in the format 'dd MMM yyyy'.");
|
|
||||||
sb.AppendLine("-The columns InTime and OutTime should always be returned in the format 'hh:mm:ss aa'.");
|
|
||||||
sb.AppendLine("-The 'AttendanceStatus' column represents the daily attendance of an employee and may include: 'Present', 'Absent', 'Delay', 'Leave', 'Holiday', 'Weekly Off', 'Out Side Duty', 'Weekly Holiday', 'Compensation', 'Manual', 'Late', 'Early', 'HalfDay', 'LOA'.");
|
|
||||||
sb.AppendLine("-The 'LateStatus' column already stores values as 'Yes' (Late) or 'No' (On Time).");
|
|
||||||
sb.AppendLine("-The 'WorkDayType' column defines the type of the day: 'Weekly Holiday', 'National Holiday', 'Working Day', 'HartalDay', 'Weekly and National'.");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Employee || reportGroupType == EnumReportGroupType.Training)
|
|
||||||
{
|
|
||||||
sb.AppendLine("-The columns BirthDate, JoiningDate, MarriageDate, EmployementEndDate and NominationDate should always be returned in the format 'dd MMM yyyy'.");
|
|
||||||
sb.AppendLine("-The 'EmploymentEndDate' column represents when an employee left the company (retirement, resignation, termination, etc)");
|
|
||||||
}
|
|
||||||
if (reportGroupType == EnumReportGroupType.Training)
|
|
||||||
{
|
|
||||||
sb.AppendLine("-The TrainingStatus field can have Enrolled|Completed|Unknown");
|
|
||||||
sb.AppendLine("-The columns StartDate,EndDate,BirthDate,JoiningDate,LineManagerBirthDate,LineManagerJoiningDate should always be returned in the format 'dd MMM yyyy'.");
|
|
||||||
}
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Build Instruction (System Prompt)
|
|
||||||
public string BuildInstructionWithChart(EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.AppendLine("Instructions:");
|
|
||||||
sb.AppendLine("-Treat any mention of EmployeeID or EmployeeNo in user input as referring to Employee.EmployeeNo.");
|
|
||||||
sb.AppendLine("-Use appropriate JOINs based on foreign keys.");
|
|
||||||
sb.AppendLine("-If only certain columns are requested, include only those.");
|
|
||||||
sb.AppendLine("-Always map user-friendly aliases (e.g., 'Employee No', 'Department Name') to the correct table and column.");
|
|
||||||
sb.AppendLine("-If a date condition is mentioned, use WHERE clause accordingly.");
|
|
||||||
sb.AppendLine("-Support ordering, limits (TOP/OFFSET), and filtering.");
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region OpenAI Previous Query Execution
|
|
||||||
public async Task<string> OpenAIPreviousQueryExecution(OpenAIQueryLog oQueryLog)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oQueryLog.TotalExecution++;
|
|
||||||
|
|
||||||
#region Update OpenAI Query Log Total Execution
|
|
||||||
Task.Run(() =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var logService = new OpenAIQueryLogService();
|
|
||||||
logService.UpdateQueryLogTotalExecution(oQueryLog);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"[LogError] OpenAI log failed: {ex.Message}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
string sql = oQueryLog.GeneratedQuery;
|
|
||||||
DataSet data = GetOpenAIData(sql);
|
|
||||||
|
|
||||||
OpenAIResponse aiResponseObject = new OpenAIResponse
|
|
||||||
{
|
|
||||||
IsChart = oQueryLog.IsChart,
|
|
||||||
ChartType = GetAIChartType(oQueryLog.ChartType),
|
|
||||||
Sql = sql,
|
|
||||||
Message = string.Empty,
|
|
||||||
Title = oQueryLog.Title
|
|
||||||
};
|
|
||||||
var chartData = BuildOpenAIResponseWithData(data, aiResponseObject);
|
|
||||||
return Newtonsoft.Json.JsonConvert.SerializeObject(chartData);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new Exception(returnMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Process DataSet to JSON
|
|
||||||
public string ProcessDataSetToJson(DataSet OpenAiData)
|
|
||||||
{
|
|
||||||
string output;
|
|
||||||
DataSet information = new DataSet();
|
|
||||||
information = OpenAiData;
|
|
||||||
var value = (object)information;
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case null:
|
|
||||||
output = "";
|
|
||||||
break;
|
|
||||||
case DataSet ds:
|
|
||||||
output = JsonSerializer.Serialize(ds.Tables.Cast<DataTable>()
|
|
||||||
.Select(tbl => new {
|
|
||||||
TableName = tbl.TableName,
|
|
||||||
Rows = tbl.Rows.Cast<DataRow>()
|
|
||||||
.Select(row => tbl.Columns.Cast<DataColumn>()
|
|
||||||
.ToDictionary(col => col.ColumnName, col => row[col]))
|
|
||||||
}),
|
|
||||||
new JsonSerializerOptions { WriteIndented = true }
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case DataTable dt:
|
|
||||||
output = JsonSerializer.Serialize(
|
|
||||||
dt.Rows.Cast<DataRow>()
|
|
||||||
.Select(row => dt.Columns.Cast<DataColumn>()
|
|
||||||
.ToDictionary(col => col.ColumnName, col => row[col])),
|
|
||||||
new JsonSerializerOptions { WriteIndented = true }
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case IEnumerable<object> list:
|
|
||||||
output = JsonSerializer.Serialize(list, new JsonSerializerOptions { WriteIndented = true });
|
|
||||||
break;
|
|
||||||
case string str:
|
|
||||||
output = str;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
output = JsonSerializer.Serialize(value, new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
WriteIndented = true,
|
|
||||||
IgnoreReadOnlyProperties = true,
|
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
||||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Get OpenAI Data (Generate OpenAI's Provided SQL Query)
|
|
||||||
public DataSet GetOpenAIData(string sql)
|
|
||||||
{
|
|
||||||
TransactionContext tc = null;
|
|
||||||
|
|
||||||
DataSet information = new DataSet();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin();
|
|
||||||
information = OpenAIDA.GetOpenAIData(tc, sql);
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
return information;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Get 'Column Definitions' and 'Relations Between Tables'
|
|
||||||
public DataTable GetColumnDefinitions(TransactionContext tc, EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnDefinition = new DataTable();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oColumnDefinition = OpenAIDA.GetColumnDefinitions(tc, reportGroupType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
return oColumnDefinition;
|
|
||||||
}
|
|
||||||
public async Task<DataTable> GetColumnDefinitions(EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnDefinition = new DataTable();
|
|
||||||
TransactionContext tc = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin();
|
|
||||||
oColumnDefinition = OpenAIDA.GetColumnDefinitions(tc, reportGroupType);
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
return oColumnDefinition;
|
|
||||||
}
|
|
||||||
public DataTable GetColumnRelations(TransactionContext tc, EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnRelation = new DataTable();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oColumnRelation = OpenAIDA.GetColumnRelations(tc, reportGroupType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
return oColumnRelation;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Get All Type for (Leave Type & Salary Head)
|
|
||||||
public DataTable GetAllType(TransactionContext tc, EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
DataTable oColumnDefinition = new DataTable();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
oColumnDefinition = OpenAIDA.GetAllType(tc, reportGroupType);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
return oColumnDefinition;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Get AI Chart Type
|
|
||||||
public EnumAIChartType GetAIChartType(string type)
|
|
||||||
{
|
|
||||||
switch (type.ToLower())
|
|
||||||
{
|
|
||||||
case "pie":
|
|
||||||
return EnumAIChartType.PieChart;
|
|
||||||
case "bar":
|
|
||||||
return EnumAIChartType.BarChart;
|
|
||||||
case "line":
|
|
||||||
return EnumAIChartType.LineGraph;
|
|
||||||
case "scatter":
|
|
||||||
return EnumAIChartType.ScatterPlot;
|
|
||||||
case "area":
|
|
||||||
return EnumAIChartType.AreaChart;
|
|
||||||
case "histogram":
|
|
||||||
return EnumAIChartType.Histogram;
|
|
||||||
case "waterfall":
|
|
||||||
return EnumAIChartType.WaterfallChart;
|
|
||||||
case "gantt":
|
|
||||||
return EnumAIChartType.GantChart;
|
|
||||||
case "radar":
|
|
||||||
return EnumAIChartType.RadarChart;
|
|
||||||
case "activity":
|
|
||||||
return EnumAIChartType.ActivityDiagram;
|
|
||||||
default:
|
|
||||||
return EnumAIChartType.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public string GetAIChartType(EnumAIChartType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case EnumAIChartType.PieChart:
|
|
||||||
return "pie";
|
|
||||||
case EnumAIChartType.BarChart:
|
|
||||||
return "bar";
|
|
||||||
case EnumAIChartType.LineGraph:
|
|
||||||
return "line";
|
|
||||||
case EnumAIChartType.ScatterPlot:
|
|
||||||
return "scatter";
|
|
||||||
case EnumAIChartType.AreaChart:
|
|
||||||
return "area";
|
|
||||||
case EnumAIChartType.Histogram:
|
|
||||||
return "histogram";
|
|
||||||
case EnumAIChartType.WaterfallChart:
|
|
||||||
return "waterfall";
|
|
||||||
case EnumAIChartType.GantChart:
|
|
||||||
return "gantt";
|
|
||||||
case EnumAIChartType.RadarChart:
|
|
||||||
return "radar";
|
|
||||||
case EnumAIChartType.ActivityDiagram:
|
|
||||||
return "activity";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Total OpenAI Call
|
|
||||||
public int TotalOpenAICall()
|
|
||||||
{
|
|
||||||
TransactionContext tc = null;
|
|
||||||
int? totalCall = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tc = TransactionContext.Begin();
|
|
||||||
DataReader dr = new DataReader(OpenAIDA.TotalOpenAICall(tc));
|
|
||||||
if (dr.Read())
|
|
||||||
{
|
|
||||||
totalCall = dr.GetInt32(0);
|
|
||||||
}
|
|
||||||
dr.Close();
|
|
||||||
tc.End();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
#region Handle Exception
|
|
||||||
if (tc != null)
|
|
||||||
tc.HandleError();
|
|
||||||
ExceptionLog.Write(e);
|
|
||||||
throw new ServiceException(e.Message, e);
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
return totalCall ?? 0;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
public class AIServiceUsageLimitException : Exception
|
|
||||||
{
|
|
||||||
public AIServiceUsageLimitException(string message) : base(message) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,161 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
||||||
var useValue = arguments.length > 2;
|
|
||||||
for (var i = 0; i < initializers.length; i++) {
|
|
||||||
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
||||||
}
|
|
||||||
return useValue ? value : void 0;
|
|
||||||
};
|
|
||||||
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
||||||
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
||||||
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
||||||
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
||||||
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
||||||
var _, done = false;
|
|
||||||
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
||||||
var context = {};
|
|
||||||
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
||||||
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
||||||
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
||||||
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
||||||
if (kind === "accessor") {
|
|
||||||
if (result === void 0) continue;
|
|
||||||
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
||||||
if (_ = accept(result.get)) descriptor.get = _;
|
|
||||||
if (_ = accept(result.set)) descriptor.set = _;
|
|
||||||
if (_ = accept(result.init)) initializers.unshift(_);
|
|
||||||
}
|
|
||||||
else if (_ = accept(result)) {
|
|
||||||
if (kind === "field") initializers.unshift(_);
|
|
||||||
else descriptor[key] = _;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
||||||
done = true;
|
|
||||||
};
|
|
||||||
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
||||||
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
||||||
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.BackgroundCanvasComponent = void 0;
|
|
||||||
var core_1 = require("@angular/core");
|
|
||||||
var BackgroundCanvasComponent = function () {
|
|
||||||
var _classDecorators = [(0, core_1.Component)({
|
|
||||||
standalone: false,
|
|
||||||
selector: 'app-background-canvas',
|
|
||||||
template: "\n <canvas #networkCanvas></canvas>\n ",
|
|
||||||
styles: ["\n canvas {\n display: block;\n position: absolute;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n }\n ",],
|
|
||||||
})];
|
|
||||||
var _classDescriptor;
|
|
||||||
var _classExtraInitializers = [];
|
|
||||||
var _classThis;
|
|
||||||
var _instanceExtraInitializers = [];
|
|
||||||
var _canvasRef_decorators;
|
|
||||||
var _canvasRef_initializers = [];
|
|
||||||
var _canvasRef_extraInitializers = [];
|
|
||||||
var _onResize_decorators;
|
|
||||||
var BackgroundCanvasComponent = _classThis = /** @class */ (function () {
|
|
||||||
function BackgroundCanvasComponent_1(elementRef, apiService) {
|
|
||||||
this.elementRef = (__runInitializers(this, _instanceExtraInitializers), elementRef);
|
|
||||||
this.apiService = apiService;
|
|
||||||
this.canvasRef = __runInitializers(this, _canvasRef_initializers, void 0);
|
|
||||||
this.canvas = __runInitializers(this, _canvasRef_extraInitializers);
|
|
||||||
this.particles = [];
|
|
||||||
this.particleCount = 120;
|
|
||||||
}
|
|
||||||
BackgroundCanvasComponent_1.prototype.ngAfterViewInit = function () {
|
|
||||||
this.canvas = this.canvasRef.nativeElement;
|
|
||||||
this.ctx = this.canvas.getContext('2d');
|
|
||||||
this.resizeCanvas();
|
|
||||||
this.initParticles();
|
|
||||||
this.animate();
|
|
||||||
};
|
|
||||||
BackgroundCanvasComponent_1.prototype.onResize = function () {
|
|
||||||
this.resizeCanvas();
|
|
||||||
};
|
|
||||||
BackgroundCanvasComponent_1.prototype.resizeCanvas = function () {
|
|
||||||
this.canvas.width = window.innerWidth;
|
|
||||||
this.canvas.height = window.innerHeight;
|
|
||||||
};
|
|
||||||
BackgroundCanvasComponent_1.prototype.initParticles = function () {
|
|
||||||
this.particles = [];
|
|
||||||
for (var i = 0; i < this.particleCount; i++) {
|
|
||||||
this.particles.push({
|
|
||||||
x: Math.random() * this.canvas.width,
|
|
||||||
y: Math.random() * this.canvas.height,
|
|
||||||
vx: (Math.random() * 2 - 1) * 0.01,
|
|
||||||
vy: (Math.random() * 2 - 1) * 0.01,
|
|
||||||
radius: Math.floor(Math.random() * 10) + 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
BackgroundCanvasComponent_1.prototype.animate = function () {
|
|
||||||
var _this = this;
|
|
||||||
if (!this.ctx)
|
|
||||||
return;
|
|
||||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
||||||
this.particles.forEach(function (p) {
|
|
||||||
p.x += p.vx;
|
|
||||||
p.y += p.vy;
|
|
||||||
if (p.x <= 0 || p.x >= _this.canvas.width)
|
|
||||||
p.vx *= -1;
|
|
||||||
if (p.y <= 0 || p.y >= _this.canvas.height)
|
|
||||||
p.vy *= -1;
|
|
||||||
_this.drawParticle(p);
|
|
||||||
});
|
|
||||||
this.connectParticles();
|
|
||||||
requestAnimationFrame(function () { return _this.animate(); });
|
|
||||||
};
|
|
||||||
BackgroundCanvasComponent_1.prototype.drawParticle = function (p) {
|
|
||||||
if (!this.ctx)
|
|
||||||
return;
|
|
||||||
this.ctx.beginPath();
|
|
||||||
this.ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
|
|
||||||
this.ctx.fillStyle = '#ffffff';
|
|
||||||
this.ctx.fill();
|
|
||||||
this.ctx.closePath();
|
|
||||||
};
|
|
||||||
BackgroundCanvasComponent_1.prototype.connectParticles = function () {
|
|
||||||
if (!this.ctx)
|
|
||||||
return;
|
|
||||||
for (var i = 0; i < this.particles.length; i++) {
|
|
||||||
for (var j = i + 1; j < this.particles.length; j++) {
|
|
||||||
var p1 = this.particles[i];
|
|
||||||
var p2 = this.particles[j];
|
|
||||||
var dx = p2.x - p1.x;
|
|
||||||
var dy = p2.y - p1.y;
|
|
||||||
var distance = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
if (distance < 100) {
|
|
||||||
var theta = Math.atan2(dy, dx);
|
|
||||||
var x1 = p1.x + Math.cos(theta) * p1.radius;
|
|
||||||
var y1 = p1.y + Math.sin(theta) * p1.radius;
|
|
||||||
var x2 = p2.x - Math.cos(theta) * p2.radius;
|
|
||||||
var y2 = p2.y - Math.sin(theta) * p2.radius;
|
|
||||||
this.ctx.beginPath();
|
|
||||||
this.ctx.moveTo(x1, y1);
|
|
||||||
this.ctx.lineTo(x2, y2);
|
|
||||||
this.ctx.strokeStyle = '#ffffff';
|
|
||||||
this.ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return BackgroundCanvasComponent_1;
|
|
||||||
}());
|
|
||||||
__setFunctionName(_classThis, "BackgroundCanvasComponent");
|
|
||||||
(function () {
|
|
||||||
var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
||||||
_canvasRef_decorators = [(0, core_1.ViewChild)('networkCanvas', { static: true })];
|
|
||||||
_onResize_decorators = [(0, core_1.HostListener)('window:resize')];
|
|
||||||
__esDecorate(_classThis, null, _onResize_decorators, { kind: "method", name: "onResize", static: false, private: false, access: { has: function (obj) { return "onResize" in obj; }, get: function (obj) { return obj.onResize; } }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
||||||
__esDecorate(null, null, _canvasRef_decorators, { kind: "field", name: "canvasRef", static: false, private: false, access: { has: function (obj) { return "canvasRef" in obj; }, get: function (obj) { return obj.canvasRef; }, set: function (obj, value) { obj.canvasRef = value; } }, metadata: _metadata }, _canvasRef_initializers, _canvasRef_extraInitializers);
|
|
||||||
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
||||||
BackgroundCanvasComponent = _classThis = _classDescriptor.value;
|
|
||||||
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
||||||
__runInitializers(_classThis, _classExtraInitializers);
|
|
||||||
})();
|
|
||||||
return BackgroundCanvasComponent = _classThis;
|
|
||||||
}();
|
|
||||||
exports.BackgroundCanvasComponent = BackgroundCanvasComponent;
|
|
||||||
//# sourceMappingURL=BackgroundCanvas.Component.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"BackgroundCanvas.Component.js","sourceRoot":"","sources":["BackgroundCanvas.Component.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sCAA8F;AAoB9F;4BAjBC,IAAA,gBAAS,EAAC;YACP,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,uBAAuB;YACjC,QAAQ,EAAE,kDAET;YACD,MAAM,EAAE,CAAC,qMASR,EAAE;SACN,CAAC;;;;;;;;;;QAQE,qCAAoB,UAAsB,EAAS,UAAuB;YAAtD,eAAU,IAPrB,mDAAyB,EAOd,UAAU,EAAY;YAAS,eAAU,GAAV,UAAU,CAAa;YAN5B,cAAS,4DAAiC;YAChF,WAAM,yDAAqB;YAE3B,cAAS,GAAU,EAAE,CAAC;YACtB,kBAAa,GAAG,GAAG,CAAC;QAG5B,CAAC;QAED,qDAAe,GAAf;YACI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;YAC3C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;QAED,8CAAQ,GAAR;YACI,IAAI,CAAC,YAAY,EAAE,CAAC;QACxB,CAAC;QACO,kDAAY,GAApB;YACI,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;QAC5C,CAAC;QACO,mDAAa,GAArB;YACI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9C,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;oBAChB,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK;oBACpC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;oBACrC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI;oBAClC,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI;oBAClC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC;iBAC7C,CAAC,CAAC;YACH,CAAC;QACL,CAAC;QACO,6CAAO,GAAf;YAAA,iBAYC;YAXG,IAAI,CAAC,IAAI,CAAC,GAAG;gBAAE,OAAO;YACtB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAChE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,UAAA,CAAC;gBACxB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBACZ,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAI,CAAC,MAAM,CAAC,KAAK;oBAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;gBACrD,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAI,CAAC,MAAM,CAAC,MAAM;oBAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;gBACtD,KAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,qBAAqB,CAAC,cAAM,OAAA,KAAI,CAAC,OAAO,EAAE,EAAd,CAAc,CAAC,CAAC;QAChD,CAAC;QACO,kDAAY,GAApB,UAAqB,CAAM;YACvB,IAAI,CAAC,IAAI,CAAC,GAAG;gBAAE,OAAO;YACtB,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YACrB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;QACO,sDAAgB,GAAxB;YACI,IAAI,CAAC,IAAI,CAAC,GAAG;gBAAE,OAAO;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACjD,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACjD,IAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBAC7B,IAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;oBAC7B,IAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBACvB,IAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBACvB,IAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;oBAE9C,IAAI,QAAQ,GAAG,GAAG,EAAE,CAAC;wBACrB,IAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;wBACjC,IAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;wBAC9C,IAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;wBAC9C,IAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;wBAC9C,IAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;wBAC9C,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;wBACrB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;wBACxB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;wBACxB,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC;wBACjC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;oBAClB,CAAC;gBACL,CAAC;YACD,CAAC;QACL,CAAC;QACL,kCAAC;IAAD,CAAC;;;;iCAlFI,IAAA,gBAAS,EAAC,eAAe,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;gCAgB5C,IAAA,mBAAY,EAAC,eAAe,CAAC;QAC9B,sNAAA,QAAQ,gEAEP;QAnB6C,kNAAA,SAAS,sCAAT,SAAS,6FAAiC;QAD5F,6KAmFC;;;QAnFY,uDAAyB;;;IAmFrC;AAnFY,8DAAyB"}
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
import { AfterViewInit, Component, ElementRef, HostListener, ViewChild } from '@angular/core';
|
|
||||||
import { ApiService } from '../app.api.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
//standalone: false,
|
|
||||||
selector: 'app-background-canvas',
|
|
||||||
template: `
|
|
||||||
<canvas #networkCanvas></canvas>
|
|
||||||
`,
|
|
||||||
styles: [`
|
|
||||||
canvas {
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
`,],
|
|
||||||
})
|
|
||||||
export class BackgroundCanvasComponent {
|
|
||||||
@ViewChild('networkCanvas', { static: true }) canvasRef!: ElementRef<HTMLCanvasElement>;
|
|
||||||
private canvas!: HTMLCanvasElement;
|
|
||||||
private ctx!: CanvasRenderingContext2D | null;
|
|
||||||
private particles: any[] = [];
|
|
||||||
private particleCount = 120;
|
|
||||||
|
|
||||||
constructor(private elementRef: ElementRef, public apiService : ApiService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
|
||||||
this.canvas = this.canvasRef.nativeElement;
|
|
||||||
this.ctx = this.canvas.getContext('2d');
|
|
||||||
this.resizeCanvas();
|
|
||||||
this.initParticles();
|
|
||||||
this.animate();
|
|
||||||
}
|
|
||||||
@HostListener('window:resize')
|
|
||||||
onResize() {
|
|
||||||
this.resizeCanvas();
|
|
||||||
}
|
|
||||||
private resizeCanvas(): void {
|
|
||||||
this.canvas.width = window.innerWidth;
|
|
||||||
this.canvas.height = window.innerHeight;
|
|
||||||
}
|
|
||||||
private initParticles(): void {
|
|
||||||
this.particles = [];
|
|
||||||
for (let i = 0; i < this.particleCount; i++) {
|
|
||||||
this.particles.push({
|
|
||||||
x: Math.random() * this.canvas.width,
|
|
||||||
y: Math.random() * this.canvas.height,
|
|
||||||
vx: (Math.random() * 2 - 1) * 0.01,
|
|
||||||
vy: (Math.random() * 2 - 1) * 0.01,
|
|
||||||
radius: Math.floor(Math.random() * 10) + 1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private animate(): void {
|
|
||||||
if (!this.ctx) return;
|
|
||||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
||||||
this.particles.forEach(p => {
|
|
||||||
p.x += p.vx;
|
|
||||||
p.y += p.vy;
|
|
||||||
if (p.x <= 0 || p.x >= this.canvas.width) p.vx *= -1;
|
|
||||||
if (p.y <= 0 || p.y >= this.canvas.height) p.vy *= -1;
|
|
||||||
this.drawParticle(p);
|
|
||||||
});
|
|
||||||
this.connectParticles();
|
|
||||||
requestAnimationFrame(() => this.animate());
|
|
||||||
}
|
|
||||||
private drawParticle(p: any): void {
|
|
||||||
if (!this.ctx) return;
|
|
||||||
this.ctx.beginPath();
|
|
||||||
this.ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
|
|
||||||
this.ctx.fillStyle = '#ffffff';
|
|
||||||
this.ctx.fill();
|
|
||||||
this.ctx.closePath();
|
|
||||||
}
|
|
||||||
private connectParticles(): void {
|
|
||||||
if (!this.ctx) return;
|
|
||||||
for (let i = 0; i < this.particles.length; i++) {
|
|
||||||
for (let j = i + 1; j < this.particles.length; j++) {
|
|
||||||
const p1 = this.particles[i];
|
|
||||||
const p2 = this.particles[j];
|
|
||||||
const dx = p2.x - p1.x;
|
|
||||||
const dy = p2.y - p1.y;
|
|
||||||
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
|
|
||||||
if (distance < 100) {
|
|
||||||
const theta = Math.atan2(dy, dx);
|
|
||||||
const x1 = p1.x + Math.cos(theta) * p1.radius;
|
|
||||||
const y1 = p1.y + Math.sin(theta) * p1.radius;
|
|
||||||
const x2 = p2.x - Math.cos(theta) * p2.radius;
|
|
||||||
const y2 = p2.y - Math.sin(theta) * p2.radius;
|
|
||||||
this.ctx.beginPath();
|
|
||||||
this.ctx.moveTo(x1, y1);
|
|
||||||
this.ctx.lineTo(x2, y2);
|
|
||||||
this.ctx.strokeStyle = '#ffffff';
|
|
||||||
this.ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
||||||
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
||||||
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
||||||
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
||||||
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
||||||
var _, done = false;
|
|
||||||
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
||||||
var context = {};
|
|
||||||
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
||||||
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
||||||
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
||||||
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
||||||
if (kind === "accessor") {
|
|
||||||
if (result === void 0) continue;
|
|
||||||
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
||||||
if (_ = accept(result.get)) descriptor.get = _;
|
|
||||||
if (_ = accept(result.set)) descriptor.set = _;
|
|
||||||
if (_ = accept(result.init)) initializers.unshift(_);
|
|
||||||
}
|
|
||||||
else if (_ = accept(result)) {
|
|
||||||
if (kind === "field") initializers.unshift(_);
|
|
||||||
else descriptor[key] = _;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
||||||
done = true;
|
|
||||||
};
|
|
||||||
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
||||||
var useValue = arguments.length > 2;
|
|
||||||
for (var i = 0; i < initializers.length; i++) {
|
|
||||||
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
||||||
}
|
|
||||||
return useValue ? value : void 0;
|
|
||||||
};
|
|
||||||
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
||||||
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
||||||
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.BackgroundCanvasModule = void 0;
|
|
||||||
var core_1 = require("@angular/core");
|
|
||||||
var kendo_angular_indicators_1 = require("@progress/kendo-angular-indicators");
|
|
||||||
var common_1 = require("@angular/common");
|
|
||||||
var BackgroundCanvas_Component_1 = require("./BackgroundCanvas.Component");
|
|
||||||
var BackgroundCanvasModule = function () {
|
|
||||||
var _classDecorators = [(0, core_1.NgModule)({
|
|
||||||
imports: [
|
|
||||||
kendo_angular_indicators_1.IndicatorsModule,
|
|
||||||
common_1.CommonModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
BackgroundCanvas_Component_1.BackgroundCanvasComponent
|
|
||||||
],
|
|
||||||
providers: [],
|
|
||||||
exports: [
|
|
||||||
BackgroundCanvas_Component_1.BackgroundCanvasComponent
|
|
||||||
]
|
|
||||||
})];
|
|
||||||
var _classDescriptor;
|
|
||||||
var _classExtraInitializers = [];
|
|
||||||
var _classThis;
|
|
||||||
var BackgroundCanvasModule = _classThis = /** @class */ (function () {
|
|
||||||
function BackgroundCanvasModule_1() {
|
|
||||||
}
|
|
||||||
return BackgroundCanvasModule_1;
|
|
||||||
}());
|
|
||||||
__setFunctionName(_classThis, "BackgroundCanvasModule");
|
|
||||||
(function () {
|
|
||||||
var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
||||||
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
||||||
BackgroundCanvasModule = _classThis = _classDescriptor.value;
|
|
||||||
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
||||||
__runInitializers(_classThis, _classExtraInitializers);
|
|
||||||
})();
|
|
||||||
return BackgroundCanvasModule = _classThis;
|
|
||||||
}();
|
|
||||||
exports.BackgroundCanvasModule = BackgroundCanvasModule;
|
|
||||||
//# sourceMappingURL=BackgroundCanvas.module.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"BackgroundCanvas.module.js","sourceRoot":"","sources":["BackgroundCanvas.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sCAAyC;AACzC,+EAAsE;AACtE,0CAA+C;AAC/C,2EAAyE;AAiBzE;4BAhBC,IAAA,eAAQ,EAAC;YACN,OAAO,EAAE;gBACL,2CAAgB;gBAChB,qBAAY;aACf;YACD,YAAY,EAAE;gBACV,sDAAyB;aAC5B;YACD,SAAS,EAAE,EAEV;YACD,OAAO,EAAE;gBACL,sDAAyB;aAC5B;SACJ,CAAC;;;;;;QAGF,CAAC;QAAD,+BAAC;IAAD,CAAC;;;;QADD,6KACC;;;QADY,uDAAsB;;;IAClC;AADY,wDAAsB"}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { IndicatorsModule } from '@progress/kendo-angular-indicators';
|
|
||||||
import { CommonModule } from "@angular/common";
|
|
||||||
import { BackgroundCanvasComponent } from './BackgroundCanvas.Component';
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
IndicatorsModule,
|
|
||||||
CommonModule
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
BackgroundCanvasComponent
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
|
|
||||||
],
|
|
||||||
exports: [
|
|
||||||
BackgroundCanvasComponent
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
export class BackgroundCanvasModule {
|
|
||||||
}
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.CourseProgress = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var CourseProgress = /** @class */ (function (_super) {
|
|
||||||
__extends(CourseProgress, _super);
|
|
||||||
function CourseProgress() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.completionPercentage = 0;
|
|
||||||
_this.startDate = new Date();
|
|
||||||
_this.isCourseComplete = false;
|
|
||||||
_this.lastActivityDate = new Date();
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return CourseProgress;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.CourseProgress = CourseProgress;
|
|
||||||
//# sourceMappingURL=course-progress.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"course-progress.js","sourceRoot":"","sources":["course-progress.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AAGjD;IAAoC,kCAAU;IAC1C;QACI,YAAA,MAAK,WAAE,SAAC;QACR,KAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAC9B,KAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,KAAI,CAAC,gBAAgB,GAAG,IAAI,IAAI,EAAE,CAAC;;IACvC,CAAC;IAUL,qBAAC;AAAD,CAAC,AAjBD,CAAoC,uBAAU,GAiB7C;AAjBY,wCAAc"}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { LessonProgress } from './lesson-progress';
|
|
||||||
|
|
||||||
export class CourseProgress extends BaseObject{
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.completionPercentage = 0;
|
|
||||||
this.startDate = new Date();
|
|
||||||
this.isCourseComplete = false;
|
|
||||||
this.lastActivityDate = new Date();
|
|
||||||
}
|
|
||||||
|
|
||||||
userID: number;
|
|
||||||
courseID: number;
|
|
||||||
enrollmentID: number;
|
|
||||||
completionPercentage: number;
|
|
||||||
startDate: Date;
|
|
||||||
isCourseComplete: boolean;
|
|
||||||
endDate?: Date;
|
|
||||||
lastActivityDate?: Date;
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.CourseType = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var enums_1 = require("../enums");
|
|
||||||
var CourseType = /** @class */ (function (_super) {
|
|
||||||
__extends(CourseType, _super);
|
|
||||||
function CourseType() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.description = "";
|
|
||||||
_this.tags = "";
|
|
||||||
_this.popularityScore = 0.0;
|
|
||||||
_this.parentTypeID = null;
|
|
||||||
_this.status = enums_1.EnumStatus.Active;
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return CourseType;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.CourseType = CourseType;
|
|
||||||
//# sourceMappingURL=course-type.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"course-type.js","sourceRoot":"","sources":["course-type.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AACjD,kCAAoC;AAEpC;IAAgC,8BAAU;IACtC;QACI,YAAA,MAAK,WAAE,SAAC;QACR,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,KAAI,CAAC,eAAe,GAAG,GAAG,CAAC;QAC3B,KAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,KAAI,CAAC,MAAM,GAAG,kBAAU,CAAC,MAAM,CAAC;;IACpC,CAAC;IAOL,iBAAC;AAAD,CAAC,AAfD,CAAgC,uBAAU,GAezC;AAfY,gCAAU"}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import {EnumStatus} from '../enums';
|
|
||||||
|
|
||||||
export class CourseType extends BaseObject {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.description = "";
|
|
||||||
this.tags = "";
|
|
||||||
this.popularityScore = 0.0;
|
|
||||||
this.parentTypeID = null;
|
|
||||||
this.status = EnumStatus.Active;
|
|
||||||
}
|
|
||||||
|
|
||||||
name : string;
|
|
||||||
description : string;
|
|
||||||
parentTypeID? : number;
|
|
||||||
tags : string;
|
|
||||||
popularityScore : number;
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Courses = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var enums_1 = require("../enums");
|
|
||||||
var lmstemplate_1 = require("./lmstemplate");
|
|
||||||
var Courses = /** @class */ (function (_super) {
|
|
||||||
__extends(Courses, _super);
|
|
||||||
function Courses() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.lessonProgres = [];
|
|
||||||
_this.courseTitle = "";
|
|
||||||
_this.courseCode = "";
|
|
||||||
_this.courseTypeID = 0;
|
|
||||||
_this.description = "";
|
|
||||||
_this.difficultyLevel = enums_1.EnumDifficultyLevel.Beginner;
|
|
||||||
_this.trainerID = 0;
|
|
||||||
_this.duration = "";
|
|
||||||
_this.status = enums_1.EnumStatus.Active;
|
|
||||||
_this.isForFree = true;
|
|
||||||
_this.price = 0;
|
|
||||||
_this.totalEnrollments = 0;
|
|
||||||
_this.rating = 0.0;
|
|
||||||
_this.popularityScore = 0.0;
|
|
||||||
_this.completionRate = 0.0;
|
|
||||||
_this.averageProgress = 0.0;
|
|
||||||
_this.isExamRequired = false;
|
|
||||||
_this.tags = "";
|
|
||||||
_this.targetedAudience = "";
|
|
||||||
_this.learningOutcomes = "";
|
|
||||||
_this.courseIncludes = "";
|
|
||||||
_this.startGuideLine = "";
|
|
||||||
_this.createdUser = "";
|
|
||||||
_this.lessons = [];
|
|
||||||
_this.totalLesson = 0;
|
|
||||||
_this.totalContent = 0;
|
|
||||||
_this.courseTemplate = new lmstemplate_1.LMSTemplate();
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return Courses;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.Courses = Courses;
|
|
||||||
//# sourceMappingURL=courses.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"courses.js","sourceRoot":"","sources":["courses.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AAEjD,kCAA2D;AAM3D,6CAA4C;AAE5C;IAA6B,2BAAU;IACnC;QACI,YAAA,MAAK,WAAE,SAAC;QA2DZ,mBAAa,GAAuB,EAAE,CAAC;QAzDnC,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,KAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,eAAe,GAAG,2BAAmB,CAAC,QAAQ,CAAC;QACpD,KAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,KAAI,CAAC,MAAM,GAAG,kBAAU,CAAC,MAAM,CAAC;QAChC,KAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,KAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,KAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC;QAC1B,KAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,KAAI,CAAC,eAAe,GAAG,GAAG,CAAC;QAC3B,KAAI,CAAC,cAAc,GAAG,GAAG,CAAC;QAC1B,KAAI,CAAC,eAAe,GAAG,GAAG,CAAC;QAC3B,KAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,KAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,KAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,KAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,KAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,KAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,KAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,KAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,KAAI,CAAC,cAAc,GAAG,IAAI,yBAAW,EAAE,CAAC;;IAC5C,CAAC;IAgCL,cAAC;AAAD,CAAC,AA9DD,CAA6B,uBAAU,GA8DtC;AA9DY,0BAAO"}
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { Employee } from '../Employee/employee';
|
|
||||||
import { EnumDifficultyLevel, EnumStatus } from '../enums';
|
|
||||||
import { CourseProgress } from './course-progress';
|
|
||||||
import { CourseType } from './course-type';
|
|
||||||
import { Enrollments } from './enrollments';
|
|
||||||
import { LessonProgress } from './lesson-progress';
|
|
||||||
import { Lessons } from './lessons';
|
|
||||||
import { LMSTemplate } from './lmstemplate';
|
|
||||||
|
|
||||||
export class Courses extends BaseObject {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.courseTitle = "";
|
|
||||||
this.courseCode = "";
|
|
||||||
this.courseTypeID = 0;
|
|
||||||
this.description = "";
|
|
||||||
this.difficultyLevel = EnumDifficultyLevel.Beginner;
|
|
||||||
this.trainerID = 0;
|
|
||||||
this.duration = "";
|
|
||||||
this.status = EnumStatus.Active;
|
|
||||||
this.isForFree = true;
|
|
||||||
this.price = 0;
|
|
||||||
this.totalEnrollments = 0;
|
|
||||||
this.rating = 0.0;
|
|
||||||
this.popularityScore = 0.0;
|
|
||||||
this.completionRate = 0.0;
|
|
||||||
this.averageProgress = 0.0;
|
|
||||||
this.isExamRequired = false;
|
|
||||||
this.tags = "";
|
|
||||||
this.targetedAudience = "";
|
|
||||||
this.learningOutcomes = "";
|
|
||||||
this.courseIncludes = "";
|
|
||||||
this.startGuideLine = "";
|
|
||||||
this.createdUser = "";
|
|
||||||
this.lessons = [];
|
|
||||||
this.totalLesson = 0;
|
|
||||||
this.totalContent = 0;
|
|
||||||
this.courseTemplate = new LMSTemplate();
|
|
||||||
}
|
|
||||||
courseTitle: string;
|
|
||||||
courseCode: string;
|
|
||||||
courseTypeID: number;
|
|
||||||
description: string;
|
|
||||||
difficultyLevel: EnumDifficultyLevel;
|
|
||||||
trainerID: number;
|
|
||||||
duration?: string;
|
|
||||||
isForFree?: boolean;
|
|
||||||
price?: number;
|
|
||||||
totalEnrollments?: number;
|
|
||||||
rating?: number;
|
|
||||||
popularityScore?: number;
|
|
||||||
completionRate?: number;
|
|
||||||
averageProgress?: number;
|
|
||||||
isExamRequired?: boolean;
|
|
||||||
tags?: string;
|
|
||||||
targetedAudience?: string;
|
|
||||||
learningOutcomes?: string;
|
|
||||||
courseIncludes?: string;
|
|
||||||
startGuideLine?: string;
|
|
||||||
lessons : Lessons[];
|
|
||||||
courseTemplate : LMSTemplate;
|
|
||||||
courseType : CourseType;
|
|
||||||
totalLesson : number;
|
|
||||||
totalContent : number;
|
|
||||||
trainer : Employee;
|
|
||||||
createdUser : string;
|
|
||||||
|
|
||||||
enrollments : Enrollments;
|
|
||||||
courseProgres : CourseProgress;
|
|
||||||
lessonProgres : LessonProgress [] = [];
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Enrollments = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var Enrollments = /** @class */ (function (_super) {
|
|
||||||
__extends(Enrollments, _super);
|
|
||||||
function Enrollments() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.enrollmentID = 0;
|
|
||||||
_this.userID = 0;
|
|
||||||
_this.courseID = 0;
|
|
||||||
_this.enrollDate = new Date();
|
|
||||||
_this.isCurrentEnroll = false;
|
|
||||||
_this.noOfEnroll = 0;
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return Enrollments;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.Enrollments = Enrollments;
|
|
||||||
//# sourceMappingURL=enrollments.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"enrollments.js","sourceRoot":"","sources":["enrollments.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AAGjD;IAAiC,+BAAU;IACvC;QACI,YAAA,MAAK,WAAE,SAAC;QACR,KAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,KAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,KAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,KAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,KAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,KAAI,CAAC,UAAU,GAAG,CAAC,CAAC;;IACxB,CAAC;IASL,kBAAC;AAAD,CAAC,AAlBD,CAAiC,uBAAU,GAkB1C;AAlBY,kCAAW"}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { CourseProgress } from './course-progress';
|
|
||||||
|
|
||||||
export class Enrollments extends BaseObject {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.enrollmentID = 0;
|
|
||||||
this.userID = 0;
|
|
||||||
this.courseID = 0;
|
|
||||||
this.enrollDate = new Date();
|
|
||||||
this.isCurrentEnroll = false;
|
|
||||||
this.noOfEnroll = 0;
|
|
||||||
}
|
|
||||||
enrollmentID: number;
|
|
||||||
userID: number;
|
|
||||||
courseID: number;
|
|
||||||
enrollDate: Date;
|
|
||||||
isCurrentEnroll: boolean;
|
|
||||||
noOfEnroll : number;
|
|
||||||
|
|
||||||
courseProgres : CourseProgress;
|
|
||||||
}
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.LessonContent = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var enums_1 = require("../enums");
|
|
||||||
var LessonContent = /** @class */ (function (_super) {
|
|
||||||
__extends(LessonContent, _super);
|
|
||||||
function LessonContent() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.isLessonComplete = false;
|
|
||||||
_this.isComplete = true;
|
|
||||||
_this.isNotComplete = false;
|
|
||||||
_this.lessonID = 0;
|
|
||||||
_this.contentTitle = "";
|
|
||||||
_this.description = "";
|
|
||||||
_this.contentUrl = "";
|
|
||||||
_this.duration = "";
|
|
||||||
_this.isMendatory = false;
|
|
||||||
_this.status = enums_1.EnumStatus.Active;
|
|
||||||
_this.accessLevel = enums_1.EnumAccessLevel.Public;
|
|
||||||
_this.accessCount = 0;
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return LessonContent;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.LessonContent = LessonContent;
|
|
||||||
//# sourceMappingURL=lesson-content.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"lesson-content.js","sourceRoot":"","sources":["lesson-content.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AACjD,kCAA2F;AAE3F;IAAmC,iCAAU;IAEzC;QACI,YAAA,MAAK,WAAE,SAAC;QAsBZ,sBAAgB,GAAY,KAAK,CAAC;QAClC,gBAAU,GAAa,IAAI,CAAC;QAC5B,mBAAa,GAAa,KAAK,CAAC;QAvB5B,KAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,KAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,KAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,KAAI,CAAC,MAAM,GAAG,kBAAU,CAAC,MAAM,CAAC;QAChC,KAAI,CAAC,WAAW,GAAG,uBAAe,CAAC,MAAM,CAAC;QAC1C,KAAI,CAAC,WAAW,GAAG,CAAC,CAAC;;IACzB,CAAC;IAeL,oBAAC;AAAD,CAAC,AA5BD,CAAmC,uBAAU,GA4B5C;AA5BY,sCAAa"}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { EnumStatus, EnumAccessLevel, EnumContentSource, EnumContentType } from '../enums';
|
|
||||||
|
|
||||||
export class LessonContent extends BaseObject{
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.lessonID = 0;
|
|
||||||
this.contentTitle = "";
|
|
||||||
this.description = "";
|
|
||||||
this.contentUrl = "";
|
|
||||||
this.duration = "";
|
|
||||||
this.isMendatory = false;
|
|
||||||
this.status = EnumStatus.Active;
|
|
||||||
this.accessLevel = EnumAccessLevel.Public;
|
|
||||||
this.accessCount = 0;
|
|
||||||
}
|
|
||||||
lessonID: number; // Foreign Key to LMS_Lessons
|
|
||||||
contentTitle: string;
|
|
||||||
contentType: EnumContentType;
|
|
||||||
description: string;
|
|
||||||
contentUrl: string;
|
|
||||||
duration?: string;
|
|
||||||
isMendatory?: boolean;
|
|
||||||
accessLevel: EnumAccessLevel;
|
|
||||||
contentSource: EnumContentSource;
|
|
||||||
accessCount?: number;
|
|
||||||
|
|
||||||
isLessonComplete: boolean = false;
|
|
||||||
isComplete : boolean = true;
|
|
||||||
isNotComplete : boolean = false;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.LessonProgress = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var LessonProgress = /** @class */ (function (_super) {
|
|
||||||
__extends(LessonProgress, _super);
|
|
||||||
function LessonProgress() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.isLessonComplete = false;
|
|
||||||
_this.completionPercentage = 0;
|
|
||||||
_this.startDate = new Date();
|
|
||||||
_this.lastAccessed = new Date();
|
|
||||||
_this.retryCount = 0;
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return LessonProgress;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.LessonProgress = LessonProgress;
|
|
||||||
//# sourceMappingURL=lesson-progress.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"lesson-progress.js","sourceRoot":"","sources":["lesson-progress.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AAGjD;IAAoC,kCAAU;IAC1C;QACI,YAAA,MAAK,WAAE,SAAC;QACR,KAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,KAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAC9B,KAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAI,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC;QAC/B,KAAI,CAAC,UAAU,GAAG,CAAC,CAAC;;IACxB,CAAC;IAeL,qBAAC;AAAD,CAAC,AAvBD,CAAoC,uBAAU,GAuB7C;AAvBY,wCAAc"}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { Lessons } from './lessons';
|
|
||||||
|
|
||||||
export class LessonProgress extends BaseObject{
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.isLessonComplete = false;
|
|
||||||
this.completionPercentage = 0;
|
|
||||||
this.startDate = new Date();
|
|
||||||
this.lastAccessed = new Date();
|
|
||||||
this.retryCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
userID: number;
|
|
||||||
lessonID: number;
|
|
||||||
courseProgressID: number;
|
|
||||||
lessonContentID: number;
|
|
||||||
isLessonComplete: boolean;
|
|
||||||
completionPercentage: number;
|
|
||||||
startDate: Date;
|
|
||||||
completeDate: Date;
|
|
||||||
timeSpent: string;
|
|
||||||
lastAccessed: Date;
|
|
||||||
retryCount: number;
|
|
||||||
|
|
||||||
lesson : Lessons;
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Lessons = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var enums_1 = require("../enums");
|
|
||||||
var Lessons = /** @class */ (function (_super) {
|
|
||||||
__extends(Lessons, _super);
|
|
||||||
function Lessons() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.lessonContents = [];
|
|
||||||
_this.courseID = 0;
|
|
||||||
_this.lessonTitle = "";
|
|
||||||
_this.lessonNo = "";
|
|
||||||
_this.description = "";
|
|
||||||
_this.duration = "";
|
|
||||||
_this.difficultyLevel = enums_1.EnumDifficultyLevel.Beginner;
|
|
||||||
_this.isQuizAvailable = false;
|
|
||||||
_this.status = enums_1.EnumStatus.Active;
|
|
||||||
_this.lessonContents = [];
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return Lessons;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.Lessons = Lessons;
|
|
||||||
//# sourceMappingURL=lessons.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"lessons.js","sourceRoot":"","sources":["lessons.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AACjD,kCAA2D;AAI3D;IAA6B,2BAAU;IACnC;QACI,YAAA,MAAK,WAAE,SAAC;QAkBZ,oBAAc,GAAqB,EAAE,CAAC;QAjBlC,KAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,KAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,KAAI,CAAC,eAAe,GAAG,2BAAmB,CAAC,QAAQ,CAAC;QACpD,KAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,KAAI,CAAC,MAAM,GAAG,kBAAU,CAAC,MAAM,CAAC;QAChC,KAAI,CAAC,cAAc,GAAG,EAAE,CAAC;;IAC7B,CAAC;IAUL,cAAC;AAAD,CAAC,AAtBD,CAA6B,uBAAU,GAsBtC;AAtBY,0BAAO"}
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { EnumDifficultyLevel, EnumStatus } from '../enums';
|
|
||||||
import { LessonContent } from './lesson-content';
|
|
||||||
import { LMSTemplate } from './lmstemplate';
|
|
||||||
|
|
||||||
export class Lessons extends BaseObject {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.courseID = 0;
|
|
||||||
this.lessonTitle = "";
|
|
||||||
this.lessonNo = "";
|
|
||||||
this.description = "";
|
|
||||||
this.duration = "";
|
|
||||||
this.difficultyLevel = EnumDifficultyLevel.Beginner;
|
|
||||||
this.isQuizAvailable = false;
|
|
||||||
this.status = EnumStatus.Active;
|
|
||||||
this.lessonContents = [];
|
|
||||||
}
|
|
||||||
courseID: number; // Foreign Key to LMS_Courses
|
|
||||||
lessonTitle: string;
|
|
||||||
lessonNo: string;
|
|
||||||
description: string;
|
|
||||||
duration?: string;
|
|
||||||
difficultyLevel: EnumDifficultyLevel;
|
|
||||||
isQuizAvailable?: boolean;
|
|
||||||
lessonContents : LessonContent[] = [];
|
|
||||||
lessonTemplate : LMSTemplate;
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __extends = (this && this.__extends) || (function () {
|
|
||||||
var extendStatics = function (d, b) {
|
|
||||||
extendStatics = Object.setPrototypeOf ||
|
|
||||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
||||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
||||||
return extendStatics(d, b);
|
|
||||||
};
|
|
||||||
return function (d, b) {
|
|
||||||
if (typeof b !== "function" && b !== null)
|
|
||||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
||||||
extendStatics(d, b);
|
|
||||||
function __() { this.constructor = d; }
|
|
||||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.LMSTemplate = void 0;
|
|
||||||
var baseObject_1 = require("../Basic/baseObject");
|
|
||||||
var LMSTemplate = /** @class */ (function (_super) {
|
|
||||||
__extends(LMSTemplate, _super);
|
|
||||||
function LMSTemplate() {
|
|
||||||
var _this = _super.call(this) || this;
|
|
||||||
_this.templateID = 0;
|
|
||||||
_this.objectID = 0;
|
|
||||||
_this.fileName = "";
|
|
||||||
return _this;
|
|
||||||
}
|
|
||||||
return LMSTemplate;
|
|
||||||
}(baseObject_1.BaseObject));
|
|
||||||
exports.LMSTemplate = LMSTemplate;
|
|
||||||
//# sourceMappingURL=lmstemplate.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"lmstemplate.js","sourceRoot":"","sources":["lmstemplate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AAGjD;IAAiC,+BAAU;IACvC;QACI,YAAA,MAAK,WAAE,SAAC;QACR,KAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,KAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,KAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;;IACvB,CAAC;IAUL,kBAAC;AAAD,CAAC,AAhBD,CAAiC,uBAAU,GAgB1C;AAhBY,kCAAW"}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { EnumTemplateType } from "../enums";
|
|
||||||
|
|
||||||
export class LMSTemplate extends BaseObject {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.templateID = 0;
|
|
||||||
this.objectID = 0;
|
|
||||||
this.fileName = "";
|
|
||||||
}
|
|
||||||
templateID : number;
|
|
||||||
objectID : number;
|
|
||||||
templateType : EnumTemplateType
|
|
||||||
fileName : string;
|
|
||||||
fileData : string ;
|
|
||||||
fileType : number;
|
|
||||||
currentFile: any;
|
|
||||||
fileAsByteArray : string;
|
|
||||||
fileTobase64 : string;
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { EnumReportGroupType } from '../enums';
|
|
||||||
|
|
||||||
export class OpenAIResponseWithData{
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
IsChart: boolean = false;
|
|
||||||
ChartType: string = "";
|
|
||||||
Title: string = "";
|
|
||||||
Labels: string[] = [];
|
|
||||||
Values: number[] = [];;
|
|
||||||
TableData: any;
|
|
||||||
LabelPosition: string = 'outsideEnd';
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { BaseObject } from '../Basic/baseObject';
|
|
||||||
import { EnumAIChartType, EnumReportGroupType } from '../enums';
|
|
||||||
|
|
||||||
export class OpenAIQueryLog extends BaseObject {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
userId : number = 0;
|
|
||||||
userPrompt : string = "";
|
|
||||||
generatedQuery : string = "";
|
|
||||||
executedAt : Date = new Date();
|
|
||||||
totalExecution : number = 0;
|
|
||||||
reportGroup: EnumReportGroupType;
|
|
||||||
isChart : boolean = false;
|
|
||||||
chartType : EnumAIChartType = EnumAIChartType.None;
|
|
||||||
title : string = "";
|
|
||||||
isCommon : boolean = false;
|
|
||||||
}
|
|
||||||
|
|
@ -16,70 +16,11 @@ export enum EnumHrNotificationType {
|
||||||
System_Generated = 2,
|
System_Generated = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum EnumDifficultyLevel {
|
|
||||||
Beginner = 1,
|
|
||||||
Intermediate = 2,
|
|
||||||
Advanced = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EnumContentSource {
|
|
||||||
Youtube = 1,
|
|
||||||
GoogleDrive = 2,
|
|
||||||
OneDrive = 3,
|
|
||||||
AzureBlobStorage = 4,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EnumAccessLevel {
|
|
||||||
Public = 1,
|
|
||||||
Private = 2,
|
|
||||||
Restricted = 3,
|
|
||||||
Premium = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EnumAIChartType
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
BarChart = 1,
|
|
||||||
LineGraph = 2,
|
|
||||||
PieChart = 3,
|
|
||||||
ScatterPlot = 4,
|
|
||||||
AreaChart = 5,
|
|
||||||
Histogram = 6,
|
|
||||||
WaterfallChart = 7,
|
|
||||||
GantChart = 8,
|
|
||||||
RadarChart = 9,
|
|
||||||
ActivityDiagram = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EnumContentType {
|
|
||||||
Video = 1,
|
|
||||||
Image = 2,
|
|
||||||
Pdf = 3,
|
|
||||||
Powerpoint = 4,
|
|
||||||
Excel = 5,
|
|
||||||
Doc = 6,
|
|
||||||
others = 7
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EnumReportGroupType
|
|
||||||
{
|
|
||||||
Employee = 1,
|
|
||||||
Salary = 2,
|
|
||||||
Performance = 3,
|
|
||||||
Training = 4,
|
|
||||||
Leave = 5,
|
|
||||||
Attendance = 6,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum EnumTaxInvestment {
|
export enum EnumTaxInvestment {
|
||||||
Regardless = 0,
|
Regardless = 0,
|
||||||
ESS = 1,
|
ESS = 1,
|
||||||
Admin = 2,
|
Admin = 2,
|
||||||
}
|
}
|
||||||
export enum EnumTemplateType {
|
|
||||||
Course = 1,
|
|
||||||
Lesson = 2,
|
|
||||||
}
|
|
||||||
export enum EnumTaxInvestmentStatus {
|
export enum EnumTaxInvestmentStatus {
|
||||||
Not_Yet_Approve = 0,
|
Not_Yet_Approve = 0,
|
||||||
Approve = 1,
|
Approve = 1,
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
import { EnumReportGroupType } from './../../_models/enums';
|
|
||||||
import {Injectable} from '@angular/core';
|
|
||||||
import {HttpClient, HttpEvent, HttpRequest} from '@angular/common/http';
|
|
||||||
import {ApiService} from '../../app.api.service';
|
|
||||||
import { OpenAIQueryLog } from 'src/app/_models/OpenAIQueryLog/OpenAIQueryLog';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class HRMOpenAIService {
|
|
||||||
constructor(public apiService: ApiService,
|
|
||||||
private http: HttpClient) {
|
|
||||||
}
|
|
||||||
GetAiInformation(userCommand : string) {
|
|
||||||
return this.apiService.httpGet<any>('/HRMApenAPIAI/GetAiInformation/' + userCommand);
|
|
||||||
}
|
|
||||||
AskOpenAI(data: any) {
|
|
||||||
return this.apiService.httpPost<any>('/HRMApenAPIAI/AskOpenAI', data);
|
|
||||||
}
|
|
||||||
GetReportColumnDefinition(reportGroupType : EnumReportGroupType) {
|
|
||||||
return this.apiService.httpGet<any[]>('/HRMApenAPIAI/GetReportColumnDefinition/' + reportGroupType);
|
|
||||||
}
|
|
||||||
GetCurrentUserAllQueryLog(reportGroupType : EnumReportGroupType) {
|
|
||||||
return this.apiService.httpGet<OpenAIQueryLog[]>('/HRMApenAPIAI/GetCurrentUserAllQueryLog/' + reportGroupType);
|
|
||||||
}
|
|
||||||
OpenAIPreviousQueryExecution(data: any) {
|
|
||||||
return this.apiService.httpPost<any>('/HRMApenAPIAI/OpenAIPreviousQueryExecution', data);
|
|
||||||
}
|
|
||||||
ChatShareWithOthers(data: any) {
|
|
||||||
return this.apiService.httpPost('/HRMApenAPIAI/ChatShareWithOthers', data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
import {Injectable} from '@angular/core';
|
|
||||||
import {HttpClient, HttpEvent, HttpRequest} from '@angular/common/http';
|
|
||||||
import {ApiService} from '../../app.api.service';
|
|
||||||
import { CourseType } from 'src/app/_models/LearningManagement/course-type';
|
|
||||||
import { EnumStatus } from 'src/app/_models/enums';
|
|
||||||
import { Courses } from 'src/app/_models/LearningManagement/courses';
|
|
||||||
import { CourseProgress } from 'src/app/_models/LearningManagement/course-progress';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class LMSService {
|
|
||||||
|
|
||||||
constructor(public apiService: ApiService,
|
|
||||||
private http: HttpClient) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Course Type
|
|
||||||
saveCourseType(param: any) {
|
|
||||||
return this.apiService.httpPost<CourseType>('/LMS/saveCourseType', param);
|
|
||||||
}
|
|
||||||
deleteCourseType(id : number) {
|
|
||||||
return this.apiService.httpGet('/LMS/deleteCourseType/' + id);
|
|
||||||
}
|
|
||||||
GetCourseTypeByStatus(status : EnumStatus) {
|
|
||||||
return this.apiService.httpGet<CourseType[]>('/LMS/getByStatus/' + status);
|
|
||||||
}
|
|
||||||
GetAllCourseType() {
|
|
||||||
return this.apiService.httpGet<CourseType[]>('/LMS/getAllCourseType');
|
|
||||||
}
|
|
||||||
getByParentID(parentID : number) {
|
|
||||||
return this.apiService.httpGet<CourseType[]>('/LMS/getAllCourseType/'+parentID);
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Courses
|
|
||||||
saveCourses(param: any) {
|
|
||||||
return this.apiService.httpPost<Courses>('/LMS/saveCourses', param);
|
|
||||||
}
|
|
||||||
deleteCourses(id : number) {
|
|
||||||
return this.apiService.httpGet('/LMS/deleteCourses/' + id);
|
|
||||||
}
|
|
||||||
GetCoursesByStatus(status : EnumStatus) {
|
|
||||||
return this.apiService.httpGet<Courses[]>('/LMS/getCoursesByStatus/' + status);
|
|
||||||
}
|
|
||||||
GetCourse(ID : number) {
|
|
||||||
return this.apiService.httpGet<Courses>('/LMS/getCourse/' + ID);
|
|
||||||
}
|
|
||||||
GetCourseForUser(ID : number) {
|
|
||||||
return this.apiService.httpGet<Courses>('/LMS/GetCourseForUser/' + ID);
|
|
||||||
}
|
|
||||||
GetCourseForEnrollment(ID : number) {
|
|
||||||
return this.apiService.httpGet<Courses>('/LMS/GetCourseForEnrollment/' + ID);
|
|
||||||
}
|
|
||||||
GetAllCourses() {
|
|
||||||
return this.apiService.httpGet<Courses[]>('/LMS/getAllCourses');
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Lessons
|
|
||||||
deleteLessons(id : number) {
|
|
||||||
return this.apiService.httpGet('/LMS/deleteLessons/' + id);
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Lesson Content
|
|
||||||
deleteLessonContent(id : number) {
|
|
||||||
return this.apiService.httpGet('/LMS/deleteLessonContent/' + id);
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region LESSON Progress
|
|
||||||
UserCourseProgress(param: any) {
|
|
||||||
return this.apiService.httpPost<Courses>('/LMS/UserCourseProgress', param);
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
import { Injectable } from '@angular/core';
|
|
||||||
|
|
||||||
@Injectable({
|
|
||||||
providedIn: 'root'
|
|
||||||
})
|
|
||||||
export class PaymentApprovalService {
|
|
||||||
|
|
||||||
constructor() { }
|
|
||||||
}
|
|
||||||
|
|
@ -97,7 +97,6 @@ import {ProgressBarModule} from '@progress/kendo-angular-progressbar';
|
||||||
import {RippleModule} from 'primeng/ripple';
|
import {RippleModule} from 'primeng/ripple';
|
||||||
import {MsalGuard, MsalInterceptor, MsalModule, MsalRedirectComponent, MsalService} from '@azure/msal-angular';
|
import {MsalGuard, MsalInterceptor, MsalModule, MsalRedirectComponent, MsalService} from '@azure/msal-angular';
|
||||||
import {InteractionType, PublicClientApplication} from '@azure/msal-browser';
|
import {InteractionType, PublicClientApplication} from '@azure/msal-browser';
|
||||||
import { HRMOpenAIModule } from './hrmopen-ai/hrmopen-ai.module';
|
|
||||||
|
|
||||||
FullCalendarModule.registerPlugins([
|
FullCalendarModule.registerPlugins([
|
||||||
dayGridPlugin,
|
dayGridPlugin,
|
||||||
|
|
@ -171,7 +170,6 @@ FullCalendarModule.registerPlugins([
|
||||||
CardModule,
|
CardModule,
|
||||||
TabViewModule,
|
TabViewModule,
|
||||||
Pickermodule,
|
Pickermodule,
|
||||||
HRMOpenAIModule,
|
|
||||||
NgxExtendedPdfViewerModule,
|
NgxExtendedPdfViewerModule,
|
||||||
ProgressBarModule,
|
ProgressBarModule,
|
||||||
MsalModule.forRoot(new PublicClientApplication(
|
MsalModule.forRoot(new PublicClientApplication(
|
||||||
|
|
|
||||||
|
|
@ -202,12 +202,7 @@ export const routes: Routes = [
|
||||||
path: 'dataintegration',
|
path: 'dataintegration',
|
||||||
canActivate: [AuthGuard],
|
canActivate: [AuthGuard],
|
||||||
loadChildren: () => import('./data-integration/data-integration.module').then(m => m.DataIntegrationModule)
|
loadChildren: () => import('./data-integration/data-integration.module').then(m => m.DataIntegrationModule)
|
||||||
},
|
}
|
||||||
{
|
|
||||||
path: 'hrm',
|
|
||||||
canActivate: [AuthGuard],
|
|
||||||
loadChildren: () => import('./hrmopen-ai/hrmopen-ai.module').then(m => m.HRMOpenAIModule)
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const AppRoutes: ModuleWithProviders<any> = RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' });
|
export const AppRoutes: ModuleWithProviders<any> = RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' });
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
import { HRMOpenAITestComponent } from './hrmopen-ai-test/hrmopen-aiteast.component';
|
|
||||||
import { AuthGuard } from '../_guards/auth.guard';
|
|
||||||
|
|
||||||
export const routes: Routes = [
|
|
||||||
{ path: 'hrm-ai', component: HRMOpenAITestComponent, canActivate: [AuthGuard] },
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forChild(routes)],
|
|
||||||
exports: [RouterModule]
|
|
||||||
})
|
|
||||||
export class HRMOpenAIRoutingModule { }
|
|
||||||
|
|
@ -1,313 +0,0 @@
|
||||||
<app-loading-panel></app-loading-panel>
|
|
||||||
|
|
||||||
<div class="card shadow-sm rounded p-2" style="background-color: #ffffff; border: 1px solid #d9d9d9;height: 100%;">
|
|
||||||
<div class="card textarea-wrapper" style="position: relative; width: 100%;padding: 5px !important;">
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-col-7">
|
|
||||||
<div class="textarea-wrapper">
|
|
||||||
<textarea (input)="onInputChange()" [(ngModel)]="inputUserCommand" rows="4" class="formAITextArea"
|
|
||||||
placeholder="Ask me anything related to payroll or HR tasks..."></textarea>
|
|
||||||
<button *ngIf="inputUserCommand || filteredSuggestions.length > 0" type="button" class="clear-btn"
|
|
||||||
(click)="clearInput()">✖</button>
|
|
||||||
</div>
|
|
||||||
<ul *ngIf="filteredSuggestions.length > 0" class="suggestions-dropdown">
|
|
||||||
<li *ngFor="let item of filteredSuggestions" (click)="selectSuggestion(item)"
|
|
||||||
class="suggestion-item" [ngClass]="{ 'chart-query': item.isChart }">
|
|
||||||
<span class="suggestion-text">{{ item.userPrompt }}</span>
|
|
||||||
<span *ngIf="item.isChart" class="chart-icon">📊</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="toolbar-container">
|
|
||||||
<div class="toolbar-left">
|
|
||||||
<kendo-dropdownlist [data]="reportGroups"
|
|
||||||
[defaultItem]="{ description: 'Select AI Purpose....', value: null }"
|
|
||||||
[textField]="'description'" [valueField]="'value'" [valuePrimitive]="true"
|
|
||||||
[(ngModel)]="selectedReportGroup" (valueChange)="onReportGroupChange($event)"
|
|
||||||
class="w-14rem">
|
|
||||||
</kendo-dropdownlist>
|
|
||||||
|
|
||||||
<button (click)="openAvailableInfoDialog()"
|
|
||||||
[disabled]="selectedReportGroup === null || selectedReportGroup === undefined" kendoButton
|
|
||||||
themeColor="secondary">
|
|
||||||
Field Column
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="toolbar-right">
|
|
||||||
<button [disabled]="selectedReportGroup === null || selectedReportGroup === undefined"
|
|
||||||
kendoButton themeColor="primary" (click)="ShowAllQueryLog()">
|
|
||||||
Chat History
|
|
||||||
</button>
|
|
||||||
<button kendoButton themeColor="primary" (click)="onCallOpenAI_One()"
|
|
||||||
(keydown.enter)="handleEnterKey($event)">
|
|
||||||
Execute
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="p-col-5">
|
|
||||||
<ul style="padding-left: 16px; margin-top: 5px; margin-bottom: 0px;">
|
|
||||||
<li>
|
|
||||||
This AI-based report generation tool transforms your questions or input text into SQL or machine
|
|
||||||
language to fetch data from the database. Field information is provided to help you understand
|
|
||||||
which data can be accessed.
|
|
||||||
</li>
|
|
||||||
<li class="suggestion-item">
|
|
||||||
The system supports various types of visualizations: <strong>Bar chart</strong>, <strong>Pie
|
|
||||||
chart</strong>, <strong>Line chart</strong>, <strong>Scatter chart</strong> and
|
|
||||||
<strong>Histogram</strong>. To create a chart, include the chart type in your query — for
|
|
||||||
example:
|
|
||||||
<strong>"Generate a bar chart showing employee categories."</strong>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr class="my-2" />
|
|
||||||
<div class="grid">
|
|
||||||
<div class="p-col-12">
|
|
||||||
<ng-container *ngIf="gridData?.length > 0; else noData">
|
|
||||||
<div class="grid-chart-wrapper" [ngClass]="{'show-chart': isShowChart}">
|
|
||||||
<div class="grid-container">
|
|
||||||
<div class="export-toolbar">
|
|
||||||
<div class="total-label">Total: <span class="total-count">{{ gridData.length }}</span></div>
|
|
||||||
<div class="export-buttons">
|
|
||||||
<button [disabled]="isDisabledShared === true" kendoButton themeColor="primary"
|
|
||||||
(click)="ShareThisChat()"
|
|
||||||
style="background: #ff6358 !important;font-weight: bold !important;"
|
|
||||||
[svgIcon]="null">Share</button>
|
|
||||||
<button kendoButton (click)="grid.saveAsExcel()">Export Excel</button>
|
|
||||||
<button kendoButton (click)="grid.saveAsPDF()">Export PDF</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<kendo-grid #grid [kendoGridBinding]="gridData" [scrollable]="'scrollable'" [height]="450"
|
|
||||||
[reorderable]="true" class="shadow-sm border custom-grid">
|
|
||||||
<ng-template kendoGridToolbarTemplate
|
|
||||||
*ngIf="deletedColumns.length > 0 && isShowChart === false">
|
|
||||||
<div class="deleted-columns-container" *ngIf="deletedColumns.length > 0">
|
|
||||||
<span class="toolbar-title">Deleted Columns :</span>
|
|
||||||
<button *ngFor="let col of deletedColumns; let idx = index"
|
|
||||||
[svgIcon]="apiService.KendoSVGIcon['plus']" kendoButton
|
|
||||||
(click)="restoreColumn(idx)" type="button" class="restore-btn">
|
|
||||||
{{ col.title || col.field }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
<kendo-grid-column *ngFor="let col of gridColumns; let i = index" [field]="col.field"
|
|
||||||
[title]="col.title" [width]="150" [orderIndex]="i">
|
|
||||||
<ng-template kendoGridHeaderTemplate>
|
|
||||||
<div class="header-container" [attr.data-col-index]="i">
|
|
||||||
<span *ngIf="!gridColumns[i].editing" class="header-title">{{
|
|
||||||
gridColumns[i].title || gridColumns[i].field }}</span>
|
|
||||||
<input *ngIf="gridColumns[i].editing" [(ngModel)]="gridColumns[i].title"
|
|
||||||
[ngModelOptions]="{ standalone: true }" (blur)="onHeaderBlur(i)" type="text"
|
|
||||||
class="header-input" />
|
|
||||||
<button *ngIf="!gridColumns[i].editing" type="button" class="edit-btn"
|
|
||||||
(click)="startEdit(i); $event.stopPropagation()"
|
|
||||||
title="Edit column title">✎</button>
|
|
||||||
<button *ngIf="!gridColumns[i].editing && isShowChart === false" type="button"
|
|
||||||
class="delete-btn" (click)="deleteColumn(i); $event.stopPropagation()"
|
|
||||||
title="Delete column">✖</button>
|
|
||||||
<button *ngIf="gridColumns[i].editing" type="button" class="save-btn"
|
|
||||||
(click)="saveHeader(i); $event.stopPropagation()" title="Save">✔</button>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
<ng-template kendoGridCellTemplate let-dataItem>
|
|
||||||
<div class="cell-wrap">{{ dataItem[col.field] }}</div>
|
|
||||||
</ng-template>
|
|
||||||
</kendo-grid-column>
|
|
||||||
<kendo-grid-excel [fileName]="excelFileName"></kendo-grid-excel>
|
|
||||||
<kendo-grid-pdf [fileName]="pdfFileName" paperSize="A4"></kendo-grid-pdf>
|
|
||||||
</kendo-grid>
|
|
||||||
</div>
|
|
||||||
<div class="chart-container" *ngIf="isShowChart">
|
|
||||||
<div class="export-toolbar justify-end">
|
|
||||||
<div class="export-buttons">
|
|
||||||
<button kendoButton (click)="exportSizedChart(chart)">Export PDF</button>
|
|
||||||
<button kendoButton (click)="exportChartImage(chart)"> Export PNG</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div style="width: 100%;overflow: auto;">
|
|
||||||
<kendo-chart #chart [transitions]="chartTransitions"
|
|
||||||
style="height: 450px !important; width: 100% !important;"
|
|
||||||
*ngIf="openAIResponseWithData.IsChart && openAIResponseWithData.ChartType !== 'scatter' && openAIResponseWithData.ChartType !== 'histogram'"
|
|
||||||
class="h-full w-full">
|
|
||||||
<kendo-chart-title [text]="openAIResponseWithData.Title"
|
|
||||||
align="center"></kendo-chart-title>
|
|
||||||
<kendo-chart-legend
|
|
||||||
[position]="openAIResponseWithData.ChartType === 'pie' ? gridData.length > 25 ? 'bottom' : 'right' : 'bottom'"></kendo-chart-legend>
|
|
||||||
<kendo-chart-category-axis>
|
|
||||||
<kendo-chart-category-axis-item [categories]="chartCategories">
|
|
||||||
</kendo-chart-category-axis-item>
|
|
||||||
</kendo-chart-category-axis>
|
|
||||||
<kendo-chart-value-axis>
|
|
||||||
<kendo-chart-value-axis-item>
|
|
||||||
<kendo-chart-value-axis-item-labels
|
|
||||||
[format]="'{0}'"></kendo-chart-value-axis-item-labels>
|
|
||||||
</kendo-chart-value-axis-item>
|
|
||||||
</kendo-chart-value-axis>
|
|
||||||
<kendo-chart-series>
|
|
||||||
<kendo-chart-series-item [type]="openAIResponseWithData.ChartType"
|
|
||||||
[data]="chartData" field="value" categoryField="category"
|
|
||||||
[labels]="{ visible: true, position: openAIResponseWithData.LabelPosition }"
|
|
||||||
[line]="{ style: 'smooth' }" [opacity]="0.7">
|
|
||||||
</kendo-chart-series-item>
|
|
||||||
</kendo-chart-series>
|
|
||||||
</kendo-chart>
|
|
||||||
<kendo-chart #chart [transitions]="chartTransitions"
|
|
||||||
style="height: 450px !important; width: 100% !important;"
|
|
||||||
*ngIf="openAIResponseWithData.IsChart && openAIResponseWithData.ChartType === 'scatter'"
|
|
||||||
class="h-full w-full">
|
|
||||||
<kendo-chart-title [text]="openAIResponseWithData.Title"></kendo-chart-title>
|
|
||||||
<kendo-chart-legend position="bottom"></kendo-chart-legend>
|
|
||||||
<kendo-chart-x-axis>
|
|
||||||
<kendo-chart-x-axis-item title="X Axis"></kendo-chart-x-axis-item>
|
|
||||||
</kendo-chart-x-axis>
|
|
||||||
<kendo-chart-y-axis>
|
|
||||||
<kendo-chart-y-axis-item title="Y Axis">
|
|
||||||
<kendo-chart-y-axis-item-labels
|
|
||||||
[format]="'{0}'"></kendo-chart-y-axis-item-labels>
|
|
||||||
</kendo-chart-y-axis-item>
|
|
||||||
</kendo-chart-y-axis>
|
|
||||||
<kendo-chart-series>
|
|
||||||
<kendo-chart-series-item type="scatter" [data]="chartData" xField="x" yField="y"
|
|
||||||
[labels]="{
|
|
||||||
visible: true,
|
|
||||||
content: scatterLabelContent
|
|
||||||
}">
|
|
||||||
</kendo-chart-series-item>
|
|
||||||
</kendo-chart-series>
|
|
||||||
</kendo-chart>
|
|
||||||
<kendo-chart #chart [transitions]="chartTransitions"
|
|
||||||
style="height: 450px !important; width: 100% !important;"
|
|
||||||
*ngIf="openAIResponseWithData.IsChart && openAIResponseWithData.ChartType === 'histogram'"
|
|
||||||
class="h-full w-full">
|
|
||||||
<kendo-chart-title text="Histogram Example"></kendo-chart-title>
|
|
||||||
<kendo-chart-legend position="bottom"></kendo-chart-legend>
|
|
||||||
<kendo-chart-category-axis>
|
|
||||||
<kendo-chart-category-axis-item
|
|
||||||
[title]="{ text: 'Value' }"></kendo-chart-category-axis-item>
|
|
||||||
</kendo-chart-category-axis>
|
|
||||||
<kendo-chart-value-axis>
|
|
||||||
<kendo-chart-value-axis-item>
|
|
||||||
<kendo-chart-value-axis-item-labels
|
|
||||||
format="{0}"></kendo-chart-value-axis-item-labels>
|
|
||||||
</kendo-chart-value-axis-item>
|
|
||||||
</kendo-chart-value-axis>
|
|
||||||
<kendo-chart-series>
|
|
||||||
<kendo-chart-series-item *ngFor="let item of histogramSeries" [type]="item.type"
|
|
||||||
[data]="item.data" [labels]="{ visible: true }">
|
|
||||||
</kendo-chart-series-item>
|
|
||||||
</kendo-chart-series>
|
|
||||||
</kendo-chart>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
<ng-template #noData>
|
|
||||||
<div class="ai-error-message" *ngIf="invalidQueryMessage" [@fadeInOut]="messageState">{{
|
|
||||||
invalidQueryMessage }}</div>
|
|
||||||
<div class="ai-guidance-card" *ngIf="isUserPromptIsNotRelated" [@fadeInOut]="messageState">
|
|
||||||
<h4 class="ai-guidance-title">⚠️ Let’s stay focused on this section</h4>
|
|
||||||
<p class="ai-guidance-text">
|
|
||||||
Your query isn’t related to the selected purpose. Please ask only about this section using the
|
|
||||||
listed fields as a guide.
|
|
||||||
💡 You can also click the <strong>Chat History</strong> button to review your previous queries.
|
|
||||||
</p>
|
|
||||||
<div *ngFor="let section of tableColumnDefinition" class="ai-section">
|
|
||||||
<p class="ai-section-title">{{ section.tableName }}</p>
|
|
||||||
<div class="ai-field-badges">
|
|
||||||
<span *ngFor="let field of section.fields" class="badge">{{ field }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="ai-tip">💡 Use the above fields to guide your AI query. The more specific you are, the
|
|
||||||
better the result will be.</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<kendo-dialog *ngIf="isShowAvailableInfo" (close)="isShowAvailableInfo = false" title="Available Information"
|
|
||||||
[maxHeight]="600" [width]="500">
|
|
||||||
<div *ngFor="let section of tableColumnDefinition">
|
|
||||||
<p style="margin-bottom: 0px !important;"><strong>{{ section.tableName }}</strong></p>
|
|
||||||
<ul style="margin-top: 0px !important;">
|
|
||||||
<li>{{ section.fields.join(', ') }}</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="centered-info">
|
|
||||||
Use the above fields to guide your AI query. The more specific you are, the better the result will be.
|
|
||||||
</p>
|
|
||||||
<kendo-dialog-actions>
|
|
||||||
<button kendoButton themeColor="primary" (click)="isShowAvailableInfo = false">Close</button>
|
|
||||||
</kendo-dialog-actions>
|
|
||||||
</kendo-dialog>
|
|
||||||
<kendo-dialog *ngIf="isShowCurrentUserAllQueryLog" (close)="isShowCurrentUserAllQueryLog = false" title="Chat History"
|
|
||||||
[maxHeight]="700" [height]="700" [width]="500">
|
|
||||||
<div class="history-wrapper">
|
|
||||||
<div class="search-box">
|
|
||||||
<textarea kendoTextArea [(ngModel)]="querySearchText" rows="2" placeholder="Search your chat history..."
|
|
||||||
style="width:100%; border-radius:8px; padding:8px; font-size:14px;border-color: #52527A;">
|
|
||||||
</textarea>
|
|
||||||
</div>
|
|
||||||
<div class="query-card-container scrollable">
|
|
||||||
<div class="query-card" *ngFor="let item of filteredQueryLog()" [ngClass]="{ 'chart-query': item.isChart }"
|
|
||||||
(mouseenter)="item.hover = true" (mouseleave)="item.hover = false"
|
|
||||||
(click)="OpenAIPreviousQueryExecution(item.id)">
|
|
||||||
<div class="query-card-content">
|
|
||||||
<div class="query-text">{{ item.userPrompt }}</div>
|
|
||||||
<div *ngIf="item.isChart" class="chart-icon">📊</div>
|
|
||||||
<i *ngIf="!item.isCommon" class="pi pi-share-alt"
|
|
||||||
(click)="ShareThisChatWithOthers(item); $event.stopPropagation()" style="margin-left: 5px;"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</kendo-dialog>
|
|
||||||
<kendo-dialog *ngIf="isShowChartOption" (close)="isShowChartOption = false" title="Charts" [maxHeight]="500"
|
|
||||||
[width]="500">
|
|
||||||
<div class="p-grid">
|
|
||||||
<div class="p-col-3"><label for="">Graph Name</label></div>
|
|
||||||
<div class="p-col-9">
|
|
||||||
<kendo-dropdownlist [data]="chartGroups" [defaultItem]="{ description: 'Select a Chart....', value: null }"
|
|
||||||
[textField]="'description'" [valueField]="'value'" [valuePrimitive]="true"
|
|
||||||
[(ngModel)]="selectedChartGroup" (valueChange)="onChartGroupChange($event)" style="width: 100%;">
|
|
||||||
</kendo-dropdownlist>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-3"><label for="">Column X</label></div>
|
|
||||||
<div class="p-col-9">
|
|
||||||
<kendo-dropdownlist [data]="gridColumns" [defaultItem]="{ description: 'X...', value: null }"
|
|
||||||
[textField]="'description'" [valueField]="'value'" [valuePrimitive]="true" [(ngModel)]="selectedColumnX"
|
|
||||||
(valueChange)="onChartGroupChange($event)" style="width: 100%;">
|
|
||||||
</kendo-dropdownlist>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-3"><label for="">Column Y</label></div>
|
|
||||||
<div class="p-col-9">
|
|
||||||
<kendo-dropdownlist [data]="gridColumns" [defaultItem]="{ description: 'Y...', value: null }"
|
|
||||||
[textField]="'description'" [valueField]="'value'" [valuePrimitive]="true" [(ngModel)]="selectedColumnY"
|
|
||||||
(valueChange)="onChartGroupChange($event)" style="width: 100%;">
|
|
||||||
</kendo-dropdownlist>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-3"><label for="">Merge</label></div>
|
|
||||||
<div class="p-col-9">
|
|
||||||
<input [(ngModel)]="chartMerge" type="text" style="width:100%" pInputText readonly>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-3"><label for="">Name</label></div>
|
|
||||||
<div class="p-col-9">
|
|
||||||
<input [(ngModel)]="chartName" type="text" style="width:100%" pInputText readonly>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="p-col-12" align="right">
|
|
||||||
<button kendoButton themeColor="primary" [svgIcon]="apiService.KendoSVGIcon['eye']">Plot</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</kendo-dialog>
|
|
||||||
|
|
@ -1,458 +0,0 @@
|
||||||
.textarea-wrapper {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea.formAITextArea {
|
|
||||||
font-size: 1rem;
|
|
||||||
padding: 0.75rem 2.5rem 0.75rem 0.75rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
resize: none;
|
|
||||||
width: 100%;
|
|
||||||
height: 78%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clear-btn {
|
|
||||||
position: absolute;
|
|
||||||
right: 10px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
background: transparent;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
color: #888;
|
|
||||||
z-index: 10;
|
|
||||||
padding: 0;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.clear-btn:hover {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
.p-button-rounded {
|
|
||||||
width: 2.5rem;
|
|
||||||
height: 2.5rem;
|
|
||||||
}
|
|
||||||
.centered-info {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 12px;
|
|
||||||
color: red;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.userPrompt{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.userPrompt :hover{
|
|
||||||
color: #414278;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.query-card-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
.query-card {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
padding: 4px 16px;
|
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
border: 1px solid #cfcfcf;
|
|
||||||
}
|
|
||||||
.query-card:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
|
|
||||||
}
|
|
||||||
.query-card-content {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.query-text {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 1.4;
|
|
||||||
max-height: calc(1.4em * 2);
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
|
||||||
.query-arrow {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #52527A;
|
|
||||||
padding-left: 10px;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.query-arrow:hover {
|
|
||||||
color: #33334e;
|
|
||||||
}
|
|
||||||
.query-date {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #777;
|
|
||||||
text-align: right;
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
.chart-icon {
|
|
||||||
margin-left: 8px;
|
|
||||||
color: #52527A;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.chart-query {
|
|
||||||
background: #e6f7ff;
|
|
||||||
}
|
|
||||||
.search-box textarea {
|
|
||||||
resize: none;
|
|
||||||
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
||||||
border: 1px solid #cfcfcf;
|
|
||||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
|
||||||
}
|
|
||||||
.search-box textarea:focus {
|
|
||||||
border-color: #52527A;
|
|
||||||
box-shadow: 0 0 5px rgba(82,82,122,0.5);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
.history-wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.search-box {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.scrollable {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
overflow-y: auto;
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
.scrollable::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
}
|
|
||||||
.scrollable::-webkit-scrollbar-track {
|
|
||||||
background: #f5f5f5;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
.scrollable::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #d6d6d6;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 2px solid #f5f5f5;
|
|
||||||
}
|
|
||||||
.scrollable::-webkit-scrollbar-thumb:hover {
|
|
||||||
background-color: #bfbfbf;
|
|
||||||
}
|
|
||||||
.suggestions-dropdown {
|
|
||||||
position: absolute;
|
|
||||||
background: rgba(255, 255, 255, 0.85); /* semi-transparent */
|
|
||||||
backdrop-filter: blur(4px); /* blur effect */
|
|
||||||
border: 1px solid #cfcfcf;
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 2px 6px rgba(0,0,0,0.15);
|
|
||||||
max-height: 350px;
|
|
||||||
overflow-y: auto;
|
|
||||||
width: 500px;
|
|
||||||
z-index: 1000;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
.suggestions-dropdown li {
|
|
||||||
padding: 6px 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
border-bottom: 1px solid #d1d1d1;
|
|
||||||
}
|
|
||||||
.suggestions-dropdown li:hover {
|
|
||||||
background: #f0f0f0;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
.suggestions-dropdown .chart-icon {
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
.textarea-wrapper {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.formAITextArea {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.75rem 2rem 0.75rem 0.75rem;
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
resize: none;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
suggestions-dropdown li.suggestion-item {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 6px 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.suggestions-dropdown li.suggestion-item:hover {
|
|
||||||
background: #f0f0f0;
|
|
||||||
}
|
|
||||||
.suggestions-dropdown .chart-icon {
|
|
||||||
margin-left: 8px;
|
|
||||||
float: right;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #52527A;
|
|
||||||
}
|
|
||||||
.grid-chart-wrapper {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
.grid-chart-wrapper.show-chart .grid-container {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
.grid-chart-wrapper.show-chart .chart-container {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
.grid-chart-wrapper:not(.show-chart) .grid-container {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.chart-container {
|
|
||||||
height: 520px;
|
|
||||||
}
|
|
||||||
.export-buttons {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 5px;
|
|
||||||
padding: 3px;
|
|
||||||
}
|
|
||||||
.ai-error-message {
|
|
||||||
text-align: center;
|
|
||||||
background: #fee2e2;
|
|
||||||
color: #991b1b;
|
|
||||||
border: 1px solid #fecaca;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 10px 15px;
|
|
||||||
margin: 10px auto;
|
|
||||||
max-width: 80%;
|
|
||||||
font-weight: 500;
|
|
||||||
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
|
|
||||||
}
|
|
||||||
.ai-guidance-card {
|
|
||||||
background: #f9fafb;
|
|
||||||
border: 1px solid #e5e7eb;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 20px;
|
|
||||||
margin: auto;
|
|
||||||
max-width: 80%;
|
|
||||||
box-shadow: 0 4px 12px rgba(0,0,0,0.06);
|
|
||||||
}
|
|
||||||
.ai-guidance-title {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #111827;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.ai-guidance-text {
|
|
||||||
color: #374151;
|
|
||||||
font-size: 0.95rem;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.ai-section {
|
|
||||||
margin-bottom: 12px;
|
|
||||||
}
|
|
||||||
.ai-section-title {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #1e40af;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
.ai-field-list {
|
|
||||||
margin: 0;
|
|
||||||
padding-left: 15px;
|
|
||||||
color: #1e3a8a;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
.ai-field-list li {
|
|
||||||
margin: 3px 0;
|
|
||||||
}
|
|
||||||
.ai-tip {
|
|
||||||
margin-top: 15px;
|
|
||||||
background: #e0f2fe;
|
|
||||||
color: #0369a1;
|
|
||||||
padding: 8px 12px;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.ai-field-badges {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
.badge {
|
|
||||||
background: #f1f3f5;
|
|
||||||
padding: 4px 10px;
|
|
||||||
border-radius: 12px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #495057;
|
|
||||||
}
|
|
||||||
.export-toolbar {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
border: 1px solid #dee2e6;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
.total-label {
|
|
||||||
font-weight: bold;
|
|
||||||
color: red;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
.total-count {
|
|
||||||
color: #000;
|
|
||||||
margin-left: 4px;
|
|
||||||
|
|
||||||
}
|
|
||||||
.export-toolbar.justify-end {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
.export-buttons .k-button-md {
|
|
||||||
padding-block: 2px !important;
|
|
||||||
padding-inline: 2px !important;
|
|
||||||
}
|
|
||||||
.custom-grid .cell-wrap {
|
|
||||||
min-width: 150px;
|
|
||||||
white-space: normal;
|
|
||||||
word-wrap: break-word;
|
|
||||||
overflow-wrap: anywhere;
|
|
||||||
}
|
|
||||||
.custom-grid .k-grid-content {
|
|
||||||
overflow-x: auto !important;
|
|
||||||
}
|
|
||||||
.header-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 2px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.header-title {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
min-width: 0;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
padding: 3px 3px;
|
|
||||||
}
|
|
||||||
.header-input {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
min-width: 0;
|
|
||||||
padding: 3px 3px;
|
|
||||||
background: #ffffff;
|
|
||||||
border: 1px solid #b5b5b5;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
.header-input:focus {
|
|
||||||
outline: 1px solid #b6d6f7;
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
.edit-btn, .save-btn {
|
|
||||||
flex: 0 0 20px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.save-btn {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
::ng-deep .grid-chart-wrapper .k-grid .k-cell-inner>.k-link {
|
|
||||||
padding: 4px 4px !important;
|
|
||||||
}
|
|
||||||
::ng-deep .k-toolbar {
|
|
||||||
padding: 4px 7px 1px 7px !important;
|
|
||||||
}
|
|
||||||
.delete-btn {
|
|
||||||
color: red;
|
|
||||||
flex: 0 0 20px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.edit-btn:hover, .save-btn:hover, .delete-btn:hover {
|
|
||||||
background: rgba(0,0,0,0.04);
|
|
||||||
}
|
|
||||||
.toolbar-title {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.deleted-columns-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0px;
|
|
||||||
max-width: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
white-space: nowrap;
|
|
||||||
padding: 0px 0px 3px 0px;
|
|
||||||
}
|
|
||||||
.restore-btn {
|
|
||||||
flex: 0 0 auto;
|
|
||||||
margin-left: 4px;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border: 1px solid #6263a0;
|
|
||||||
border-radius: 4px;
|
|
||||||
background: #e3f2fd;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #495057;
|
|
||||||
}
|
|
||||||
.deleted-columns-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-left,
|
|
||||||
.toolbar-right {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-left {
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-right {
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.toolbar-container {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-left,
|
|
||||||
.toolbar-right {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,572 +0,0 @@
|
||||||
|
|
||||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
|
||||||
import { ApiService } from 'src/app/app.api.service';
|
|
||||||
import { DataTransferService } from 'src/app/data.transfer.service';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { SearchEmployee } from 'src/app/_models/Employee/searchEmployee';
|
|
||||||
import { HRMNotificationService } from 'src/app/app.notification.service';
|
|
||||||
import { loadingPanelService } from 'src/app/hrm-loding panel/loding.panel.service';
|
|
||||||
import { Courses } from 'src/app/_models/LearningManagement/courses';
|
|
||||||
import { Lessons } from 'src/app/_models/LearningManagement/lessons';
|
|
||||||
import { LessonContent } from 'src/app/_models/LearningManagement/lesson-content';
|
|
||||||
import { LMSService } from 'src/app/_services/LearningManagement/lms.service';
|
|
||||||
import { EnumAccessLevel, EnumAIChartType, EnumContentType, EnumDifficultyLevel, EnumFileType, EnumReportGroupType, EnumStatus, EnumTemplateType } from 'src/app/_models/enums';
|
|
||||||
import { CourseType } from 'src/app/_models/LearningManagement/course-type';
|
|
||||||
import { LMSTemplate } from 'src/app/_models/LearningManagement/lmstemplate';
|
|
||||||
import { HRMOpenAIService } from 'src/app/_services/HRMOpenAI/hrmopen-ai.service';
|
|
||||||
import { OpenAIQueryLog } from 'src/app/_models/OpenAIQueryLog/OpenAIQueryLog';
|
|
||||||
import { OpenAIResponseWithData } from 'src/app/_models/OpenAI BO/OpenAIResponseWithData';
|
|
||||||
import { Pipe, PipeTransform } from '@angular/core';
|
|
||||||
import { HostListener } from '@angular/core';
|
|
||||||
import { saveAs } from "@progress/kendo-file-saver";
|
|
||||||
import { ChartComponent } from "@progress/kendo-angular-charts";
|
|
||||||
import { exportPDF, fit, geometry, Group } from "@progress/kendo-drawing";
|
|
||||||
function mm(val: number): number {return val * 2.8347;}
|
|
||||||
const PAGE_RECT = new geometry.Rect([0, 0], [mm(210 - 20), mm(297 - 20)]);
|
|
||||||
import { trigger, state, style, animate, transition } from '@angular/animations';
|
|
||||||
@Component({
|
|
||||||
selector: 'app-hrmopen-aiteast',
|
|
||||||
templateUrl: './hrmopen-aiteast.component.html',
|
|
||||||
styleUrls: ['./hrmopen-aiteast.component.scss'],
|
|
||||||
//standalone: false,
|
|
||||||
animations: [
|
|
||||||
trigger('fadeInOut', [
|
|
||||||
transition('* => changed', [
|
|
||||||
style({ opacity: 0 }),
|
|
||||||
animate('500ms ease-in', style({ opacity: 1 }))
|
|
||||||
])
|
|
||||||
])
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export class HRMOpenAITestComponent implements OnInit{
|
|
||||||
|
|
||||||
constructor(public apiService : ApiService,
|
|
||||||
public notificationService: HRMNotificationService,
|
|
||||||
public loadingpanelService: loadingPanelService, public opeAiService : HRMOpenAIService) {
|
|
||||||
this.apiService.selectedMenuName = "HRM AI";
|
|
||||||
}
|
|
||||||
|
|
||||||
inputUserCommand : string = "";
|
|
||||||
public gridData: any[] = []; // data for the grid
|
|
||||||
public gridColumns: any[] = [];
|
|
||||||
public gridColumnsForChart: any[] = []; // columns for dynamic grid
|
|
||||||
public output: any = "";
|
|
||||||
public reportGroups : any[] = [];
|
|
||||||
public chartGroups : any[] = [];
|
|
||||||
public reportColumnDefinition: any[] = [];
|
|
||||||
public tableColumnDefinition: ReportColumnDefinition[] = [];
|
|
||||||
public selectedReportGroup: EnumReportGroupType | null;
|
|
||||||
public selectedChartGroup: EnumReportGroupType | null;
|
|
||||||
public isShowAvailableInfo: boolean = false;
|
|
||||||
public isShowCurrentUserAllQueryLog: boolean = false;
|
|
||||||
public invalidQueryMessage : string = "The AI can provide information when you ask about HR.";
|
|
||||||
public currentUserAllQueryLog : OpenAIQueryLog[] = [];
|
|
||||||
public filteredSuggestions: OpenAIQueryLog[] = [];
|
|
||||||
public OpenAIResponce: any = {};
|
|
||||||
public openAIResponseWithData: OpenAIResponseWithData = new OpenAIResponseWithData();
|
|
||||||
public chartData: any[] = [];
|
|
||||||
public isShowChart: boolean = false;
|
|
||||||
public isShowChartOption: boolean = false;
|
|
||||||
public chartMerge : string = "";
|
|
||||||
public chartName : string = "";
|
|
||||||
public selectedColumnX : any;
|
|
||||||
public selectedColumnY : any;
|
|
||||||
public searchText: string = "";
|
|
||||||
public querySearchText: string = "";
|
|
||||||
public excelFileName: string = "OpenAIQueryLog.xlsx";
|
|
||||||
public pdfFileName: string = "OpenAIQueryLog.pdf";
|
|
||||||
public pdfFileNameForChart: string = "OpenAIQueryLog.pdf";
|
|
||||||
public pngFilename: string = "OpenAIQueryLog.png";
|
|
||||||
public chartTransitions = false;
|
|
||||||
public isUserPromptIsNotRelated = false;
|
|
||||||
public messageState: string = '';
|
|
||||||
public isDisabledShared : boolean = true;
|
|
||||||
public currentChat : OpenAIQueryLog | undefined;
|
|
||||||
public deletedColumns: any[] = [];
|
|
||||||
|
|
||||||
@ViewChild('deletedContainer', { static: false }) deletedContainer!: ElementRef;
|
|
||||||
@ViewChild("chart")
|
|
||||||
private chart: ChartComponent;
|
|
||||||
private setInvalidQueryMessage(msg: string) {
|
|
||||||
this.invalidQueryMessage = msg;
|
|
||||||
this.messageState = "changed";
|
|
||||||
setTimeout(() => (this.messageState = ""), 500);
|
|
||||||
}
|
|
||||||
ngOnInit(){
|
|
||||||
this.deletedColumns = [];
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
this.currentChat = undefined;
|
|
||||||
this.invalidQueryMessage = "The AI can provide information when you ask about HR."
|
|
||||||
this.reportGroups = [
|
|
||||||
{description : "Employee", value : EnumReportGroupType.Employee},
|
|
||||||
{description : "Leave", value : EnumReportGroupType.Leave},
|
|
||||||
{description : "Attendance", value : EnumReportGroupType.Attendance},
|
|
||||||
{description : "Salary", value : EnumReportGroupType.Salary},
|
|
||||||
{description : "Performance", value : EnumReportGroupType.Performance},
|
|
||||||
{description : "Training", value : EnumReportGroupType.Training},
|
|
||||||
];
|
|
||||||
this.chartGroups = [
|
|
||||||
{description : "Bar Chart", value : EnumAIChartType.BarChart},
|
|
||||||
{description : "Line Graph", value : EnumAIChartType.LineGraph},
|
|
||||||
{description : "Pie Chart", value : EnumAIChartType.PieChart},
|
|
||||||
{description : "Scatter Plot", value : EnumAIChartType.ScatterPlot},
|
|
||||||
{description : "Area Chart", value : EnumAIChartType.AreaChart},
|
|
||||||
{description : "Histogram", value : EnumAIChartType.Histogram},
|
|
||||||
{description : "Waterfall Chart", value : EnumAIChartType.WaterfallChart},
|
|
||||||
{description : "Gant Chart", value : EnumAIChartType.GantChart},
|
|
||||||
{description : "Radar Chart", value : EnumAIChartType.RadarChart},
|
|
||||||
{description : "Activity Diagram", value : EnumAIChartType.ActivityDiagram},
|
|
||||||
];
|
|
||||||
this.selectedReportGroup = EnumReportGroupType.Employee
|
|
||||||
this.onReportGroupChange(this.selectedReportGroup);
|
|
||||||
|
|
||||||
}
|
|
||||||
LoadCurrentUserAllQueryLog(reportGroupType : EnumReportGroupType){
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = true;
|
|
||||||
this.opeAiService.GetCurrentUserAllQueryLog(reportGroupType).subscribe(
|
|
||||||
(resp: any) => {
|
|
||||||
this.currentUserAllQueryLog = resp;
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.notificationService.showError(err.error, "Error");
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.currentChat = undefined;
|
|
||||||
if(this.currentUserAllQueryLog && this.currentUserAllQueryLog.length > 0){
|
|
||||||
if(this.inputUserCommand !== ""){
|
|
||||||
let queryLog : OpenAIQueryLog = this.currentUserAllQueryLog.find(x => x.userPrompt.toLowerCase() === this.inputUserCommand.toLowerCase()) ?? undefined;
|
|
||||||
if(queryLog != undefined){
|
|
||||||
if(queryLog.isCommon === false){
|
|
||||||
this.currentChat = queryLog;
|
|
||||||
this.isDisabledShared = false;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.isDisabledShared = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.isDisabledShared = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.isDisabledShared = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
ShowAllQueryLog(){
|
|
||||||
this.querySearchText = "";
|
|
||||||
this.isShowCurrentUserAllQueryLog = true;
|
|
||||||
this.LoadCurrentUserAllQueryLog(this.selectedReportGroup);
|
|
||||||
}
|
|
||||||
onInputChange() {
|
|
||||||
const text = this.inputUserCommand?.toLowerCase().trim() || '';
|
|
||||||
if (!text) {this.filteredSuggestions = [];return;}
|
|
||||||
this.filteredSuggestions = this.currentUserAllQueryLog
|
|
||||||
.filter(item => item.userPrompt.toLowerCase().startsWith(text))
|
|
||||||
.slice(0, 10);
|
|
||||||
}
|
|
||||||
closeSuggestions() {
|
|
||||||
this.filteredSuggestions = [];
|
|
||||||
}
|
|
||||||
clearInput() {
|
|
||||||
this.inputUserCommand = '';
|
|
||||||
this.filteredSuggestions = [];
|
|
||||||
this.gridData = this.gridColumns = [];
|
|
||||||
this.OpenAIResponce = {};
|
|
||||||
this.currentChat = undefined;
|
|
||||||
this.isDisabledShared = true;
|
|
||||||
}
|
|
||||||
@HostListener('document:click', ['$event'])
|
|
||||||
handleClickOutside(event: MouseEvent) {
|
|
||||||
const target = event.target as HTMLElement;
|
|
||||||
if (!target.closest('.suggestion-wrapper')) {
|
|
||||||
this.closeSuggestions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selectSuggestion(item: OpenAIQueryLog) {
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
this.invalidQueryMessage = "No data returned from AI."
|
|
||||||
this.inputUserCommand = item.userPrompt;
|
|
||||||
this.filteredSuggestions = [];
|
|
||||||
this.OpenAIPreviousQueryExecution(item.id); // or any other action
|
|
||||||
}
|
|
||||||
handleEnterKey(event: KeyboardEvent): void {
|
|
||||||
event.preventDefault();
|
|
||||||
if (this.inputUserCommand?.trim()) {
|
|
||||||
this.onCallOpenAI_One();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onCallOpenAI_One(){
|
|
||||||
this.deletedColumns = [];
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
this.currentChat = undefined;
|
|
||||||
this.invalidQueryMessage = "No data returned from AI."
|
|
||||||
if(this.selectedReportGroup && this.inputUserCommand && this.inputUserCommand !== "" &&
|
|
||||||
(this.selectedReportGroup === EnumReportGroupType.Employee || this.selectedReportGroup === EnumReportGroupType.Salary
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Performance || this.selectedReportGroup === EnumReportGroupType.Training
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Leave || this.selectedReportGroup === EnumReportGroupType.Attendance)){
|
|
||||||
const data = {userPrompt: this.inputUserCommand,reportGroup: this.selectedReportGroup}
|
|
||||||
this.gridData = this.gridColumns = [];
|
|
||||||
this.OpenAIResponce = {};
|
|
||||||
this.isShowChart = false;
|
|
||||||
if(this.CheckUserPromptFromPreviousQueryLog(this.inputUserCommand)){
|
|
||||||
let OpenAIQueryLog: OpenAIQueryLog = this.currentUserAllQueryLog.find(x => x.userPrompt.toLowerCase() === this.inputUserCommand.toLowerCase()) ?? undefined;
|
|
||||||
if(OpenAIQueryLog != undefined){
|
|
||||||
this.OpenAIPreviousQueryExecution(OpenAIQueryLog.id);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = true;
|
|
||||||
this.opeAiService.AskOpenAI(data).subscribe(
|
|
||||||
(resp: any) => {
|
|
||||||
this.OpenAIResponce = JSON.parse(resp);
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
if (err.error && (err.error as string).includes("Sorry, I can only help with retrieving data. I am not allowed to update or delete any records.")) {
|
|
||||||
this.setInvalidQueryMessage("Sorry, I can only help with retrieving data. I am not allowed to update or delete any records.");
|
|
||||||
}
|
|
||||||
else if (err.error && (err.error as string).includes("I can only help with questions related to")) {
|
|
||||||
this.showOutOfScopeNotice();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.notificationService.showError(err.error, "Error");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.ProcessOpenAIData();
|
|
||||||
this.LoadCurrentUserAllQueryLog(this.selectedReportGroup);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CheckUserPromptFromPreviousQueryLog(userPrompt: string): boolean {
|
|
||||||
return this.currentUserAllQueryLog.some(item => item.userPrompt.toLowerCase() === userPrompt.toLowerCase());
|
|
||||||
}
|
|
||||||
get chartCategories(): string[] {
|
|
||||||
if (!this.chartData) return [];
|
|
||||||
return this.chartData.map(d => d.category);
|
|
||||||
}
|
|
||||||
public scatterLabelContent(e: any): string {
|
|
||||||
return `(${e.dataItem.x}, ${e.dataItem.y})`;
|
|
||||||
}
|
|
||||||
ProcessOpenAIData() {
|
|
||||||
this.deletedColumns = [];
|
|
||||||
if (!this.OpenAIResponce) {
|
|
||||||
this.invalidQueryMessage = "No data returned from AI.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.openAIResponseWithData = this.OpenAIResponce as OpenAIResponseWithData;
|
|
||||||
if (!this.openAIResponseWithData) { return; }
|
|
||||||
// --- CHART handling (kept mostly same as your original logic) ---
|
|
||||||
if (this.openAIResponseWithData.IsChart && this.openAIResponseWithData.ChartType && this.openAIResponseWithData.ChartType !== "") {
|
|
||||||
if (this.openAIResponseWithData.ChartType === 'line' || this.openAIResponseWithData.ChartType === 'area') {
|
|
||||||
this.openAIResponseWithData.LabelPosition = 'above';
|
|
||||||
} else {
|
|
||||||
this.openAIResponseWithData.LabelPosition = 'outsideEnd';
|
|
||||||
}
|
|
||||||
this.isShowChart = true;
|
|
||||||
this.chartData = [];
|
|
||||||
if (this.openAIResponseWithData.ChartType === 'scatter') {
|
|
||||||
this.chartData = this.openAIResponseWithData.Labels.map((label, index) => ({
|
|
||||||
x: label,
|
|
||||||
y: this.openAIResponseWithData.Values[index]
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
this.chartData = this.openAIResponseWithData.Labels.map((label, index) => ({
|
|
||||||
category: label,
|
|
||||||
value: this.openAIResponseWithData.Values[index]
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// --- TABLE parsing and normalization ---
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(this.openAIResponseWithData.TableData);
|
|
||||||
let allRows: any[] = [];
|
|
||||||
if (Array.isArray(parsed)) {
|
|
||||||
// If parsed is an array of tables with Rows properties
|
|
||||||
allRows = parsed.flatMap(t => t.Rows ?? []);
|
|
||||||
} else if (parsed && Array.isArray(parsed.Rows)) {
|
|
||||||
allRows = parsed.Rows;
|
|
||||||
} else {
|
|
||||||
// fallback: if parsed itself is an array of row objects
|
|
||||||
allRows = Array.isArray(parsed) ? parsed : [];
|
|
||||||
}
|
|
||||||
if (!allRows || allRows.length === 0) {
|
|
||||||
this.gridData = [];
|
|
||||||
this.gridColumns = [];
|
|
||||||
this.gridColumnsForChart = [];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Use keys from first row as canonical columns
|
|
||||||
const keys = Object.keys(allRows[0]);
|
|
||||||
// Build gridColumns with safe field names and non-empty titles
|
|
||||||
this.gridColumns = keys.map(k => {
|
|
||||||
const safeKey = k.replace(/\s+/g, '_');
|
|
||||||
return {
|
|
||||||
field: safeKey,
|
|
||||||
title: (k && k.toString().trim()) ? k.toString() : safeKey,
|
|
||||||
editing: false
|
|
||||||
};
|
|
||||||
});
|
|
||||||
// Normalize each row: convert keys to safeKey, replace null/object with readable value
|
|
||||||
this.gridData = allRows.map(row => {
|
|
||||||
const normalized: any = {};
|
|
||||||
for (const k of keys) {
|
|
||||||
const safeKey = k.replace(/\s+/g, '_');
|
|
||||||
let val = row[k];
|
|
||||||
|
|
||||||
if (val === null || val === undefined || typeof val === 'object') {
|
|
||||||
normalized[safeKey] = '-';
|
|
||||||
} else {
|
|
||||||
normalized[safeKey] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return normalized;
|
|
||||||
});
|
|
||||||
// Columns for chart control:
|
|
||||||
if (this.gridColumns && this.gridColumns.length > 0) {
|
|
||||||
this.gridColumnsForChart = this.gridColumns.map(col => ({ description: col.title, value: col.field }));
|
|
||||||
} else {
|
|
||||||
this.gridColumnsForChart = [];
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Parse error in ProcessOpenAIData', e);
|
|
||||||
this.notificationService.showError("Failed to parse OpenAI response.", "Parse Error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveHeader(index: number) {
|
|
||||||
if (!this.gridColumns || !this.gridColumns[index]) { return; }
|
|
||||||
const col = this.gridColumns[index];
|
|
||||||
if (!col.title || col.title.toString().trim() === '') {
|
|
||||||
col.title = col.field;
|
|
||||||
}
|
|
||||||
col.editing = false;
|
|
||||||
delete col._oldTitle;
|
|
||||||
}
|
|
||||||
cancelHeader(index: number) {
|
|
||||||
if (!this.gridColumns || !this.gridColumns[index]) { return; }
|
|
||||||
const col = this.gridColumns[index];
|
|
||||||
if (col._oldTitle !== undefined) {
|
|
||||||
col.title = col._oldTitle;
|
|
||||||
}
|
|
||||||
col.editing = false;
|
|
||||||
delete col._oldTitle;
|
|
||||||
}
|
|
||||||
deleteColumn(index: number) {
|
|
||||||
const removed = this.gridColumns.splice(index, 1)[0];
|
|
||||||
this.deletedColumns.push({ ...removed, index });
|
|
||||||
}
|
|
||||||
scrollDeleted(direction: number) {
|
|
||||||
if (this.deletedContainer && this.deletedContainer.nativeElement) {
|
|
||||||
const el = this.deletedContainer.nativeElement;
|
|
||||||
const scrollAmount = 150;
|
|
||||||
el.scrollBy({ left: direction * scrollAmount, behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
startEdit(index: number) {
|
|
||||||
if (!this.gridColumns || !this.gridColumns[index]) { return; }
|
|
||||||
const col = this.gridColumns[index];
|
|
||||||
|
|
||||||
col._oldTitle = col.title;
|
|
||||||
col.editing = true;
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
const selector = `.header-container[data-col-index="${index}"] .header-input`;
|
|
||||||
const el = document.querySelector(selector) as HTMLInputElement | null;
|
|
||||||
if (el) {
|
|
||||||
el.focus();
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
restoreColumn(idx: number) {
|
|
||||||
const col = this.deletedColumns.splice(idx, 1)[0];
|
|
||||||
this.gridColumns.splice(col.index, 0, col);
|
|
||||||
}
|
|
||||||
onHeaderBlur(index: number) {
|
|
||||||
this.saveHeader(index);
|
|
||||||
}
|
|
||||||
openAvailableInfoDialog(){
|
|
||||||
this.isShowAvailableInfo = true;
|
|
||||||
}
|
|
||||||
onReportGroupChange(group : any){
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
this.invalidQueryMessage = "The AI can provide information when you ask about HR."
|
|
||||||
if(this.selectedReportGroup &&
|
|
||||||
(this.selectedReportGroup === EnumReportGroupType.Employee
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Salary
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Performance
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Training
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Attendance
|
|
||||||
|| this.selectedReportGroup === EnumReportGroupType.Leave)){
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = true;
|
|
||||||
this.reportColumnDefinition = [];
|
|
||||||
this.tableColumnDefinition = [];
|
|
||||||
this.opeAiService.GetReportColumnDefinition(this.selectedReportGroup).subscribe(
|
|
||||||
(resp: any) => {
|
|
||||||
this.reportColumnDefinition = resp as any[];
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.notificationService.showError(err.error, "Error");
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.gridData = [];
|
|
||||||
if (this.reportColumnDefinition && this.reportColumnDefinition.length > 0) {
|
|
||||||
const excludedNormalizedCaptions = new Set(['employeeid']);
|
|
||||||
const excludedNormalizedCaptionsSalaryMonthlyID = new Set(['salarymonthlyid']);
|
|
||||||
const groupedMap = new Map<string, ReportColumnDefinition>();
|
|
||||||
this.reportColumnDefinition.forEach(item => {
|
|
||||||
const normalized = this.normalizeCaption(item.caption);
|
|
||||||
if (!excludedNormalizedCaptions.has(normalized) && !excludedNormalizedCaptionsSalaryMonthlyID.has(normalized)) {
|
|
||||||
const rawTableName = item.tablename || '';
|
|
||||||
const cleanedTableName = rawTableName.startsWith('vw') ? rawTableName.substring(2) : rawTableName;
|
|
||||||
if (!groupedMap.has(cleanedTableName)) {
|
|
||||||
groupedMap.set(cleanedTableName, {
|
|
||||||
tableName: cleanedTableName,
|
|
||||||
fields: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
groupedMap.get(cleanedTableName)!.fields.push(item.caption);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.tableColumnDefinition = Array.from(groupedMap.values());
|
|
||||||
}
|
|
||||||
this.LoadCurrentUserAllQueryLog(this.selectedReportGroup);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
normalizeCaption(caption: string): string {
|
|
||||||
return caption.replace(/\s+/g, '').toLowerCase().trim();
|
|
||||||
}
|
|
||||||
OpenAIPreviousQueryExecution(id : number){
|
|
||||||
this.isUserPromptIsNotRelated = false;
|
|
||||||
this.invalidQueryMessage = "No data returned from AI."
|
|
||||||
if(id && id > 0){
|
|
||||||
let oQueryLog : OpenAIQueryLog = this.currentUserAllQueryLog.find(x => x.id === id) ?? undefined;
|
|
||||||
if(oQueryLog != undefined){
|
|
||||||
this.isShowCurrentUserAllQueryLog = false
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = true;
|
|
||||||
this.inputUserCommand = oQueryLog.userPrompt;
|
|
||||||
this.selectedReportGroup = oQueryLog.reportGroup;
|
|
||||||
if(oQueryLog.title && oQueryLog.title !== ""){
|
|
||||||
this.pdfFileName = `${oQueryLog.title}.pdf`;
|
|
||||||
this.excelFileName = `${oQueryLog.title}.xlsx`;
|
|
||||||
this.pngFilename = `${oQueryLog.title}_Chart.png`;
|
|
||||||
this.pdfFileNameForChart = `${oQueryLog.title}_Chart.pdf`;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.pdfFileName = 'FileData.pdf';
|
|
||||||
this.excelFileName = 'FileData.xlsx';
|
|
||||||
this.pngFilename = 'FileData_Chart.png';
|
|
||||||
this.pdfFileNameForChart = 'FileData_Chart.pdf';
|
|
||||||
}
|
|
||||||
const data = {
|
|
||||||
oQueryLog: oQueryLog
|
|
||||||
}
|
|
||||||
this.gridData = [];
|
|
||||||
this.gridColumns = [];
|
|
||||||
this.gridData = this.gridColumns = [];
|
|
||||||
this.OpenAIResponce = {};
|
|
||||||
this.isShowChart = false;
|
|
||||||
this.opeAiService.OpenAIPreviousQueryExecution(data).subscribe(
|
|
||||||
(resp: any) => {
|
|
||||||
this.OpenAIResponce = JSON.parse(resp);
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
this.isShowCurrentUserAllQueryLog = false
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.notificationService.showError(err.error, "Error");
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.isShowCurrentUserAllQueryLog = false
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.ProcessOpenAIData();
|
|
||||||
this.LoadCurrentUserAllQueryLog(this.selectedReportGroup);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.isShowCurrentUserAllQueryLog = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
this.isShowCurrentUserAllQueryLog = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ShowChart(){
|
|
||||||
this.isShowChartOption = true;
|
|
||||||
}
|
|
||||||
onChartGroupChange(group : any){
|
|
||||||
}
|
|
||||||
showOutOfScopeNotice() {
|
|
||||||
const msg = this.scopeMessages[this.selectedReportGroup] ?? "I can only help with questions related to this section.";
|
|
||||||
this.setInvalidQueryMessage(msg);
|
|
||||||
this.isUserPromptIsNotRelated = true;
|
|
||||||
}
|
|
||||||
filteredQueryLog(): OpenAIQueryLog[] {
|
|
||||||
if (!this.querySearchText) return this.currentUserAllQueryLog;
|
|
||||||
const search = this.querySearchText.toLowerCase();
|
|
||||||
return this.currentUserAllQueryLog.filter(item =>
|
|
||||||
item.userPrompt.toLowerCase().includes(search)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
exportChartImage(chart: ChartComponent) {
|
|
||||||
this.chartTransitions = false;
|
|
||||||
setTimeout(() => {
|
|
||||||
chart.exportImage().then((dataURI: string) => {
|
|
||||||
saveAs(dataURI, this.pngFilename);
|
|
||||||
this.chartTransitions = true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exportSizedChart(chart: ChartComponent): void {
|
|
||||||
const visual = chart.exportVisual({width: PAGE_RECT.size.width,});
|
|
||||||
this.exportElement(visual);
|
|
||||||
}
|
|
||||||
exportElement(element: Group): void {
|
|
||||||
exportPDF(element, {paperSize: "A4",margin: "1cm",}).then((dataURI) => {saveAs(dataURI, this.pdfFileNameForChart);});
|
|
||||||
}
|
|
||||||
private scopeMessages: Record<number, string> = {
|
|
||||||
[EnumReportGroupType.Employee]: "I can only help with questions related to Employee information.",
|
|
||||||
[EnumReportGroupType.Salary]: "I can only help with questions related to Employee Salary.",
|
|
||||||
[EnumReportGroupType.Performance]:"I can only help with questions related to Employee Performance.",
|
|
||||||
[EnumReportGroupType.Training]: "I can only help with questions related to Employee Training."
|
|
||||||
};
|
|
||||||
ShareThisChatWithOthers(queryLog : OpenAIQueryLog){
|
|
||||||
this.currentChat = undefined;
|
|
||||||
this.currentChat = queryLog;
|
|
||||||
this.ShareThisChat();
|
|
||||||
}
|
|
||||||
ShareThisChat(){
|
|
||||||
if(this.currentChat !== undefined){
|
|
||||||
this.currentChat.isCommon = !this.currentChat.isCommon;
|
|
||||||
const data = {
|
|
||||||
oQueryLog : this.currentChat
|
|
||||||
}
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = true;
|
|
||||||
this.opeAiService.ChatShareWithOthers(data).subscribe(
|
|
||||||
(resp: any) => {
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.notificationService.showError(err.error, "Error");
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
this.loadingpanelService.ShowLoadingPanel = false;
|
|
||||||
this.LoadCurrentUserAllQueryLog(this.selectedReportGroup);
|
|
||||||
this.notificationService.showSuccess("Successfully Shared");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ReportColumnDefinition {
|
|
||||||
tableName: string;
|
|
||||||
fields: string[] = [];
|
|
||||||
}
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
"use strict";
|
|
||||||
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
||||||
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
||||||
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
||||||
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
||||||
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
||||||
var _, done = false;
|
|
||||||
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
||||||
var context = {};
|
|
||||||
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
||||||
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
||||||
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
||||||
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
||||||
if (kind === "accessor") {
|
|
||||||
if (result === void 0) continue;
|
|
||||||
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
||||||
if (_ = accept(result.get)) descriptor.get = _;
|
|
||||||
if (_ = accept(result.set)) descriptor.set = _;
|
|
||||||
if (_ = accept(result.init)) initializers.unshift(_);
|
|
||||||
}
|
|
||||||
else if (_ = accept(result)) {
|
|
||||||
if (kind === "field") initializers.unshift(_);
|
|
||||||
else descriptor[key] = _;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
||||||
done = true;
|
|
||||||
};
|
|
||||||
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
||||||
var useValue = arguments.length > 2;
|
|
||||||
for (var i = 0; i < initializers.length; i++) {
|
|
||||||
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
||||||
}
|
|
||||||
return useValue ? value : void 0;
|
|
||||||
};
|
|
||||||
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
||||||
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
||||||
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.HRMOpenAIModule = void 0;
|
|
||||||
var core_1 = require("@angular/core");
|
|
||||||
var common_1 = require("@angular/common");
|
|
||||||
var Basic_From_Builder_module_1 = require("../form-builder/Basic-From-Builder.module");
|
|
||||||
var kendo_angular_grid_1 = require("@progress/kendo-angular-grid");
|
|
||||||
//import { BodyModule, SharedModule } from '@progress/kendo-angular-grid';
|
|
||||||
var kendo_angular_inputs_1 = require("@progress/kendo-angular-inputs");
|
|
||||||
var kendo_angular_charts_1 = require("@progress/kendo-angular-charts");
|
|
||||||
var kendo_angular_dialog_1 = require("@progress/kendo-angular-dialog");
|
|
||||||
var forms_1 = require("@angular/forms");
|
|
||||||
var kendo_angular_dropdowns_1 = require("@progress/kendo-angular-dropdowns");
|
|
||||||
var kendo_angular_dateinputs_1 = require("@progress/kendo-angular-dateinputs");
|
|
||||||
var kendo_angular_indicators_1 = require("@progress/kendo-angular-indicators");
|
|
||||||
var loading_panel_module_1 = require("../hrm-loding panel/loading-panel.module");
|
|
||||||
var loding_panel_service_1 = require("../hrm-loding panel/loding.panel.service");
|
|
||||||
var kendo_angular_buttons_1 = require("@progress/kendo-angular-buttons");
|
|
||||||
var inputtext_1 = require("primeng/inputtext");
|
|
||||||
var dialog_1 = require("primeng/dialog");
|
|
||||||
var scrollpanel_1 = require("primeng/scrollpanel");
|
|
||||||
var accordion_1 = require("primeng/accordion");
|
|
||||||
var autocomplete_1 = require("primeng/autocomplete");
|
|
||||||
var breadcrumb_1 = require("primeng/breadcrumb");
|
|
||||||
var calendar_1 = require("primeng/calendar");
|
|
||||||
var card_1 = require("primeng/card");
|
|
||||||
var carousel_1 = require("primeng/carousel");
|
|
||||||
var chart_1 = require("primeng/chart");
|
|
||||||
var checkbox_1 = require("primeng/checkbox");
|
|
||||||
var chips_1 = require("primeng/chips");
|
|
||||||
//import { CodeHighlighterModule } from 'primeng/codehighlighter';
|
|
||||||
var confirmdialog_1 = require("primeng/confirmdialog");
|
|
||||||
var colorpicker_1 = require("primeng/colorpicker");
|
|
||||||
var contextmenu_1 = require("primeng/contextmenu");
|
|
||||||
var dataview_1 = require("primeng/dataview");
|
|
||||||
var dropdown_1 = require("primeng/dropdown");
|
|
||||||
var editor_1 = require("primeng/editor");
|
|
||||||
var fieldset_1 = require("primeng/fieldset");
|
|
||||||
var fileupload_1 = require("primeng/fileupload");
|
|
||||||
//import { FullCalendarModule } from 'primeng/fullcalendar';
|
|
||||||
var galleria_1 = require("primeng/galleria");
|
|
||||||
var inplace_1 = require("primeng/inplace");
|
|
||||||
var inputmask_1 = require("primeng/inputmask");
|
|
||||||
var inputswitch_1 = require("primeng/inputswitch");
|
|
||||||
//import { InputTextareaModule } from 'primeng/inputtextarea';
|
|
||||||
//import { LightboxModule } from 'primeng/lightbox';
|
|
||||||
var listbox_1 = require("primeng/listbox");
|
|
||||||
var megamenu_1 = require("primeng/megamenu");
|
|
||||||
var menu_1 = require("primeng/menu");
|
|
||||||
var menubar_1 = require("primeng/menubar");
|
|
||||||
var messages_1 = require("primeng/messages");
|
|
||||||
var message_1 = require("primeng/message");
|
|
||||||
var multiselect_1 = require("primeng/multiselect");
|
|
||||||
var orderlist_1 = require("primeng/orderlist");
|
|
||||||
var organizationchart_1 = require("primeng/organizationchart");
|
|
||||||
var overlaypanel_1 = require("primeng/overlaypanel");
|
|
||||||
var paginator_1 = require("primeng/paginator");
|
|
||||||
var panel_1 = require("primeng/panel");
|
|
||||||
var panelmenu_1 = require("primeng/panelmenu");
|
|
||||||
var password_1 = require("primeng/password");
|
|
||||||
var picklist_1 = require("primeng/picklist");
|
|
||||||
var progressbar_1 = require("primeng/progressbar");
|
|
||||||
var radiobutton_1 = require("primeng/radiobutton");
|
|
||||||
var rating_1 = require("primeng/rating");
|
|
||||||
var selectbutton_1 = require("primeng/selectbutton");
|
|
||||||
//import { SlideMenuModule } from 'primeng/slidemenu';
|
|
||||||
var slider_1 = require("primeng/slider");
|
|
||||||
//import { SpinnerModule } from 'primeng/spinner';
|
|
||||||
var splitbutton_1 = require("primeng/splitbutton");
|
|
||||||
var steps_1 = require("primeng/steps");
|
|
||||||
var tabmenu_1 = require("primeng/tabmenu");
|
|
||||||
var table_1 = require("primeng/table");
|
|
||||||
var tabview_1 = require("primeng/tabview");
|
|
||||||
var terminal_1 = require("primeng/terminal");
|
|
||||||
var tieredmenu_1 = require("primeng/tieredmenu");
|
|
||||||
var toast_1 = require("primeng/toast");
|
|
||||||
var togglebutton_1 = require("primeng/togglebutton");
|
|
||||||
var toolbar_1 = require("primeng/toolbar");
|
|
||||||
var tooltip_1 = require("primeng/tooltip");
|
|
||||||
var tree_1 = require("primeng/tree");
|
|
||||||
var treetable_1 = require("primeng/treetable");
|
|
||||||
//import { VirtualScrollerModule } from 'primeng/virtualscroller';
|
|
||||||
var kendo_angular_layout_1 = require("@progress/kendo-angular-layout");
|
|
||||||
var ng2_pdf_viewer_1 = require("ng2-pdf-viewer");
|
|
||||||
var kendo_angular_layout_2 = require("@progress/kendo-angular-layout");
|
|
||||||
var kendo_angular_layout_3 = require("@progress/kendo-angular-layout");
|
|
||||||
var kendo_angular_progressbar_1 = require("@progress/kendo-angular-progressbar");
|
|
||||||
var app_notification_service_1 = require("../app.notification.service");
|
|
||||||
var picker_module_1 = require("../picker/picker.module");
|
|
||||||
;
|
|
||||||
var BackgroundCanvas_module_1 = require("../BackgroundCanvas/BackgroundCanvas.module");
|
|
||||||
var hrmopen_ai_routing_module_1 = require("./hrmopen-ai-routing.module");
|
|
||||||
var hrmopen_aiteast_component_1 = require("./hrmopen-ai-test/hrmopen-aiteast.component");
|
|
||||||
var hrmopen_ai_service_1 = require("../_services/HRMOpenAI/hrmopen-ai.service");
|
|
||||||
require("@progress/kendo-drawing");
|
|
||||||
var HRMOpenAIModule = function () {
|
|
||||||
var _classDecorators = [(0, core_1.NgModule)({
|
|
||||||
declarations: [hrmopen_aiteast_component_1.HRMOpenAITestComponent],
|
|
||||||
imports: [
|
|
||||||
common_1.CommonModule,
|
|
||||||
hrmopen_ai_routing_module_1.HRMOpenAIRoutingModule,
|
|
||||||
common_1.CommonModule,
|
|
||||||
forms_1.FormsModule,
|
|
||||||
forms_1.ReactiveFormsModule,
|
|
||||||
kendo_angular_dialog_1.DialogsModule,
|
|
||||||
kendo_angular_grid_1.GridModule,
|
|
||||||
kendo_angular_inputs_1.InputsModule,
|
|
||||||
kendo_angular_grid_1.PDFModule,
|
|
||||||
kendo_angular_grid_1.ExcelModule,
|
|
||||||
kendo_angular_charts_1.ChartsModule,
|
|
||||||
Basic_From_Builder_module_1.BasicFromBuilderModule,
|
|
||||||
kendo_angular_dropdowns_1.DropDownsModule,
|
|
||||||
kendo_angular_dateinputs_1.DateInputsModule,
|
|
||||||
kendo_angular_dateinputs_1.DateInputsModule,
|
|
||||||
picker_module_1.Pickermodule,
|
|
||||||
kendo_angular_indicators_1.IndicatorsModule,
|
|
||||||
loading_panel_module_1.LoadingPanelModule,
|
|
||||||
kendo_angular_buttons_1.ButtonModule,
|
|
||||||
inputtext_1.InputTextModule,
|
|
||||||
dialog_1.DialogModule,
|
|
||||||
scrollpanel_1.ScrollPanelModule,
|
|
||||||
ng2_pdf_viewer_1.PdfViewerModule,
|
|
||||||
autocomplete_1.AutoCompleteModule,
|
|
||||||
breadcrumb_1.BreadcrumbModule,
|
|
||||||
calendar_1.CalendarModule,
|
|
||||||
card_1.CardModule,
|
|
||||||
carousel_1.CarouselModule,
|
|
||||||
chart_1.ChartModule,
|
|
||||||
checkbox_1.CheckboxModule,
|
|
||||||
chips_1.ChipsModule,
|
|
||||||
confirmdialog_1.ConfirmDialogModule,
|
|
||||||
accordion_1.AccordionModule,
|
|
||||||
colorpicker_1.ColorPickerModule,
|
|
||||||
contextmenu_1.ContextMenuModule,
|
|
||||||
dataview_1.DataViewModule,
|
|
||||||
dropdown_1.DropdownModule,
|
|
||||||
editor_1.EditorModule,
|
|
||||||
fieldset_1.FieldsetModule,
|
|
||||||
fileupload_1.FileUploadModule,
|
|
||||||
galleria_1.GalleriaModule,
|
|
||||||
inplace_1.InplaceModule,
|
|
||||||
inputmask_1.InputMaskModule,
|
|
||||||
inputswitch_1.InputSwitchModule,
|
|
||||||
listbox_1.ListboxModule,
|
|
||||||
megamenu_1.MegaMenuModule,
|
|
||||||
menu_1.MenuModule,
|
|
||||||
menubar_1.MenubarModule,
|
|
||||||
messages_1.MessagesModule,
|
|
||||||
message_1.MessageModule,
|
|
||||||
multiselect_1.MultiSelectModule,
|
|
||||||
orderlist_1.OrderListModule,
|
|
||||||
organizationchart_1.OrganizationChartModule,
|
|
||||||
overlaypanel_1.OverlayPanelModule,
|
|
||||||
paginator_1.PaginatorModule,
|
|
||||||
panel_1.PanelModule,
|
|
||||||
panelmenu_1.PanelMenuModule,
|
|
||||||
password_1.PasswordModule,
|
|
||||||
picklist_1.PickListModule,
|
|
||||||
progressbar_1.ProgressBarModule,
|
|
||||||
radiobutton_1.RadioButtonModule,
|
|
||||||
rating_1.RatingModule,
|
|
||||||
selectbutton_1.SelectButtonModule,
|
|
||||||
kendo_angular_layout_1.CardModule,
|
|
||||||
treetable_1.TreeTableModule,
|
|
||||||
tree_1.TreeModule,
|
|
||||||
tooltip_1.TooltipModule,
|
|
||||||
toolbar_1.ToolbarModule,
|
|
||||||
togglebutton_1.ToggleButtonModule,
|
|
||||||
toast_1.ToastModule,
|
|
||||||
tieredmenu_1.TieredMenuModule,
|
|
||||||
terminal_1.TerminalModule,
|
|
||||||
tabview_1.TabViewModule,
|
|
||||||
table_1.TableModule,
|
|
||||||
tabmenu_1.TabMenuModule,
|
|
||||||
steps_1.StepsModule,
|
|
||||||
splitbutton_1.SplitButtonModule,
|
|
||||||
slider_1.SliderModule,
|
|
||||||
kendo_angular_layout_2.TabStripModule,
|
|
||||||
kendo_angular_layout_3.ExpansionPanelModule,
|
|
||||||
kendo_angular_progressbar_1.ProgressBarModule,
|
|
||||||
BackgroundCanvas_module_1.BackgroundCanvasModule
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
loding_panel_service_1.loadingPanelService,
|
|
||||||
app_notification_service_1.HRMNotificationService,
|
|
||||||
hrmopen_ai_service_1.HRMOpenAIService
|
|
||||||
]
|
|
||||||
})];
|
|
||||||
var _classDescriptor;
|
|
||||||
var _classExtraInitializers = [];
|
|
||||||
var _classThis;
|
|
||||||
var HRMOpenAIModule = _classThis = /** @class */ (function () {
|
|
||||||
function HRMOpenAIModule_1() {
|
|
||||||
}
|
|
||||||
return HRMOpenAIModule_1;
|
|
||||||
}());
|
|
||||||
__setFunctionName(_classThis, "HRMOpenAIModule");
|
|
||||||
(function () {
|
|
||||||
var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
||||||
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
||||||
HRMOpenAIModule = _classThis = _classDescriptor.value;
|
|
||||||
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
||||||
__runInitializers(_classThis, _classExtraInitializers);
|
|
||||||
})();
|
|
||||||
return HRMOpenAIModule = _classThis;
|
|
||||||
}();
|
|
||||||
exports.HRMOpenAIModule = HRMOpenAIModule;
|
|
||||||
//# sourceMappingURL=hrmopen-ai.module.js.map
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"version":3,"file":"hrmopen-ai.module.js","sourceRoot":"","sources":["hrmopen-ai.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,sCAAyC;AACzC,0CAAwD;AACxD,uFAAmF;AACnF,mEAAkF;AAClF,0EAA0E;AAC1E,uEAA8D;AAC9D,uEAA8D;AAC9D,uEAA6E;AAC7E,wCAAkE;AAClE,6EAAoE;AACpE,+EAAsE;AACtE,+EAAsE;AACtE,iFAA8E;AAC9E,iFAA+E;AAE/E,yEAA+D;AAC/D,+CAAoD;AACpD,yCAA8C;AAC9C,mDAAwD;AAExD,+CAAoD;AACpD,qDAA0D;AAC1D,iDAAsD;AACtD,6CAAkD;AAClD,qCAA0C;AAC1C,6CAAkD;AAClD,uCAA4C;AAC5C,6CAAkD;AAClD,uCAA4C;AAC5C,kEAAkE;AAClE,uDAA4D;AAC5D,mDAAwD;AACxD,mDAAwD;AACxD,6CAAkD;AAClD,6CAAkD;AAClD,yCAA8C;AAC9C,6CAAkD;AAClD,iDAAsD;AACtD,4DAA4D;AAC5D,6CAAkD;AAClD,2CAAgD;AAChD,+CAAoD;AACpD,mDAAwD;AACxD,8DAA8D;AAC9D,oDAAoD;AACpD,2CAAgD;AAChD,6CAAkD;AAClD,qCAA0C;AAC1C,2CAAgD;AAChD,6CAAkD;AAClD,2CAAgD;AAChD,mDAAwD;AACxD,+CAAoD;AACpD,+DAAoE;AACpE,qDAA0D;AAC1D,+CAAoD;AACpD,uCAA4C;AAC5C,+CAAoD;AACpD,6CAAkD;AAClD,6CAAkD;AAClD,mDAAwD;AACxD,mDAAwD;AACxD,yCAA8C;AAC9C,qDAA0D;AAC1D,sDAAsD;AACtD,yCAA8C;AAC9C,kDAAkD;AAClD,mDAAwD;AACxD,uCAA4C;AAC5C,2CAAgD;AAChD,uCAA4C;AAC5C,2CAAgD;AAChD,6CAAkD;AAClD,iDAAsD;AACtD,uCAA4C;AAC5C,qDAA0D;AAC1D,2CAAgD;AAChD,2CAAgD;AAChD,qCAA0C;AAC1C,+CAAoD;AACpD,kEAAkE;AAClE,uEAA+E;AAE/E,iDAAiD;AACjD,uEAAgE;AAChE,uEAAsE;AAMtE,iFAAkG;AAGlG,wEAAqE;AAErE,yDAAuD;AAK2B,CAAC;AACnF,uFAAqF;AAErF,yEAAqE;AACrE,yFAAqF;AACrF,gFAA6E;AAC7E,mCAAiC;AA8FjC;4BA5FC,IAAA,eAAQ,EAAC;YACR,YAAY,EAAE,CAAC,kDAAsB,CAAC;YACtC,OAAO,EAAE;gBACP,qBAAY;gBACZ,kDAAsB;gBACtB,qBAAY;gBACZ,mBAAW;gBACX,2BAAmB;gBACnB,oCAAa;gBACb,+BAAU;gBACV,mCAAY;gBACZ,8BAAS;gBACT,gCAAW;gBACX,mCAAY;gBACZ,kDAAsB;gBACtB,yCAAe;gBACf,2CAAgB;gBAChB,2CAAgB;gBAChB,4BAAY;gBACZ,2CAAgB;gBAChB,yCAAkB;gBAClB,oCAAY;gBACZ,2BAAe;gBACf,qBAAY;gBACZ,+BAAiB;gBACjB,gCAAe;gBACf,iCAAkB;gBAClB,6BAAgB;gBAChB,yBAAc;gBACd,iBAAU;gBACV,yBAAc;gBACd,mBAAW;gBACX,yBAAc;gBACd,mBAAW;gBACX,mCAAmB;gBACnB,2BAAe;gBACf,+BAAiB;gBACjB,+BAAiB;gBACjB,yBAAc;gBACd,yBAAc;gBACd,qBAAY;gBACZ,yBAAc;gBACd,6BAAgB;gBAChB,yBAAc;gBACd,uBAAa;gBACb,2BAAe;gBACf,+BAAiB;gBACjB,uBAAa;gBACb,yBAAc;gBACd,iBAAU;gBACV,uBAAa;gBACb,yBAAc;gBACd,uBAAa;gBACb,+BAAiB;gBACjB,2BAAe;gBACf,2CAAuB;gBACvB,iCAAkB;gBAClB,2BAAe;gBACf,mBAAW;gBACX,2BAAe;gBACf,yBAAc;gBACd,yBAAc;gBACd,+BAAiB;gBACjB,+BAAiB;gBACjB,qBAAY;gBACZ,iCAAkB;gBAClB,iCAAe;gBACf,2BAAe;gBACf,iBAAU;gBACV,uBAAa;gBACb,uBAAa;gBACb,iCAAkB;gBAClB,mBAAW;gBACX,6BAAgB;gBAChB,yBAAc;gBACd,uBAAa;gBACb,mBAAW;gBACX,uBAAa;gBACb,mBAAW;gBACX,+BAAiB;gBACjB,qBAAY;gBACZ,qCAAc;gBACd,2CAAoB;gBACpB,6CAAsB;gBACtB,gDAAsB;aACvB;YACA,SAAS,EAAC;gBACT,0CAAmB;gBACnB,iDAAsB;gBACtB,qCAAgB;aACjB;SACF,CAAC;;;;;;QAC6B,CAAC;QAAD,wBAAC;IAAD,CAAC;;;;QAAhC,6KAAgC;;;QAAnB,uDAAe;;;IAAI;AAAnB,0CAAe"}
|
|
||||||
|
|
@ -1,197 +0,0 @@
|
||||||
import { LMSService } from "./../_services/LearningManagement/lms.service";
|
|
||||||
import { NgModule } from "@angular/core";
|
|
||||||
import { CommonModule, DatePipe } from "@angular/common";
|
|
||||||
import { BasicFromBuilderModule } from "../form-builder/Basic-From-Builder.module";
|
|
||||||
import { ExcelModule, GridModule, PDFModule } from "@progress/kendo-angular-grid";
|
|
||||||
//import { BodyModule, SharedModule } from '@progress/kendo-angular-grid';
|
|
||||||
import { InputsModule } from "@progress/kendo-angular-inputs";
|
|
||||||
import { ChartsModule } from "@progress/kendo-angular-charts";
|
|
||||||
import { DialogsModule, WindowModule } from "@progress/kendo-angular-dialog";
|
|
||||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
|
||||||
import { DropDownsModule } from "@progress/kendo-angular-dropdowns";
|
|
||||||
import { DateInputsModule } from "@progress/kendo-angular-dateinputs";
|
|
||||||
import { IndicatorsModule } from "@progress/kendo-angular-indicators";
|
|
||||||
import { LoadingPanelModule } from "../hrm-loding panel/loading-panel.module";
|
|
||||||
import { loadingPanelService } from "../hrm-loding panel/loding.panel.service";
|
|
||||||
import { AttendanceServices } from "../_services/attendance/attendance.service";
|
|
||||||
import { ButtonModule } from "@progress/kendo-angular-buttons";
|
|
||||||
import { InputTextModule } from "primeng/inputtext";
|
|
||||||
import { DialogModule } from "primeng/dialog";
|
|
||||||
import { ScrollPanelModule } from "primeng/scrollpanel";
|
|
||||||
import { HttpClient } from "@angular/common/http";
|
|
||||||
import { AccordionModule } from "primeng/accordion";
|
|
||||||
import { AutoCompleteModule } from "primeng/autocomplete";
|
|
||||||
import { BreadcrumbModule } from "primeng/breadcrumb";
|
|
||||||
import { CalendarModule } from "primeng/calendar";
|
|
||||||
import { CardModule } from "primeng/card";
|
|
||||||
import { CarouselModule } from "primeng/carousel";
|
|
||||||
import { ChartModule } from "primeng/chart";
|
|
||||||
import { CheckboxModule } from "primeng/checkbox";
|
|
||||||
import { ChipsModule } from "primeng/chips";
|
|
||||||
//import { CodeHighlighterModule } from 'primeng/codehighlighter';
|
|
||||||
import { ConfirmDialogModule } from "primeng/confirmdialog";
|
|
||||||
import { ColorPickerModule } from "primeng/colorpicker";
|
|
||||||
import { ContextMenuModule } from "primeng/contextmenu";
|
|
||||||
import { DataViewModule } from "primeng/dataview";
|
|
||||||
import { DropdownModule } from "primeng/dropdown";
|
|
||||||
import { EditorModule } from "primeng/editor";
|
|
||||||
import { FieldsetModule } from "primeng/fieldset";
|
|
||||||
import { FileUploadModule } from "primeng/fileupload";
|
|
||||||
//import { FullCalendarModule } from 'primeng/fullcalendar';
|
|
||||||
import { GalleriaModule } from "primeng/galleria";
|
|
||||||
import { InplaceModule } from "primeng/inplace";
|
|
||||||
import { InputMaskModule } from "primeng/inputmask";
|
|
||||||
import { InputSwitchModule } from "primeng/inputswitch";
|
|
||||||
//import { InputTextareaModule } from 'primeng/inputtextarea';
|
|
||||||
//import { LightboxModule } from 'primeng/lightbox';
|
|
||||||
import { ListboxModule } from "primeng/listbox";
|
|
||||||
import { MegaMenuModule } from "primeng/megamenu";
|
|
||||||
import { MenuModule } from "primeng/menu";
|
|
||||||
import { MenubarModule } from "primeng/menubar";
|
|
||||||
import { MessagesModule } from "primeng/messages";
|
|
||||||
import { MessageModule } from "primeng/message";
|
|
||||||
import { MultiSelectModule } from "primeng/multiselect";
|
|
||||||
import { OrderListModule } from "primeng/orderlist";
|
|
||||||
import { OrganizationChartModule } from "primeng/organizationchart";
|
|
||||||
import { OverlayPanelModule } from "primeng/overlaypanel";
|
|
||||||
import { PaginatorModule } from "primeng/paginator";
|
|
||||||
import { PanelModule } from "primeng/panel";
|
|
||||||
import { PanelMenuModule } from "primeng/panelmenu";
|
|
||||||
import { PasswordModule } from "primeng/password";
|
|
||||||
import { PickListModule } from "primeng/picklist";
|
|
||||||
import { ProgressBarModule } from "primeng/progressbar";
|
|
||||||
import { RadioButtonModule } from "primeng/radiobutton";
|
|
||||||
import { RatingModule } from "primeng/rating";
|
|
||||||
import { SelectButtonModule } from "primeng/selectbutton";
|
|
||||||
//import { SlideMenuModule } from 'primeng/slidemenu';
|
|
||||||
import { SliderModule } from "primeng/slider";
|
|
||||||
//import { SpinnerModule } from 'primeng/spinner';
|
|
||||||
import { SplitButtonModule } from "primeng/splitbutton";
|
|
||||||
import { StepsModule } from "primeng/steps";
|
|
||||||
import { TabMenuModule } from "primeng/tabmenu";
|
|
||||||
import { TableModule } from "primeng/table";
|
|
||||||
import { TabViewModule } from "primeng/tabview";
|
|
||||||
import { TerminalModule } from "primeng/terminal";
|
|
||||||
import { TieredMenuModule } from "primeng/tieredmenu";
|
|
||||||
import { ToastModule } from "primeng/toast";
|
|
||||||
import { ToggleButtonModule } from "primeng/togglebutton";
|
|
||||||
import { ToolbarModule } from "primeng/toolbar";
|
|
||||||
import { TooltipModule } from "primeng/tooltip";
|
|
||||||
import { TreeModule } from "primeng/tree";
|
|
||||||
import { TreeTableModule } from "primeng/treetable";
|
|
||||||
//import { VirtualScrollerModule } from 'primeng/virtualscroller';
|
|
||||||
import { CardModule as kendoCardModule } from "@progress/kendo-angular-layout";
|
|
||||||
import { AppWindowPopUp } from "../app.windowPopup.service";
|
|
||||||
import { PdfViewerModule } from "ng2-pdf-viewer";
|
|
||||||
import { TabStripModule } from "@progress/kendo-angular-layout";
|
|
||||||
import { ExpansionPanelModule } from "@progress/kendo-angular-layout";
|
|
||||||
|
|
||||||
import { BrowserModule } from "@angular/platform-browser";
|
|
||||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
|
||||||
|
|
||||||
import { ProgressBarModule as KendoProgressBarModule } from "@progress/kendo-angular-progressbar";
|
|
||||||
import { DropDownListModule } from "@progress/kendo-angular-dropdowns";
|
|
||||||
|
|
||||||
import { HRMNotificationService } from "../app.notification.service";
|
|
||||||
import { LeaveService } from "../_services/leave/leave.service";
|
|
||||||
import { Pickermodule } from "../picker/picker.module";
|
|
||||||
import { BasicService } from "../_services/Basic/basic.service";
|
|
||||||
import { PaymentApprovalService } from "../_services/payment-approval/payment-approval.service";
|
|
||||||
import { SalaryService } from "../_services/payroll/salary.service";
|
|
||||||
import { UntilityHandlerService } from "../utility.hanldler.service";
|
|
||||||
import { EmpLifeCycleServices } from "../_services/employee/empLifeCycle.service";
|
|
||||||
import { BackgroundCanvasModule } from "../BackgroundCanvas/BackgroundCanvas.module";
|
|
||||||
|
|
||||||
import { HRMOpenAIRoutingModule } from "./hrmopen-ai-routing.module";
|
|
||||||
import { HRMOpenAITestComponent } from "./hrmopen-ai-test/hrmopen-aiteast.component";
|
|
||||||
import { HRMOpenAIService } from "../_services/HRMOpenAI/hrmopen-ai.service";
|
|
||||||
import "@progress/kendo-drawing";
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [HRMOpenAITestComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
DialogsModule,
|
|
||||||
GridModule,
|
|
||||||
InputsModule,
|
|
||||||
PDFModule,
|
|
||||||
ExcelModule,
|
|
||||||
ChartsModule,
|
|
||||||
BasicFromBuilderModule,
|
|
||||||
DropDownsModule,
|
|
||||||
DateInputsModule,
|
|
||||||
DateInputsModule,
|
|
||||||
Pickermodule,
|
|
||||||
IndicatorsModule,
|
|
||||||
LoadingPanelModule,
|
|
||||||
ButtonModule,
|
|
||||||
InputTextModule,
|
|
||||||
DialogModule,
|
|
||||||
ScrollPanelModule,
|
|
||||||
PdfViewerModule,
|
|
||||||
AutoCompleteModule,
|
|
||||||
BreadcrumbModule,
|
|
||||||
CalendarModule,
|
|
||||||
CardModule,
|
|
||||||
CarouselModule,
|
|
||||||
ChartModule,
|
|
||||||
CheckboxModule,
|
|
||||||
ChipsModule,
|
|
||||||
ConfirmDialogModule,
|
|
||||||
AccordionModule,
|
|
||||||
ColorPickerModule,
|
|
||||||
ContextMenuModule,
|
|
||||||
DataViewModule,
|
|
||||||
DropdownModule,
|
|
||||||
EditorModule,
|
|
||||||
FieldsetModule,
|
|
||||||
FileUploadModule,
|
|
||||||
GalleriaModule,
|
|
||||||
InplaceModule,
|
|
||||||
InputMaskModule,
|
|
||||||
InputSwitchModule,
|
|
||||||
ListboxModule,
|
|
||||||
MegaMenuModule,
|
|
||||||
MenuModule,
|
|
||||||
MenubarModule,
|
|
||||||
MessagesModule,
|
|
||||||
MessageModule,
|
|
||||||
MultiSelectModule,
|
|
||||||
OrderListModule,
|
|
||||||
OrganizationChartModule,
|
|
||||||
OverlayPanelModule,
|
|
||||||
PaginatorModule,
|
|
||||||
PanelModule,
|
|
||||||
PanelMenuModule,
|
|
||||||
PasswordModule,
|
|
||||||
PickListModule,
|
|
||||||
ProgressBarModule,
|
|
||||||
RadioButtonModule,
|
|
||||||
RatingModule,
|
|
||||||
SelectButtonModule,
|
|
||||||
kendoCardModule,
|
|
||||||
TreeTableModule,
|
|
||||||
TreeModule,
|
|
||||||
TooltipModule,
|
|
||||||
ToolbarModule,
|
|
||||||
ToggleButtonModule,
|
|
||||||
ToastModule,
|
|
||||||
TieredMenuModule,
|
|
||||||
TerminalModule,
|
|
||||||
TabViewModule,
|
|
||||||
TableModule,
|
|
||||||
TabMenuModule,
|
|
||||||
StepsModule,
|
|
||||||
SplitButtonModule,
|
|
||||||
SliderModule,
|
|
||||||
TabStripModule,
|
|
||||||
ExpansionPanelModule,
|
|
||||||
KendoProgressBarModule,
|
|
||||||
BackgroundCanvasModule,
|
|
||||||
HRMOpenAIRoutingModule
|
|
||||||
],
|
|
||||||
providers: [loadingPanelService, HRMNotificationService, HRMOpenAIService],
|
|
||||||
})
|
|
||||||
export class HRMOpenAIModule {}
|
|
||||||
|
|
@ -156,6 +156,7 @@
|
||||||
<Menu key="7.1.7.4" name="Multiple Employee Leave Ledger" url="/reports/report-viewer/102" parentkey="7.1.7"
|
<Menu key="7.1.7.4" name="Multiple Employee Leave Ledger" url="/reports/report-viewer/102" parentkey="7.1.7"
|
||||||
action="add;edit;delete" RoleType="Admin"></Menu>
|
action="add;edit;delete" RoleType="Admin"></Menu>
|
||||||
|
|
||||||
|
|
||||||
<Menu key="5" name="Attendance" url="" parentkey="" action="add;edit;delete" RoleType="Admin"></Menu>
|
<Menu key="5" name="Attendance" url="" parentkey="" action="add;edit;delete" RoleType="Admin"></Menu>
|
||||||
<Menu key="5.1" name="Master Data" url="" parentkey="5" action="add;edit;delete" RoleType="Admin"></Menu>
|
<Menu key="5.1" name="Master Data" url="" parentkey="5" action="add;edit;delete" RoleType="Admin"></Menu>
|
||||||
<Menu key="5.1.1" name="Shift" url="/attendance/shift" parentkey="5.1" action="add;edit;delete"
|
<Menu key="5.1.1" name="Shift" url="/attendance/shift" parentkey="5.1" action="add;edit;delete"
|
||||||
|
|
|
||||||
|
|
@ -318,10 +318,6 @@ namespace HRM.UI.Configuration.DI
|
||||||
services.AddTransient<IMembersTransactionDetailsService, MembersTransactionDetailsService>();
|
services.AddTransient<IMembersTransactionDetailsService, MembersTransactionDetailsService>();
|
||||||
services.AddTransient<IEmployeeTaxExcecptionService, EmployeeTaxExceptionService>();
|
services.AddTransient<IEmployeeTaxExcecptionService, EmployeeTaxExceptionService>();
|
||||||
|
|
||||||
//OpenAI
|
|
||||||
services.AddTransient<IOpenAIQueryLogService, OpenAIQueryLogService>();
|
|
||||||
|
|
||||||
|
|
||||||
// services.AddTransient<IDataIntergrationRequestService, DataIntergrationRequestService>();
|
// services.AddTransient<IDataIntergrationRequestService, DataIntergrationRequestService>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Data;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using AutoMapper.Configuration;
|
|
||||||
using Ease.Core;
|
|
||||||
using HRM.BO;
|
|
||||||
using HRM.DA;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.StaticFiles;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Payroll.BO;
|
|
||||||
using Payroll.Service;
|
|
||||||
using IConfiguration = Microsoft.Extensions.Configuration.IConfiguration;
|
|
||||||
|
|
||||||
namespace HRM.UI.Controllers
|
|
||||||
{
|
|
||||||
[ApiController]
|
|
||||||
[Route("api/HRMApenAPIAI")]
|
|
||||||
[Authorize]
|
|
||||||
public class OpenAIController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly OpenAIService _openAIService;
|
|
||||||
private readonly IOpenAIQueryLogService _openAIQueryLogService;
|
|
||||||
|
|
||||||
public OpenAIController(OpenAIService openAIService, IOpenAIQueryLogService openAIQueryLogService)
|
|
||||||
{
|
|
||||||
_openAIService = openAIService;
|
|
||||||
_openAIQueryLogService = openAIQueryLogService;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Route("AskOpenAI")]
|
|
||||||
public async Task<IActionResult> AskOpenAI(dynamic data)
|
|
||||||
{
|
|
||||||
CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);
|
|
||||||
var item = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(data));
|
|
||||||
string userCommand = (string)item["userPrompt"].ToObject<string>();
|
|
||||||
EnumReportGroupType reportGroupType = (EnumReportGroupType)item["reportGroup"].ToObject<EnumReportGroupType>();
|
|
||||||
DataSet oEmpBasicInfos = new DataSet();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
var response = await _openAIService.AskOpenAISqlQueryWithChartAsync(userCommand, (int)currentUser.UserID, reportGroupType,
|
|
||||||
currentUser.NextPayProcessDate ?? DateTime.Now);
|
|
||||||
return Ok(response);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Route("GetReportColumnDefinition/{reportGroupType}")]
|
|
||||||
public async Task<IActionResult> GetReportColumnDefinition(EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await _openAIService.GetColumnDefinitions(reportGroupType);
|
|
||||||
return Ok(response);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Route("GetCurrentUserAllQueryLog/{reportGroupType}")]
|
|
||||||
public ActionResult GetCurrentUserAllQueryLog(EnumReportGroupType reportGroupType)
|
|
||||||
{
|
|
||||||
CurrentUser currentUser = CurrentUser.GetCurrentUser(HttpContext.User);
|
|
||||||
List<OpenAIQueryLog> queryLogs = new List<OpenAIQueryLog>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
queryLogs = _openAIQueryLogService.GetAllQueryLogByUserID((int)currentUser.UserID, reportGroupType);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
|
|
||||||
}
|
|
||||||
return Ok(queryLogs);
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Route("OpenAIPreviousQueryExecution")]
|
|
||||||
public async Task<IActionResult> OpenAIPreviousQueryExecution(dynamic data)
|
|
||||||
{
|
|
||||||
var item = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(data));
|
|
||||||
OpenAIQueryLog userCommand = (OpenAIQueryLog)item["oQueryLog"].ToObject<OpenAIQueryLog>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await _openAIService.OpenAIPreviousQueryExecution(userCommand);
|
|
||||||
return Ok(response);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Route("ChatShareWithOthers")]
|
|
||||||
public async Task<IActionResult> ChatShareWithOthers(dynamic data)
|
|
||||||
{
|
|
||||||
var item = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(data));
|
|
||||||
OpenAIQueryLog userCommand = (OpenAIQueryLog)item["oQueryLog"].ToObject<OpenAIQueryLog>();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_openAIQueryLogService.ChatShareWithOthers(userCommand);
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return StatusCode(StatusCodes.Status500InternalServerError, ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -202,18 +202,6 @@ namespace HRM.UI.Api
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region AI Integration (OpenAI)
|
|
||||||
services.AddSingleton<OpenAIService>(provider =>
|
|
||||||
{
|
|
||||||
var config = provider.GetRequiredService<IConfiguration>();
|
|
||||||
var encryptedkey = config["OpenAI:ApiKey"];
|
|
||||||
var model = config["OpenAI:Model"];
|
|
||||||
int maxLimit = 5000;
|
|
||||||
return new OpenAIService(encryptedkey, model, maxLimit);
|
|
||||||
});
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Business Service
|
#region Business Service
|
||||||
|
|
||||||
services.ConfigureBusinessServices(Configuration);
|
services.ConfigureBusinessServices(Configuration);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user