Commit d011eb7b by Mac Stephens

Connected to entcad database, uniqueries created with all fields, initial…

Connected to entcad database, uniqueries created with all fields, initial complaint list endpoint created, cleaned up more envoy calls issues
parent 6fa13c63
// Where the database is kept. Only used by Lookup.ServiceImpl to retrieve info
// from the data base and send it to the client.
// Author: ???
unit Api.Database; unit Api.Database;
interface interface
...@@ -15,7 +12,6 @@ type ...@@ -15,7 +12,6 @@ type
ucEnvoy: TUniConnection; ucEnvoy: TUniConnection;
PostgreSQLUniProvider1: TPostgreSQLUniProvider; PostgreSQLUniProvider1: TPostgreSQLUniProvider;
UniQuery1: TUniQuery; UniQuery1: TUniQuery;
ucBooking: TUniConnection;
OracleUniProvider1: TOracleUniProvider; OracleUniProvider1: TOracleUniProvider;
uqBooking: TUniQuery; uqBooking: TUniQuery;
uqUnitsCurrent: TUniQuery; uqUnitsCurrent: TUniQuery;
...@@ -24,6 +20,104 @@ type ...@@ -24,6 +20,104 @@ type
uqCFSMemos: TUniQuery; uqCFSMemos: TUniQuery;
uqComplaintList: TUniQuery; uqComplaintList: TUniQuery;
uqComplaintDetails: TUniQuery; uqComplaintDetails: TUniQuery;
ucENTCAD: TUniConnection;
uqComplaintListCOMPLAINTID: TFloatField;
uqComplaintListCFSID: TFloatField;
uqComplaintListCOMPLAINT: TStringField;
uqComplaintListAGENCY: TStringField;
uqComplaintListDISPATCH_CODE_DESC: TStringField;
uqComplaintListSOURCE: TStringField;
uqComplaintListSOURCE_DESC: TStringField;
uqComplaintListPRIORITY: TStringField;
uqComplaintListADDRESSID: TFloatField;
uqComplaintListADDRESS: TStringField;
uqComplaintListAPARTMENT: TStringField;
uqComplaintListCITY: TStringField;
uqComplaintListBUSINESS: TStringField;
uqComplaintListDISPATCHDISTRICT: TStringField;
uqComplaintListDISPATCHSECTOR: TStringField;
uqComplaintListADDRESSDISTRICT: TStringField;
uqComplaintListADDRESSSECTOR: TStringField;
uqComplaintListXCOORD: TFloatField;
uqComplaintListYCOORD: TFloatField;
uqComplaintListWARNINGS: TFloatField;
uqComplaintListCONTACTS: TFloatField;
uqComplaintListHISTORY: TFloatField;
uqComplaintListDATEREPORTED: TDateTimeField;
uqComplaintListDATERECEIVED: TDateTimeField;
uqComplaintListDATEDISPATCHED: TDateTimeField;
uqComplaintListDATERESPONDED: TDateTimeField;
uqComplaintListDATEARRIVED: TDateTimeField;
uqComplaintListDATECLEARED: TDateTimeField;
uqComplaintDetailsCOMPLAINTID: TFloatField;
uqComplaintDetailsCFSID: TFloatField;
uqComplaintDetailsCOMPLAINT: TStringField;
uqComplaintDetailsAGENCY: TStringField;
uqComplaintDetailsDISPATCHCODE: TStringField;
uqComplaintDetailsDISPATCH_CODE_DESC: TStringField;
uqComplaintDetailsSOURCE: TStringField;
uqComplaintDetailsSOURCE_DESC: TStringField;
uqComplaintDetailsPRIORITY: TStringField;
uqComplaintDetailsADDRESSID: TFloatField;
uqComplaintDetailsADDRESS: TStringField;
uqComplaintDetailsAPARTMENT: TStringField;
uqComplaintDetailsCITY: TStringField;
uqComplaintDetailsBUSINESS: TStringField;
uqComplaintDetailsDISPATCHDISTRICT: TStringField;
uqComplaintDetailsDISPATCHSECTOR: TStringField;
uqComplaintDetailsADDRESSDISTRICT: TStringField;
uqComplaintDetailsADDRESSSECTOR: TStringField;
uqComplaintDetailsXCOORD: TFloatField;
uqComplaintDetailsYCOORD: TFloatField;
uqComplaintDetailsWARNINGS: TFloatField;
uqComplaintDetailsCONTACTS: TFloatField;
uqComplaintDetailsHISTORY: TFloatField;
uqComplaintDetailsDATEREPORTED: TDateTimeField;
uqComplaintDetailsDATERECEIVED: TDateTimeField;
uqComplaintDetailsDATEDISPATCHED: TDateTimeField;
uqComplaintDetailsDATERESPONDED: TDateTimeField;
uqComplaintDetailsDATEARRIVED: TDateTimeField;
uqComplaintDetailsDATECLEARED: TDateTimeField;
uqCFSActiveCOMPLAINTID: TFloatField;
uqCFSActiveUNITID: TFloatField;
uqCFSActiveUNITNAME: TStringField;
uqCFSActiveDATEDISPATCHED: TDateTimeField;
uqCFSActiveDATERESPONDED: TDateTimeField;
uqCFSActiveDATEARRIVED: TDateTimeField;
uqCFSActiveDATECLEARED: TDateTimeField;
uqCFSActiveLOCATION: TStringField;
uqCFSMemosMEMO_ID: TFloatField;
uqCFSMemosCFSID: TFloatField;
uqCFSMemosMEMO_TYPE: TFloatField;
uqCFSMemosTIMESTAMP: TDateTimeField;
uqCFSMemosBADGE_NUMBER: TStringField;
uqCFSMemosREMARKS: TStringField;
uqUnitsCurrentENTRYID: TFloatField;
uqUnitsCurrentUNITID: TFloatField;
uqUnitsCurrentUNITNAME: TStringField;
uqUnitsCurrentUNIT_DISTRICT: TStringField;
uqUnitsCurrentGPS_LATITUDE: TFloatField;
uqUnitsCurrentGPS_LONGITUDE: TFloatField;
uqDISUnitsActiveUNITID: TFloatField;
uqDISUnitsActiveUNITNAME: TStringField;
uqDISUnitsActiveCARNUMBER_DESC: TStringField;
uqDISUnitsActiveDISTRICT_DESC: TStringField;
uqDISUnitsActiveSECTOR_DESC: TStringField;
uqDISUnitsActiveOFFICER1_EMPNUM: TStringField;
uqDISUnitsActiveOFFICER1_LAST_NAME: TStringField;
uqDISUnitsActiveOFFICER1_FIRST_NAME: TStringField;
uqDISUnitsActiveOFFICER1_MI: TStringField;
uqDISUnitsActiveOFFICER2_EMPNUM: TStringField;
uqDISUnitsActiveOFFICER2_LAST_NAME: TStringField;
uqDISUnitsActiveOFFICER2_FIRST_NAME: TStringField;
uqDISUnitsActiveOFFICER2_MI: TStringField;
uqDISUnitsActiveLOCATION: TStringField;
uqDISUnitsActiveCOMPLAINT: TStringField;
uqDISUnitsActiveUNITSTATUS: TFloatField;
uqDISUnitsActiveUNIT_STATUS_DESC: TStringField;
uqDISUnitsActiveENTRYID: TFloatField;
uqDISUnitsActiveGPS_LATITUDE: TFloatField;
uqDISUnitsActiveGPS_LONGITUDE: TFloatField;
procedure DataModuleCreate(Sender: TObject); procedure DataModuleCreate(Sender: TObject);
private private
{ Private declarations } { Private declarations }
......
unit Api.Service;
interface
uses
XData.Service.Common,
Aurelius.Mapping.Attributes,
System.JSON,
System.Generics.Collections,
System.Classes;
const
API_MODEL = 'Api';
type
[ServiceContract, Model(API_MODEL)]
IApiService = interface(IInvokable)
['{4FCB7FAF-44E5-49D6-9C0F-EE44BFB33313}']
[HttpGet] function GetComplaintList: TJSONObject;
end;
implementation
end.
unit Api.ServiceImpl;
interface
uses
XData.Server.Module, XData.Service.Common, Api.Database, Data.DB,
System.SysUtils, System.Generics.Collections, XData.Sys.Exceptions,
System.Hash, System.Classes, Common.Logging, System.JSON, Api.Service;
type
[ServiceImplementation]
TApiService = class(TInterfacedObject, IApiService)
strict private
ApiDB: TApiDatabaseModule;
private
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
public
function GetComplaintList: TJSONObject;
end;
implementation
uses
uLibrary;
procedure TApiService.AfterConstruction;
begin
inherited;
ApiDB := TApiDatabaseModule.Create(nil);
Logger.Log(3, 'ApiDatabaseModule created');
end;
procedure TApiService.BeforeDestruction;
begin
ApiDB.Free;
inherited;
Logger.Log(3, 'ApiDatabaseModule destroyed');
end;
function TApiService.GetComplaintList: TJSONObject;
var
data: TJSONArray;
begin
Logger.Log(3, '---TApiService.GetComplaintList initiated');
Result := TJSONObject.Create;
TXDataOperationContext.Current.Handler.ManagedObjects.Add(Result);
data := TJSONArray.Create;
try
with ApiDB.uqComplaintList do
begin
Open;
First;
while not Eof do
begin
var status: string;
if not FieldByName('DATECLEARED').IsNull then
status := 'Cleared'
else if not FieldByName('DATEARRIVED').IsNull then
status := 'AtScene'
else if not FieldByName('DATEDISPATCHED').IsNull then
status := 'Dispatched'
else
status := 'Pending';
var item := TJSONObject.Create;
item.AddPair('ComplaintId', ApiDB.uqComplaintListCOMPLAINTID.AsString);
item.AddPair('Agency', ApiDB.uqComplaintListAGENCY.AsString);
item.AddPair('Priority', TJSONNumber.Create(ApiDB.uqComplaintListPRIORITY.AsString));
item.AddPair('DispatchCodeDesc', ApiDB.uqComplaintListDISPATCH_CODE_DESC.AsString);
item.AddPair('Address', ApiDB.uqComplaintListADDRESS.AsString);
item.AddPair('CFSId', ApiDB.uqComplaintListCFSID.AsString);
item.AddPair('Status', status);
item.AddPair('DispatchDistrict', ApiDB.uqComplaintListDISPATCHDISTRICT.AsString);
item.AddPair('DateReported', ApiDB.uqComplaintListDATEREPORTED.AsString);
data.AddElement(item);
Next;
end;
end;
Result.AddPair('count', TJSONNumber.Create(data.Count));
Result.AddPair('returned', TJSONNumber.Create(data.Count));
Result.AddPair('data', data);
except
data.Free;
Logger.Log(3, '---TApiService.GetComplaintList End (error)');
raise EXDataHttpException.Create(500, 'Failed to load complaints list');
end;
Logger.Log(3, '---TApiService.GetComplaintList End');
end;
initialization
RegisterServiceType(TApiService);
end.
// Lookup Service interface which retrieves information from the database
// which is then sent to the client.
// Authors:
// Cameron Hayes
// Mac ...
// Elias Sarraf
unit Lookup.Service;
interface
uses
XData.Service.Common,
Aurelius.Mapping.Attributes,
System.JSON,
System.Generics.Collections,
System.Classes;
const
API_MODEL = 'Api';
type
TCallItem = class
// Class of the info we want from the database from a specific call.
// callSid: SID of the call, 34 digit string.
// fromNumber: Who the phone call was from. (xxx) xxx-xxxx
// toNumber: Who the phone call was to. (xxx) xxx-xxxx
// dateCreated: Date the phone call was created. mm/dd/yyyy hh:nn:ss am/pm
// mediaURL: Link to the recording audio
// duration: Length of the entire call and recording.
// transcription: Transcription of the recording. Not always present due to
// the call being answerered or caller did not leave a message.
public
callSid: string;
fromNumber: string;
toNumber: string;
dateCreated: string;
mediaUrl: string;
duration: string;
transcription: string;
end;
// List of call items
// count: Total amount of records that fit the SQL query
// data: List of retrieved calls
TCallList = class
public
count: integer;
data: TList<TCallItem>;
end;
TUserItem = class
public
userID: string;
username: string;
full_name: string;
phone_number: string;
email_address: string;
admin: boolean;
active: boolean;
password: string;
end;
TUserList = class
public
count: integer;
data: TList<TUserItem>;
end;
type
[ServiceContract, Model(API_MODEL)]
ILookupService = interface(IInvokable)
['{F24E1468-5279-401F-A877-CD48B44F4416}']
[HttpGet] function GetCalls(searchOptions: string): TCallList;
[HttpGet] function Search(phoneNum: string): TCallList;
[HttpGet] function GetUsers(searchOptions: string): TUserList;
function AddUser(userInfo: string): string;
function DelUser(username: string): string;
function EditUser(const editOptions: string): string;
end;
implementation
initialization
RegisterServiceType(TypeInfo(ILookupService));
end.
...@@ -7,7 +7,7 @@ uses ...@@ -7,7 +7,7 @@ uses
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls, Vcl.ExtCtrls, System.Generics.Collections, System.IniFiles, Vcl.StdCtrls, Vcl.ExtCtrls, System.Generics.Collections, System.IniFiles,
Auth.Service, Auth.Server.Module, Api.Server.Module, App.Server.Module, Auth.Service, Auth.Server.Module, Api.Server.Module, App.Server.Module,
ExeInfo, Lookup.Service; ExeInfo, Api.Service;
type type
TFMain = class(TForm) TFMain = class(TForm)
......
...@@ -18,9 +18,9 @@ uses ...@@ -18,9 +18,9 @@ uses
Auth.Database in 'Source\Auth.Database.pas' {AuthDatabase: TDataModule}, Auth.Database in 'Source\Auth.Database.pas' {AuthDatabase: TDataModule},
uLibrary in 'Source\uLibrary.pas', uLibrary in 'Source\uLibrary.pas',
Auth.Service in 'Source\Auth.Service.pas', Auth.Service in 'Source\Auth.Service.pas',
Lookup.Service in 'Source\Lookup.Service.pas', Api.Service in 'Source\Api.Service.pas',
Auth.ServiceImpl in 'Source\Auth.ServiceImpl.pas', Auth.ServiceImpl in 'Source\Auth.ServiceImpl.pas',
Lookup.ServiceImpl in 'Source\Lookup.ServiceImpl.pas', Api.ServiceImpl in 'Source\Api.ServiceImpl.pas',
Twilio.Data.Module in 'Source\Twilio.Data.Module.pas' {TwilioDataModule: TDataModule}, Twilio.Data.Module in 'Source\Twilio.Data.Module.pas' {TwilioDataModule: TDataModule},
App.Server.Module in 'Source\App.Server.Module.pas' {AppServerModule: TDataModule}, App.Server.Module in 'Source\App.Server.Module.pas' {AppServerModule: TDataModule},
Common.Ini in 'Source\Common.Ini.pas'; Common.Ini in 'Source\Common.Ini.pas';
......
...@@ -160,9 +160,9 @@ ...@@ -160,9 +160,9 @@
</DCCReference> </DCCReference>
<DCCReference Include="Source\uLibrary.pas"/> <DCCReference Include="Source\uLibrary.pas"/>
<DCCReference Include="Source\Auth.Service.pas"/> <DCCReference Include="Source\Auth.Service.pas"/>
<DCCReference Include="Source\Lookup.Service.pas"/> <DCCReference Include="Source\Api.Service.pas"/>
<DCCReference Include="Source\Auth.ServiceImpl.pas"/> <DCCReference Include="Source\Auth.ServiceImpl.pas"/>
<DCCReference Include="Source\Lookup.ServiceImpl.pas"/> <DCCReference Include="Source\Api.ServiceImpl.pas"/>
<DCCReference Include="Source\Twilio.Data.Module.pas"> <DCCReference Include="Source\Twilio.Data.Module.pas">
<Form>TwilioDataModule</Form> <Form>TwilioDataModule</Form>
<DesignClass>TDataModule</DesignClass> <DesignClass>TDataModule</DesignClass>
......
[Settings] [Settings]
LogFileNum=409 LogFileNum=414
webClientVersion=0.1.0 webClientVersion=0.1.0
TwilioUpdateTime=1 TwilioUpdateTime=1
......
object FViewComplaints: TFViewComplaints object FViewComplaints: TFViewComplaints
Width = 676 Width = 359
Height = 480 Height = 480
CSSLibrary = cssBootstrap CSSLibrary = cssBootstrap
ElementFont = efCSS ElementFont = efCSS
...@@ -11,157 +11,91 @@ object FViewComplaints: TFViewComplaints ...@@ -11,157 +11,91 @@ object FViewComplaints: TFViewComplaints
ParentFont = False ParentFont = False
Visible = True Visible = True
OnCreate = WebFormCreate OnCreate = WebFormCreate
object lblEntries: TWebLabel object WebButton1: TWebButton
Left = 0 Left = 180
Top = 336 Top = 110
Width = 77 Width = 43
Height = 13 Height = 25
Caption = 'Showing 0 of ...' Caption = 'Group'
ElementID = 'lblentries' ChildOrder = 1
ElementFont = efCSS ElementClassName = 'btn btn-light'
HeightStyle = ssAuto ElementID = 'complaints_btngroup'
HeightPercent = 100.000000000000000000
Visible = False
WidthPercent = 100.000000000000000000
end
object wcbPageSize: TWebComboBox
Left = 0
Top = 0
Width = 145
Height = 21
ElementClassName = 'custom-select'
ElementID = 'wcbpagesize'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
Text = '10'
Visible = False
WidthPercent = 100.000000000000000000
ItemIndex = -1
Items.Strings = (
'10'
'25'
'50')
end
object wcbLocation: TWebLookupComboBox
Left = 154
Top = 0
Width = 145
Height = 22
ElementClassName = 'custom-select'
ElementID = 'wcblocation'
ElementFont = efCSS
HeightPercent = 100.000000000000000000
Visible = False
WidthPercent = 100.000000000000000000
ItemIndex = -1
LookupValues = <
item
DisplayText = 'All'
end
item
Value = '(716) 681-8820'
DisplayText = 'Galleria'
end
item
Value = '(716) 297-4654'
DisplayText = 'NF Outlet'
end
item
Value = '(585) 445-8911'
DisplayText = 'Rochester'
end
item
Value = '(315) 565-4138'
DisplayText = 'Syracuse'
end>
end
object dtpStartDate: TWebEdit
Left = 342
Top = 0
Width = 121
Height = 22
ChildOrder = 10
ElementClassName = 'form-control'
ElementID = 'dtpstartdate'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
Visible = False
WidthPercent = 100.000000000000000000
end
object dtpEndDate: TWebEdit
Left = 478
Top = 0
Width = 121
Height = 22
ChildOrder = 10
ElementClassName = 'form-control'
ElementID = 'dtpenddate'
ElementFont = efCSS ElementFont = efCSS
HeightStyle = ssAuto HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
Visible = False
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object wcbSortBy: TWebComboBox object WebButton2: TWebButton
Left = 442 Left = 242
Top = 52 Top = 110
Width = 145 Width = 37
Height = 21 Height = 25
ElementClassName = 'custom-select' Caption = 'Filter'
ElementID = 'wcbsortby' ChildOrder = 1
ElementClassName = 'btn btn-light'
ElementID = 'complaints_btnfilter'
ElementFont = efCSS ElementFont = efCSS
HeightStyle = ssAuto HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
Text = 'Date'
Visible = False
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
ItemIndex = -1
Items.Strings = (
'Date'
'Phone Number')
end end
object btnApply: TWebButton object Complaints: TWebButton
Left = 478 Left = 114
Top = 128 Top = 110
Width = 96 Width = 53
Height = 25 Height = 25
Caption = 'Apply' Caption = 'Refresh'
ChildOrder = 7 ChildOrder = 1
ElementClassName = 'btn btn-light' ElementClassName = 'btn btn-light'
ElementID = 'btnapply' ElementID = 'complaints_btnrefresh'
ElementFont = efCSS ElementFont = efCSS
HeightStyle = ssAuto HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
Visible = False
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object edtSearch: TWebEdit object dblComplaintsList: TWebDBListControl
Left = 50 Left = 36
Top = 382 Top = 148
Width = 121 Width = 263
Height = 22 Height = 237
HelpType = htKeyword ElementID = 'complaints_dbl_complaint_list'
ChildOrder = 8
ElementClassName = 'form-control'
ElementID = 'edtsearch'
ElementFont = efCSS
HeightStyle = ssAuto HeightStyle = ssAuto
HeightPercent = 100.000000000000000000 HeightPercent = 100.000000000000000000
HideSelection = False
TextHint = 'Format: (XXX) XXX-XXXX'
Visible = False
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
ChildOrder = 3
DefaultItemClassName = 'list-group-item'
DefaultItemLinkClassName = 'list-group-link'
ElementFont = efCSS
ElementListClassName = 'list-group'
Items = <
item
ItemClassName = 'list-group-item'
Items = <>
LinkClassName = 'list-group-link'
Text = 'Item 0'
end
item
ItemClassName = 'list-group-item'
Items = <>
LinkClassName = 'list-group-link'
Text = 'Item 1'
end
item
ItemClassName = 'list-group-item'
Items = <>
LinkClassName = 'list-group-link'
Text = 'Item 2'
end>
Style = lsListGroup
end end
object XDataWebClient1: TXDataWebClient object xdwcComplaints: TXDataWebClient
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 426 Left = 92
Top = 240 Top = 416
end end
object XDataWebDataSet1: TXDataWebDataSet object xdwdsComplaints: TXDataWebDataSet
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 440 Left = 214
Top = 300 Top = 414
end end
end end
...@@ -5,20 +5,20 @@ ...@@ -5,20 +5,20 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row w-100 g-2 align-items-stretch"> <div class="row w-100 g-2 align-items-stretch">
<div class="col"> <div class="col">
<span id="complaints.title" class="navbar-brand mb-0 h5 text-white">Complaints</span> <span id="complaints_title" class="navbar-brand mb-0 h5 text-white">Complaints</span>
</div> </div>
<div class="col"> <div class="col">
<button id="complaints.btnrefresh" type="button" class="btn btn-primary w-100 h-100"> <button id="complaints_btnrefresh" type="button" class="btn btn-primary w-100 h-100">
<i class="fa fa-sync-alt me-1"></i><span class="d-none d-sm-inline">Refresh</span> <i class="fa fa-sync-alt me-1"></i><span class="d-none d-sm-inline">Refresh</span>
</button> </button>
</div> </div>
<div class="col"> <div class="col">
<button id="complaints.btngroup" type="button" class="btn btn-primary w-100 h-100"> <button id="complaints_btngroup" type="button" class="btn btn-primary w-100 h-100">
<i class="fa fa-layer-group me-1"></i><span class="d-none d-sm-inline">Group</span> <i class="fa fa-layer-group me-1"></i><span class="d-none d-sm-inline">Group</span>
</button> </button>
</div> </div>
<div class="col"> <div class="col">
<button id="complaints.btnfilter" type="button" class="btn btn-primary w-100 h-100"> <button id="complaints_btnfilter" type="button" class="btn btn-primary w-100 h-100">
<i class="fa fa-sliders-h me-1"></i><span class="d-none d-sm-inline">Filter</span> <i class="fa fa-sliders-h me-1"></i><span class="d-none d-sm-inline">Filter</span>
</button> </button>
</div> </div>
...@@ -31,52 +31,33 @@ ...@@ -31,52 +31,33 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="input-group"> <div class="input-group">
<span class="input-group-text bg-white"><i class="fa fa-search"></i></span> <span class="input-group-text bg-white"><i class="fa fa-search"></i></span>
<input id="complaints.search" class="form-control" placeholder="Search..."> <input id="complaints_search" class="form-control" placeholder="Search...">
</div> </div>
</div> </div>
</div> </div>
</div> <!-- /sticky-top wrapper --> </div> <!-- /sticky-top wrapper -->
<!-- Existing content (unchanged) --> <!-- Complaints list container -->
<div class="row"> <div class="container-fluid mt-2">
<div class="col-12"> <div class="row justify-content-center">
<div class="container mt-4"> <div class="col-12 col-md-10 col-lg-8">
<div class="row justify-content-center"> <!-- This is where the DBListControl will inject cards -->
<div class="col-12 col-md-10 col-lg-8"> <div id="complaints_dbl_complaint_list" class="d-flex flex-column gap-2">
<h1 class="page-header pt-3 pb-2 mb-3 border-bottom fs-4 fw-bold" id="view.calls.title">Complaints</h1> <!-- Cards will render here -->
</div>
<!-- Data Table -->
<div class="table-responsive mt-4">
<table class="table table-sm table-striped table-bordered align-middle" id="tblPhoneGrid">
<thead class="table-dark">
<tr>
<th scope="col">Phone Number</th>
<th scope="col">Caller</th>
<th scope="col">Time</th>
<th scope="col">Duration</th>
<th scope="col">Transcript</th>
<th scope="col">Listen</th>
</tr>
</thead>
<tbody>
<!-- Rows added dynamically in Delphi -->
</tbody>
</table>
</div>
<!-- Entry Count Label --> <!-- Entry Count Label -->
<label id="lblentries" class="mt-2 d-block"></label> <label id="lblentries" class="mt-2 d-block"></label>
<!-- Pagination --> <!-- Pagination -->
<nav aria-label="Page navigation"> <nav aria-label="Page navigation">
<ul class="pagination justify-content-center" id="pagination"> <ul class="pagination justify-content-center" id="pagination">
<!-- Pagination items added in Delphi --> <!-- Pagination items rendered in Delphi -->
</ul> </ul>
</nav> </nav>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment