Commit ce5c1912 by Mac Stephens

Adding archive modal, WIP

parent b272a8e0
[Settings]
LogFileNum=659
LogFileNum=660
webClientVersion=0.1.0
--------------------------------2026/4/30 23:44:37--------------------------------
FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.
Freed object class: System.JSON.TJSONObject
Virtual method: Destroy
Virtual method address: CDDB7C
The allocation number was: 350389
The object was allocated by thread 0x4650, and the stack trace (return addresses) at the time was:
9E722E [System.pas][System][@GetMem$qqri][5057]
9E92D7 [System.pas][System][TObject.NewInstance][18511]
9E99DA [System.pas][System][@ClassCreate$qqrpvzc][19841]
CDD9CE [System.JSON.pas][System.JSON][Json.TJSONObject.Create][3021]
10AB558 [MemDS][TMemDataSet.Locate]
138251F [Api.ServiceImpl.pas][Api.ServiceImpl][Serviceimpl.TApiService.GetComplaintArchiveDetails][546]
A62D74 [System.Rtti.pas][System.Rtti][Rtti.RawInvoke$qqrpvp23System.Rtti.TParamBlock][8868]
A63159 [System.Rtti.pas][System.Rtti][Rtti.Invoke$qqrpvx42System.%DynamicArray$18System.Rtti.TValue%24System.Typinfo.TCallConvp24System.Typinfo.TTypeInfooo][9113]
9ED079 [System.pas][System][@FinalizeRecord$qqrpvt1][33521]
9F074B [System.pas][System][@IntfClear$qqrr44System.%DelphiInterface$17System.IInterface%][39340]
F02CDD [XData.Aurelius.Model.pas][XData.Aurelius.Model][Aurelius.Model.TXDataAureliusModel.GetActionInfo][490]
The object was subsequently freed by thread 0x4650, and the stack trace (return addresses) at the time was:
9E92F5 [System.pas][System][TObject.FreeInstance][18520]
9E9A25 [System.pas][System][@ClassDestroy$qqrxp14System.TObject][19884]
CDDBE1 [System.JSON.pas][System.JSON][Json.TJSONObject.Destroy][3113]
9E93EB [System.pas][System][TObject.Free][18583]
CDD859 [System.JSON.pas][System.JSON][Json.TJSONPair.Destroy][2952]
9E93EB [System.pas][System][TObject.Free][18583]
CDDBB0 [System.JSON.pas][System.JSON][Json.TJSONObject.Destroy][3108]
9E93EB [System.pas][System][TObject.Free][18583]
FAD403 [XData.Server.Module.pas][XData.Server.Module][Server.Module.TXDataRequestHandler.DestroyIfNotInManagers][1679]
FAB45B [XData.Server.Module.pas][XData.Server.Module][Server.Module.TXDataRequestHandler.CleanUp][1267]
F4C49C [XData.Module.Base.pas][XData.Module.Base][Module.Base.TXDataBaseRequestHandler.InnerProcessRequest][869]
The current thread ID is 0x4650, and the stack trace (return addresses) leading to this error is:
9E93EB [System.pas][System][TObject.Free][18583]
FAD403 [XData.Server.Module.pas][XData.Server.Module][Server.Module.TXDataRequestHandler.DestroyIfNotInManagers][1679]
FAB45B [XData.Server.Module.pas][XData.Server.Module][Server.Module.TXDataRequestHandler.CleanUp][1267]
F4C49C [XData.Module.Base.pas][XData.Module.Base][Module.Base.TXDataBaseRequestHandler.InnerProcessRequest][869]
F4CA62 [XData.Module.Base.pas][XData.Module.Base][Module.Base.TXDataBaseRequestHandler.ProcessRequest][907]
F4AAB0 [XData.Module.Base.pas][XData.Module.Base][Module.Base.TXDataBaseModule.ProcessRequest][330]
F403EE [Sparkle.HttpServer.Module.pas][Sparkle.HttpServer.Module][261]
105A727 [Sparkle.Middleware.Jwt.pas][Sparkle.Middleware.Jwt][Middleware.Jwt.TJwtMiddleware.ProcessRequest][273]
F40B10 [Sparkle.HttpServer.Module.pas][Sparkle.HttpServer.Module][304]
105CECF [Sparkle.Middleware.Compress.pas][Sparkle.Middleware.Compress][Middleware.Compress.TCompressMiddleware.ProcessRequest][228]
F40B10 [Sparkle.HttpServer.Module.pas][Sparkle.HttpServer.Module][304]
Current memory dump of 256 bytes starting at pointer address 7E79CD40:
8C CC 4E 01 80 80 80 80 80 80 80 80 80 80 80 80 91 9A DF 6F 80 80 80 80 00 00 00 00 C0 98 79 7E
00 00 00 00 00 00 00 00 78 AD 9F 00 00 00 00 00 0B 5A 05 00 2E 72 9E 00 5B B2 9E 00 F8 B6 9E 00
53 89 E5 00 C7 E6 E5 00 91 E6 E5 00 ED DD F4 00 3E 2E FB 00 14 2D FB 00 B4 20 FB 00 C5 D4 FA 00
50 46 00 00 50 46 00 00 4A 72 9E 00 F5 92 9E 00 25 9A 9E 00 DE 93 9E 00 74 1C 9F 00 4B 07 9F 00
C7 D4 9E 00 0A CE A3 00 44 9A 9F 00 04 B0 9F 00 19 B0 9F 00 12 00 00 00 B0 D6 CE 00 5C 8D 36 90
B0 04 02 00 01 00 00 00 02 00 00 00 4F 00 4B 00 00 00 A3 72 C9 6F 80 80 00 00 00 00 61 B9 79 7E
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38 4C 05 00 2E 72 9E 00 5B B2 9E 00 F8 B6 9E 00
AC 4E AA 00 B5 7C AA 00 DA 99 9E 00 A6 8E C1 00 09 C1 C2 00 17 23 0A 01 D5 88 16 01 33 DA 19 01
N . o . . . . y ~
. . . . . . . . x . . . . . . Z . . . r . [ . .
S . . . . > . . . - . . .
P F . . P F . . J r . . % . . t . . K . .
. . . D . . . . . . . . . . \ 6
. . . . . . . . . . . O . K . . . r o . . . . a y ~
. . . . . . . . . . . . . . . . 8 L . . . r . [ . .
N . | . . . . . . # . . . . 3 . .
......@@ -110,20 +110,6 @@ object FViewComplaintArchive: TFViewComplaintArchive
WidthPercent = 100.000000000000000000
OnClick = btnCmpArcClick
end
object btnComplaintViewOnMapArc: TWebButton
Left = 342
Top = 259
Width = 96
Height = 25
Caption = 'Map'
ChildOrder = 1
ElementID = 'btn_complaint_view_on_map_arc'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnComplaintViewOnMapArcClick
end
object xdwcComplaintArchive: TXDataWebClient
Connection = DMConnection.ApiConnection
Left = 292
......
......@@ -81,11 +81,4 @@
</div>
</div>
<button id="btn_complaint_view_on_map_arc"
type="button"
class="btn btn-primary btn-sm shadow position-fixed"
style="right: 15px; bottom: 25px; z-index: 1040;">
Map
</button>
</div>
......@@ -26,13 +26,10 @@ type
btnREMArc: TWebButton;
btnE911Arc: TWebButton;
btnCmpArc: TWebButton;
btnComplaintViewOnMapArc: TWebButton;
procedure WebFormCreate(Sender: TObject);
procedure btnCmpArcClick(Sender: TObject);
procedure btnE911ArcClick(Sender: TObject);
procedure btnREMArcClick(Sender: TObject);
procedure btnUntArcClick(Sender: TObject);
procedure btnComplaintViewOnMapArcClick(Sender: TObject);
private
FComplaintId: string;
FCfsId: string;
......@@ -44,6 +41,8 @@ type
FShowREM: Boolean;
FShowUNT: Boolean;
FInitialized: Boolean;
procedure WireUi;
procedure SetTextById(const Id, Value: string);
procedure SetHiddenById(const Id: string; Hidden: Boolean);
......@@ -56,8 +55,13 @@ type
function GetMemoTypeCode(const MemoType: string): string;
function MemoTypeLabel(const MemoType: string): string;
function MemoTypeInList(const memoType: string; const list: array of string): Boolean;
procedure SetRemarksData(dataArr: TJSArray);
function DeriveStatusFromDates(const dateDispatched, dateArrived, dateCleared: string): string;
public
class function CreateForm(const AHostId, AComplaintId: string): TFViewComplaintArchive;
class function CreateForm(const AHostId, AComplaintId: string): TWebForm;
procedure InitializeForm;
end;
implementation
......@@ -67,14 +71,32 @@ uses
{$R *.dfm}
class function TFViewComplaintArchive.CreateForm(const AHostId, AComplaintId: string): TFViewComplaintArchive;
class function TFViewComplaintArchive.CreateForm(const AHostId, AComplaintId: string): TWebForm;
procedure AfterCreate(AForm: TObject);
begin
with TFViewComplaintArchive(AForm) do
begin
FComplaintId := AComplaintId;
InitializeForm;
end;
end;
begin
Result := TFViewComplaintArchive(inherited CreateNew(AHostId));
Result.FComplaintId := AComplaintId;
Application.CreateForm(TFViewComplaintArchive, AHostId, Result, @AfterCreate);
end;
procedure TFViewComplaintArchive.WebFormCreate(Sender: TObject);
procedure TFViewComplaintArchive.InitializeForm;
begin
if FInitialized then
Exit;
FInitialized := True;
xdwcComplaintArchive.Connection := DMConnection.ApiConnection;
xdwdsRemarksArc.Connection := DMConnection.ApiConnection;
FAllMemos := nil;
FShowCMP := True;
......@@ -142,21 +164,27 @@ var
rootObj: TJSObject;
dataObj: TJSObject;
business: string;
dateDispatchedText: string;
dateArrivedText: string;
dateClearedText: string;
statusText: string;
begin
resp := await(xdwcComplaintArchive.RawInvokeAsync('IApiService.GetComplaintArchiveDetails', [FComplaintId]));
rootObj := TJSObject(resp.Result);
dataObj := TJSObject(rootObj['data']);
// Summary title (optional)
SetTextById('lbl_summary_title_arc', 'Summary');
SetTextById('lbl_summary_title_arc', 'Summary for Complaint ' + string(dataObj['Complaint']));
SetTextById('lbl_priority_arc', string(dataObj['Priority']));
SetTextById('lbl_dispatch_code_arc', string(dataObj['DispatchCodeDesc']));
SetTextById('lbl_dispatch_district_arc', string(dataObj['DispatchDistrict']));
SetTextById('lbl_address_arc', string(dataObj['Address']));
business := '';
if dataObj.hasOwnProperty('Business') then
business := string(dataObj['Business']);
if business <> '' then
if Trim(business) <> '' then
begin
SetTextById('lbl_business_arc', business);
SetHiddenById('row_business_arc', False);
......@@ -164,15 +192,30 @@ begin
else
SetHiddenById('row_business_arc', True);
// Status: same logic style as details; simplest is derive from timestamps if you want,
// but archive view can just show blank unless you prefer the full logic.
// If your archive endpoint includes a computed Status, you can display it directly.
dateDispatchedText := '';
dateArrivedText := '';
dateClearedText := '';
if dataObj.hasOwnProperty('DateDispatched') then
dateDispatchedText := string(dataObj['DateDispatched']);
if dataObj.hasOwnProperty('DateArrived') then
dateArrivedText := string(dataObj['DateArrived']);
if dataObj.hasOwnProperty('DateCleared') then
dateClearedText := string(dataObj['DateCleared']);
statusText := '';
if dataObj.hasOwnProperty('Status') then
SetTextById('lbl_status_arc', string(dataObj['Status']))
else
SetTextById('lbl_status_arc', '');
statusText := string(dataObj['Status']);
if Trim(statusText) = '' then
statusText := DeriveStatusFromDates(dateDispatchedText, dateArrivedText, dateClearedText);
// CFSId is needed for memos
SetTextById('lbl_status_arc', statusText);
FCfsId := '';
if dataObj.hasOwnProperty('CFSId') then
FCfsId := string(dataObj['CFSId']);
await(LoadMemosAsync);
......@@ -180,30 +223,41 @@ end;
function TFViewComplaintArchive.MemoTypeLabel(const MemoType: string): string;
var
c: string;
code: string;
begin
c := GetMemoTypeCode(MemoType);
if c = 'CMP' then Exit('CMP');
if c = 'E911' then Exit('E-911');
if c = 'REM' then Exit('REM');
if c = 'UNT' then Exit('UNT');
code := GetMemoTypeCode(MemoType);
if code = 'CMP' then
Exit('CMP');
if code = 'E911' then
Exit('E-911');
if code = 'REM' then
Exit('REM');
if code = 'UNT' then
Exit('UNT');
Result := MemoType;
end;
function TFViewComplaintArchive.GetMemoTypeCode(const MemoType: string): string;
var
mt: string;
memoTypeCode: string;
begin
mt := LowerCase(Trim(MemoType));
memoTypeCode := Trim(MemoType);
if MemoTypeInList(memoTypeCode, ['30', '31', '32', '33', '34']) then
Exit('UNT');
// Match whatever your server returns in GetComplaintMemos:
// Keep these mappings aligned with ComplaintDetails.
if (mt = 'cmp') or (mt = 'complaint') then Exit('CMP');
if (mt = 'e-911') or (mt = 'e911') then Exit('E911');
if (mt = 'rem') or (mt = 'remarks') then Exit('REM');
if (mt = 'unt') or (mt = 'unit') then Exit('UNT');
if MemoTypeInList(memoTypeCode, ['3', '4']) then
Exit('CMP');
Result := UpperCase(mt);
if MemoTypeInList(memoTypeCode, ['2']) then
Exit('E911');
if MemoTypeInList(memoTypeCode, ['1']) then
Exit('REM');
Result := memoTypeCode;
end;
[async] procedure TFViewComplaintArchive.LoadMemosAsync;
......@@ -218,6 +272,9 @@ begin
// Reset dataset
xdwdsRemarksArc.Close;
if Trim(FCfsId) = '' then
Exit;
resp := await(xdwcComplaintArchive.RawInvokeAsync('IApiService.GetComplaintMemos', [FCfsId]));
rootObj := TJSObject(resp.Result);
dataArr := TJSArray(rootObj['data']);
......@@ -265,8 +322,7 @@ begin
filtered.push(memoObj);
end;
xdwdsRemarksArc.SetJsonData(filtered);
xdwdsRemarksArc.Open;
SetRemarksData(filtered);
end;
procedure TFViewComplaintArchive.btnCmpArcClick(Sender: TObject);
......@@ -297,10 +353,36 @@ begin
ApplyMemoFilters;
end;
procedure TFViewComplaintArchive.btnComplaintViewOnMapArcClick(Sender: TObject);
function TFViewComplaintArchive.MemoTypeInList(const memoType: string; const list: array of string): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(list) to High(list) do
begin
if memoType = list[i] then
Exit(True);
end;
end;
procedure TFViewComplaintArchive.SetRemarksData(dataArr: TJSArray);
begin
xdwdsRemarksArc.Close;
xdwdsRemarksArc.SetJsonData(dataArr);
xdwdsRemarksArc.Open;
end;
function TFViewComplaintArchive.DeriveStatusFromDates(const dateDispatched, dateArrived, dateCleared: string): string;
begin
if Assigned(FViewMain) then
FViewMain.ShowMapFocusComplaint(FComplaintId);
if Trim(dateCleared) <> '' then
Exit('Cleared');
if Trim(dateArrived) <> '' then
Exit('On Scene');
if Trim(dateDispatched) <> '' then
Exit('Dispatched');
Result := 'Pending';
end;
end.
......@@ -373,6 +373,20 @@ object FViewComplaintDetails: TFViewComplaintDetails
WidthPercent = 100.000000000000000000
OnClick = btnComplaintViewOnMapClick
end
object btnArchive: TWebButton
Left = 612
Top = 165
Width = 96
Height = 25
Caption = 'Archive Details'
ChildOrder = 14
ElementID = 'btn_archive'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnArchiveClick
end
object xdwcComplaintDetails: TXDataWebClient
Connection = DMConnection.ApiConnection
Left = 384
......
......@@ -78,6 +78,11 @@
<button type="button" class="btn btn-success btn-sm px-3 active" id="btn_rem" aria-pressed="true">REM</button>
<button type="button" class="btn btn-success btn-sm px-3 active" id="btn_unt" aria-pressed="true">UNT</button>
</div>
<!-- History action row (only visible on History tab) -->
<div class="d-flex flex-wrap gap-2 justify-content-center mt-2 tab-hidden" id="row_history_actions">
<button type="button" class="btn btn-secondary btn-sm px-3 disabled" id="btn_archive" disabled>Archive</button>
</div>
</div>
</div>
......
......@@ -55,6 +55,7 @@ type
lstWarnings: TWebDBListControl;
btnComplaintViewOnMap: TWebButton;
xdwdsHistoryComplaintId: TStringField;
btnArchive: TWebButton;
procedure btnRemarksClick(Sender: TObject);
procedure btnHistoryClick(Sender: TObject);
......@@ -65,6 +66,7 @@ type
procedure btnE911Click(Sender: TObject);
procedure btnREMClick(Sender: TObject);
procedure btnUntClick(Sender: TObject);
procedure btnArchiveClick(Sender: TObject);
private
FComplaintId: string;
FCfsId: string;
......@@ -85,6 +87,9 @@ type
FContactsLoaded: Boolean;
FWarningsLoaded: Boolean;
FSelectedArchiveComplaintId: string;
FHistorySelectionBound: Boolean;
procedure WireUi;
procedure CloseClick(Event: TJSEvent);
......@@ -101,6 +106,11 @@ type
procedure UpdateTabButtonCss(const activeTabName: string);
procedure SetButtonEnabledById(const buttonId: string; enabled: Boolean);
procedure BindHistoryRowSelection;
procedure HistoryTableClick(Event: TJSEvent);
procedure ClearHistorySelection;
procedure SelectHistoryRowByIndex(rowIndex: Integer);
procedure ApplyRemarksFilters;
[async] procedure ApplyTabAsync(const tabName: string);
......@@ -163,6 +173,9 @@ begin
FContactsLoaded := False;
FWarningsLoaded := False;
FSelectedArchiveComplaintId := '';
FHistorySelectionBound := False;
WireUi;
LoadComplaintAsync;
end;
......@@ -174,6 +187,8 @@ begin
btnClose := Document.getElementById('btn_close_complaint_details');
if btnClose <> nil then
btnClose.addEventListener('click', @CloseClick);
BindHistoryRowSelection;
end;
procedure TFViewComplaintDetails.CloseClick(Event: TJSEvent);
......@@ -348,16 +363,121 @@ begin
end;
end;
procedure TFViewComplaintDetails.BindHistoryRowSelection;
var
el: TJSElement;
begin
if FHistorySelectionBound then
Exit;
el := Document.getElementById('tbl_history');
if el = nil then
Exit;
el.addEventListener('click', @HistoryTableClick);
FHistorySelectionBound := True;
end;
procedure TFViewComplaintDetails.HistoryTableClick(Event: TJSEvent);
var
rowIndex: Integer;
begin
rowIndex := -1;
asm
var target = Event.target;
var row = target.closest('tbody tr');
if (!row) {
return;
}
var rows = Array.prototype.slice.call(row.parentNode.children);
rows.forEach(function(r) {
r.classList.remove('table-primary');
});
row.classList.add('table-primary');
rowIndex = rows.indexOf(row);
end;
SelectHistoryRowByIndex(rowIndex);
end;
procedure TFViewComplaintDetails.ClearHistorySelection;
begin
FSelectedArchiveComplaintId := '';
SetButtonEnabledById('btn_archive', False);
asm
var host = document.getElementById('tbl_history');
if (host) {
var rows = host.querySelectorAll('tbody tr');
rows.forEach(function(row) {
row.classList.remove('table-primary');
});
}
end;
end;
procedure TFViewComplaintDetails.SelectHistoryRowByIndex(rowIndex: Integer);
var
i: Integer;
begin
FSelectedArchiveComplaintId := '';
if rowIndex < 0 then
begin
SetButtonEnabledById('btn_archive', False);
Exit;
end;
if not xdwdsHistory.Active then
begin
SetButtonEnabledById('btn_archive', False);
Exit;
end;
xdwdsHistory.First;
for i := 0 to rowIndex - 1 do
begin
if xdwdsHistory.Eof then
Break;
xdwdsHistory.Next;
end;
if xdwdsHistory.Eof then
begin
SetButtonEnabledById('btn_archive', False);
Exit;
end;
FSelectedArchiveComplaintId := xdwdsHistory.FieldByName('ComplaintId').AsString;
SetButtonEnabledById('btn_archive', Trim(FSelectedArchiveComplaintId) <> '');
end;
procedure TFViewComplaintDetails.SetActiveTab(const tabName: string);
begin
SetHiddenById('tbl_remarks', tabName <> 'remarks');
SetHiddenById('tbl_history', tabName <> 'history');
if tabName <> 'history' then
ClearHistorySelection;
SetHiddenById('tbl_contacts', tabName <> 'contacts');
SetHiddenById('tbl_warnings', tabName <> 'warnings');
SetHiddenById('lst_warnings', tabName <> 'warnings');
SetHiddenById('row_remarks_toggles', tabName <> 'remarks');
SetHiddenById('row_history_actions', tabName <> 'history');
UpdateTabButtonCss(tabName);
end;
......@@ -497,6 +617,15 @@ begin
ApplyTabAsync('warnings');
end;
procedure TFViewComplaintDetails.btnArchiveClick(Sender: TObject);
begin
if Trim(FSelectedArchiveComplaintId) = '' then
Exit;
if Assigned(FViewMain) then
FViewMain.ShowComplaintArchive(FSelectedArchiveComplaintId);
end;
procedure TFViewComplaintDetails.btnCmpClick(Sender: TObject);
begin
FShowCmp := not FShowCmp;
......@@ -684,6 +813,9 @@ begin
dataArr := TJSArray(rootObj['data']);
SetDataSetJsonData(xdwdsHistory, dataArr);
BindHistoryRowSelection;
ClearHistorySelection;
FHistoryLoaded := True;
end;
......
......@@ -206,7 +206,7 @@ object FViewMain: TFViewMain
ChildOrder = 15
ElementFont = efCSS
TabOrder = 10
object WebButton1: TWebButton
object btnArchiveModalClose: TWebButton
Left = 127
Top = 8
Width = 28
......@@ -216,7 +216,7 @@ object FViewMain: TFViewMain
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnDetailsModalCloseClick
OnClick = btnArchiveModalCloseClick
end
end
object xdwcBadgeCounts: TXDataWebClient
......
......@@ -21,8 +21,6 @@
<div id="pnl_map" class="flex-grow-1 position-relative p-0 overflow-hidden" style="min-height:0;"></div>
<div id="pnl_units" class="flex-grow-1 position-relative p-0 overflow-hidden d-none" style="min-height:0;"></div>
<div id="pnl_complaints" class="flex-grow-1 position-relative p-0 overflow-hidden d-none" style="min-height:0;"></div>
<div id="pnl_archive" class="flex-grow-1 position-relative p-0 overflow-hidden d-none" style="min-height:0;"></div>
<!-- Details modal (new panel pnl_details) -->
<div id="pnl_details"
......@@ -39,6 +37,21 @@
</div>
</div>
<!-- Archive details modal -->
<div id="pnl_archive"
class="position-fixed top-0 start-0 w-100 h-100 d-none d-flex justify-content-center align-items-center"
style="background: rgba(0,0,0,0.35); z-index:1070;">
<div class="card shadow-lg w-100 mx-2 d-flex flex-column" style="max-width: 96vw; height: 92%;">
<div class="card-header d-flex align-items-center justify-content-between">
<h5 class="card-title mb-0" id="lbl_archive_title">Archived Complaint Details</h5>
<button id="btn_archive_modal_close" type="button" class="btn-close" aria-label="Close"></button>
</div>
<div class="card-body p-0 flex-grow-1 overflow-hidden" style="min-height:0;">
<div id="pnl_archive_host" class="h-100"></div>
</div>
</div>
</div>
<!-- Bottom Nav -->
<nav id="bottom_nav" class="navbar navbar-dark bg-primary py-2 flex-shrink-0">
<div class="container-fluid">
......
......@@ -31,7 +31,7 @@ type
pnlDetails: TWebPanel;
btnDetailsModalClose: TWebButton;
pnlArchive: TWebPanel;
WebButton1: TWebButton;
btnArchiveModalClose: TWebButton;
procedure WebFormCreate(Sender: TObject);
procedure mnuLogoutClick(Sender: TObject);
procedure wllblLogoutClick(Sender: TObject);
......@@ -41,6 +41,7 @@ type
procedure tmrBadgeCountsTimer(Sender: TObject);
procedure tmrGlobalRefreshTimer(Sender: TObject);
procedure btnDetailsModalCloseClick(Sender: TObject);
procedure btnArchiveModalCloseClick(Sender: TObject);
private
{ Private declarations }
FUserInfo: string;
......@@ -49,12 +50,15 @@ type
FUnitsForm: TFViewUnits;
FComplaintsForm: TFViewComplaints;
FDetailsForm: TWebForm;
FArchiveForm: TWebForm;
FLogoutProc: TLogoutProc;
[async] procedure RefreshBadgesAsync;
procedure ShowUnitDetails(UnitId: string);
procedure SetHeaderTitle(const title: string);
procedure HideDetailsModal;
procedure ShowDetailsModal(const titleText: string);
procedure HideArchiveModal;
procedure ShowArchiveModal(const titleText: string);
type TActivePanel = (apNone, apMap, apUnits, apComplaints);
var
......@@ -74,6 +78,7 @@ type
class procedure Display(LogoutProc: TLogoutProc);
procedure ShowForm( AFormClass: TWebFormClass );
procedure ShowComplaintDetails(ComplaintId: string);
procedure ShowComplaintArchive(ComplaintId: string);
procedure SetActiveNavButton(const BtnId: string);
procedure ShowMapFocusUnit(const unitId: string);
procedure ShowMapFocusComplaint(const complaintId: string);
......@@ -95,12 +100,14 @@ uses
View.Users,
View.EditUser,
View.UnitDetails,
View.ComplaintArchive,
Utils;
{$R *.dfm}
const
DETAILS_HOST_ID = 'pnl_details_host';
ARCHIVE_HOST_ID = 'pnl_archive_host';
procedure TFViewMain.WebFormCreate(Sender: TObject);
var
......@@ -110,6 +117,7 @@ begin
lblUsername.Caption := ' ' + userName.ToLower + ' ';
FChildForm := nil;
FDetailsForm := nil;
FArchiveForm := nil;
FActivePanel := apNone;
FGlobalRefreshTick := 0;
......@@ -127,6 +135,7 @@ begin
HidePanel(pnlUnits);
HidePanel(pnlComplaints);
HidePanel(pnlDetails);
HidePanel(pnlArchive);
if not Assigned(FMapForm) then
begin
......@@ -226,6 +235,11 @@ begin
end;
procedure TFViewMain.btnArchiveModalCloseClick(Sender: TObject);
begin
HideArchiveModal;
end;
procedure TFViewMain.btnComplaintsClick(Sender: TObject);
begin
ShowForm(TFViewComplaints);
......@@ -234,6 +248,7 @@ end;
procedure TFViewMain.btnDetailsModalCloseClick(Sender: TObject);
begin
HideArchiveModal;
HideDetailsModal;
end;
......@@ -260,6 +275,7 @@ end;
procedure TFViewMain.ShowForm(AFormClass: TWebFormClass);
begin
HideArchiveModal;
HideDetailsModal;
if AFormClass = TFViewMap then
......@@ -374,6 +390,16 @@ begin
FDetailsForm := TFViewComplaintDetails.CreateForm(DETAILS_HOST_ID, ComplaintId);
end;
procedure TFViewMain.ShowComplaintArchive(ComplaintId: string);
begin
ShowArchiveModal('Archived Complaint Details');
if Assigned(FArchiveForm) then
FArchiveForm.Free;
FArchiveForm := TFViewComplaintArchive.CreateForm(ARCHIVE_HOST_ID, ComplaintId);
end;
procedure TFViewMain.ShowUnitDetails(UnitId: string);
begin
ShowDetailsModal('Unit Details');
......@@ -509,4 +535,27 @@ begin
end;
procedure TFViewMain.HideArchiveModal;
begin
HidePanel(pnlArchive);
if Assigned(FArchiveForm) then
begin
FArchiveForm.Free;
FArchiveForm := nil;
end;
end;
procedure TFViewMain.ShowArchiveModal(const titleText: string);
var
el: TJSElement;
begin
ShowPanel(pnlArchive);
el := Document.getElementById('lbl_archive_title');
if el <> nil then
el.innerHTML := titleText;
end;
end.
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