Commit 2607279b by Mac Stephens

wip - finishing task items from 630

parent 8ef6fb7a
...@@ -43,8 +43,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -43,8 +43,7 @@ object ApiDatabaseModule: TApiDatabaseModule
'LEFT JOIN PERSONNEL p1 ON p1.PF_NAMEID = dua.OFFICER1ID' 'LEFT JOIN PERSONNEL p1 ON p1.PF_NAMEID = dua.OFFICER1ID'
'LEFT JOIN PERSONNEL p2 ON p2.PF_NAMEID = dua.OFFICER2ID' 'LEFT JOIN PERSONNEL p2 ON p2.PF_NAMEID = dua.OFFICER2ID'
'WHERE uc.GPS_LATITUDE IS NOT NULL' 'WHERE uc.GPS_LATITUDE IS NOT NULL'
' AND uc.GPS_LONGITUDE IS NOT NULL' ' AND uc.GPS_LONGITUDE IS NOT NULL')
' AND ag.AGENCYTYPE = '#39'POL'#39)
ReadOnly = True ReadOnly = True
Left = 466 Left = 466
Top = 390 Top = 390
...@@ -447,12 +446,12 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -447,12 +446,12 @@ object ApiDatabaseModule: TApiDatabaseModule
'ECTOR AND cs.CODE_TYPE = cd.AGENCYCODE' 'ECTOR AND cs.CODE_TYPE = cd.AGENCYCODE'
'WHERE ca.COMPLAINT IS NOT NULL' 'WHERE ca.COMPLAINT IS NOT NULL'
'ORDER BY COALESCE(cd.CODE_DESC, '#39#39'), ct.DATEREPORTED DESC, ca.PR' + 'ORDER BY COALESCE(ca.AGENCY, '#39#39'), ct.DATEREPORTED DESC, ca.PRIOR' +
'IORITY DESC') 'ITY DESC')
ReadOnly = True ReadOnly = True
OnCalcFields = uqComplaintListCalcFields OnCalcFields = uqComplaintListCalcFields
Left = 78 Left = 80
Top = 244 Top = 248
object uqComplaintListcomplaintid: TFloatField object uqComplaintListcomplaintid: TFloatField
FieldName = 'complaintid' FieldName = 'complaintid'
Required = True Required = True
...@@ -676,7 +675,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -676,7 +675,7 @@ object ApiDatabaseModule: TApiDatabaseModule
'WHERE ca.COMPLAINTID = :COMPLAINTID;' 'WHERE ca.COMPLAINTID = :COMPLAINTID;'
'') '')
ReadOnly = True ReadOnly = True
Left = 80 Left = 82
Top = 302 Top = 302
ParamData = < ParamData = <
item item
...@@ -824,20 +823,26 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -824,20 +823,26 @@ object ApiDatabaseModule: TApiDatabaseModule
'SELECT' 'SELECT'
' ca.COMPLAINTID,' ' ca.COMPLAINTID,'
' cd.CODE_DESC AS DISPATCHDISTRICT,' ' cd.CODE_DESC AS DISPATCHDISTRICT,'
' ca.AGENCY AS AGENCY,'
' ag.AGENCYNAME AS AGENCY_NAME,'
' ca.PRIORITY AS PRIORITY,' ' ca.PRIORITY AS PRIORITY,'
' ca.BUSINESS,' ' ca.BUSINESS,'
' cdc.CATEGORY AS DISPATCHCODECATEGORY,' ' cdc.CATEGORY AS DISPATCHCODECATEGORY,'
'' ''
' ST_X(' ' ST_X('
' ST_Transform(' ' ST_Transform('
' ST_SetSRID(ST_MakePoint(ca.XCOORD, ca.YCOORD), 2262),'
' ST_SetSRID(ST_MakePoint(ca.XCOORD::double precision, ca.YC' +
'OORD::double precision), 2262),'
' 4326' ' 4326'
' )' ' )'
' ) AS LNG,' ' ) AS LNG,'
'' ''
' ST_Y(' ' ST_Y('
' ST_Transform(' ' ST_Transform('
' ST_SetSRID(ST_MakePoint(ca.XCOORD, ca.YCOORD), 2262),'
' ST_SetSRID(ST_MakePoint(ca.XCOORD::double precision, ca.YC' +
'OORD::double precision), 2262),'
' 4326' ' 4326'
' )' ' )'
' ) AS LAT,' ' ) AS LAT,'
...@@ -851,6 +856,8 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -851,6 +856,8 @@ object ApiDatabaseModule: TApiDatabaseModule
' ON cdc.CODE = ca.DISPATCHCODE' ' ON cdc.CODE = ca.DISPATCHCODE'
'LEFT JOIN CD_DISTRICT cd' 'LEFT JOIN CD_DISTRICT cd'
' ON cd.AGENCYCODE = ca.DISPATCHDISTRICT' ' ON cd.AGENCYCODE = ca.DISPATCHDISTRICT'
'LEFT JOIN AGENCY ag'
' ON ag.AGENCYID = ca.AGENCY'
'WHERE ca.COMPLAINT IS NOT NULL' 'WHERE ca.COMPLAINT IS NOT NULL'
' AND ca.XCOORD IS NOT NULL' ' AND ca.XCOORD IS NOT NULL'
' AND ca.YCOORD IS NOT NULL') ' AND ca.YCOORD IS NOT NULL')
...@@ -907,6 +914,15 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -907,6 +914,15 @@ object ApiDatabaseModule: TApiDatabaseModule
FieldName = 'pngName' FieldName = 'pngName'
Calculated = True Calculated = True
end end
object uqMapComplaintsagency: TStringField
FieldName = 'agency'
Size = 6
end
object uqMapComplaintsagency_name: TStringField
FieldName = 'agency_name'
ReadOnly = True
Size = 40
end
end end
object uqBadgeCounts: TUniQuery object uqBadgeCounts: TUniQuery
Connection = ucENTCAD Connection = ucENTCAD
...@@ -923,7 +939,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -923,7 +939,7 @@ object ApiDatabaseModule: TApiDatabaseModule
' where ag.AGENCYTYPE = '#39'POL'#39') as Units') ' where ag.AGENCYTYPE = '#39'POL'#39') as Units')
ReadOnly = True ReadOnly = True
Left = 200 Left = 200
Top = 190 Top = 192
object uqBadgeCountscomplaints: TLargeintField object uqBadgeCountscomplaints: TLargeintField
FieldName = 'complaints' FieldName = 'complaints'
ReadOnly = True ReadOnly = True
......
...@@ -195,6 +195,8 @@ type ...@@ -195,6 +195,8 @@ type
uqMapUnitsofficer2_lname: TStringField; uqMapUnitsofficer2_lname: TStringField;
uqMapUnitsofficer2_fname: TStringField; uqMapUnitsofficer2_fname: TStringField;
uqMapUnitsofficer2_empnum: TStringField; uqMapUnitsofficer2_empnum: TStringField;
uqMapComplaintsagency: TStringField;
uqMapComplaintsagency_name: TStringField;
procedure uqComplaintListCalcFields(DataSet: TDataSet); procedure uqComplaintListCalcFields(DataSet: TDataSet);
procedure uqMapComplaintsCalcFields(DataSet: TDataSet); procedure uqMapComplaintsCalcFields(DataSet: TDataSet);
procedure DataModuleCreate(Sender: TObject); procedure DataModuleCreate(Sender: TObject);
......
...@@ -154,6 +154,8 @@ begin ...@@ -154,6 +154,8 @@ begin
item.AddPair('ComplaintId',ApiDB.uqMapComplaintsCOMPLAINTID.AsString); item.AddPair('ComplaintId',ApiDB.uqMapComplaintsCOMPLAINTID.AsString);
item.AddPair('DispatchDistrict', ApiDB.uqMapComplaintsDISPATCHDISTRICT.AsString); item.AddPair('DispatchDistrict', ApiDB.uqMapComplaintsDISPATCHDISTRICT.AsString);
item.AddPair('Agency', ApiDB.uqMapComplaintsAGENCY.AsString);
item.AddPair('AgencyName', ApiDB.uqMapComplaintsAGENCY_NAME.AsString);
item.AddPair('DispatchCodeDesc',ApiDB.uqMapComplaintsDISPATCH_CODE_DESC.AsString); item.AddPair('DispatchCodeDesc',ApiDB.uqMapComplaintsDISPATCH_CODE_DESC.AsString);
item.AddPair('DispatchCodeCategory',ApiDB.uqMapComplaintsDISPATCHCODECATEGORY.AsString); item.AddPair('DispatchCodeCategory',ApiDB.uqMapComplaintsDISPATCHCODECATEGORY.AsString);
item.AddPair('Priority',ApiDB.uqMapComplaintsPRIORITY.AsString); item.AddPair('Priority',ApiDB.uqMapComplaintsPRIORITY.AsString);
...@@ -225,6 +227,7 @@ begin ...@@ -225,6 +227,7 @@ begin
item.AddPair('UnitId', ApiDB.uqMapUnitsUNITID.AsString); item.AddPair('UnitId', ApiDB.uqMapUnitsUNITID.AsString);
item.AddPair('UnitName', ApiDB.uqMapUnitsUNITNAME.AsString); item.AddPair('UnitName', ApiDB.uqMapUnitsUNITNAME.AsString);
item.AddPair('UnitBadge', ApiDB.uqMapUnitsUNITNAME.AsString);
item.AddPair('Agency', ApiDB.uqMapUnitsAGENCY.AsString); item.AddPair('Agency', ApiDB.uqMapUnitsAGENCY.AsString);
item.AddPair('AgencyName', ApiDB.uqMapUnitsAGENCY_NAME.AsString); item.AddPair('AgencyName', ApiDB.uqMapUnitsAGENCY_NAME.AsString);
...@@ -311,13 +314,15 @@ begin ...@@ -311,13 +314,15 @@ begin
var item := TJSONObject.Create; var item := TJSONObject.Create;
var curDistrict := ApiDB.uqComplaintListDISPATCHDISTRICT.AsString; var curAgency := Trim(ApiDB.uqComplaintListAGENCY.AsString);
if not SameText(curDistrict, lastDistrict) then if curAgency = '' then
item.AddPair('DistrictHeader', curDistrict); curAgency := 'Unknown Agency';
lastDistrict := curDistrict;
var districtSector := ApiDB.uqComplaintListDISTRICT_DESC.AsString + ApiDB.uqComplaintListSECTOR_DESC.AsString; if not SameText(curAgency, lastDistrict) then
item.AddPair('DistrictSector', districtSector); item.AddPair('DistrictHeader', curAgency);
lastDistrict := curAgency;
item.AddPair('DistrictSector', 'Agency: ' + curAgency);
var colorVal := ApiDB.uqComplaintListPRIORITY_COLOR.AsInteger; var colorVal := ApiDB.uqComplaintListPRIORITY_COLOR.AsInteger;
item.AddPair('PriorityColor', '#' + IntToHex(colorVal and $FFFFFF, 6)); item.AddPair('PriorityColor', '#' + IntToHex(colorVal and $FFFFFF, 6));
...@@ -336,7 +341,7 @@ begin ...@@ -336,7 +341,7 @@ begin
item.AddPair('Business', ApiDB.uqComplaintListBUSINESS.AsString); item.AddPair('Business', ApiDB.uqComplaintListBUSINESS.AsString);
item.AddPair('CFSId', ApiDB.uqComplaintListCFSID.AsString); item.AddPair('CFSId', ApiDB.uqComplaintListCFSID.AsString);
item.AddPair('Status', status); item.AddPair('Status', status);
item.AddPair('DispatchDistrict', curDistrict); item.AddPair('DispatchDistrict', ApiDB.uqComplaintListDISPATCHDISTRICT.AsString);
item.AddPair('DateReported', ApiDB.uqComplaintListDATEREPORTED.AsString); item.AddPair('DateReported', ApiDB.uqComplaintListDATEREPORTED.AsString);
data.AddElement(item); data.AddElement(item);
......
...@@ -58,9 +58,3 @@ begin ...@@ -58,9 +58,3 @@ begin
end; end;
end. end.
constructor TAgencyItem.Create(AAgency: String);
begin
agency := AAgency;
end;
end.
...@@ -77,7 +77,7 @@ begin ...@@ -77,7 +77,7 @@ begin
authDB.uqAuth.SQL.Text := authDB.uqAuth.SQL.Text :=
'select agencyid as agency ' + 'select agencyid as agency ' +
'from lems.agency ' + 'from lems.agency ' +
'where agencytype = ''POL'' ' + 'where login = ''T'' ' +
'order by agencyid'; 'order by agencyid';
authDB.uqAuth.Open; authDB.uqAuth.Open;
...@@ -119,7 +119,7 @@ begin ...@@ -119,7 +119,7 @@ begin
sql := 'select agencyid, agencyname ' + sql := 'select agencyid, agencyname ' +
'from lems.agency ' + 'from lems.agency ' +
'where agencytype = ''POL'' ' + 'where login = ''T'' ' +
'order by agencyname'; 'order by agencyname';
authDB.uqAuth.SQL.Text := sql; authDB.uqAuth.SQL.Text := sql;
......
[Settings] [Settings]
LogFileNum=695 LogFileNum=706
webClientVersion=0.1.0 webClientVersion=0.1.0
[Database] [Database]
......
...@@ -53,8 +53,8 @@ ...@@ -53,8 +53,8 @@
</button> </button>
</div> </div>
<div class="card-footer text-muted small"> <div class="card-footer text-muted small">
Please use your CHARMS username &amp; password to login.<br><br> Please use your lems username &amp; password to login.<br><br>
For non-CHARMS users, please call the CPS Help Desk at For non-lems users, please call the CPS Help Desk at
(716) 858-7773 during business hours<br> (716) 858-7773 during business hours<br>
or email: <a href="mailto:CPSHelpdesk@erie.gov">CPSHelpdesk@erie.gov</a> or email: <a href="mailto:CPSHelpdesk@erie.gov">CPSHelpdesk@erie.gov</a>
</div> </div>
......
...@@ -16,18 +16,6 @@ object FViewMain: TFViewMain ...@@ -16,18 +16,6 @@ object FViewMain: TFViewMain
Visible = False Visible = False
WidthPercent = 100.000000000000000000 WidthPercent = 100.000000000000000000
end end
object wllblLogout: TWebLinkLabel
Left = 551
Top = 85
Width = 41
Height = 15
ElementID = 'dropdown.menu.logout'
Visible = False
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = wllblLogoutClick
Caption = ' Logout'
end
object lblAppTitle: TWebLabel object lblAppTitle: TWebLabel
Left = 57 Left = 57
Top = 31 Top = 31
...@@ -82,6 +70,18 @@ object FViewMain: TFViewMain ...@@ -82,6 +70,18 @@ object FViewMain: TFViewMain
ElementID = 'pnl_main' ElementID = 'pnl_main'
ChildOrder = 3 ChildOrder = 3
TabOrder = 0 TabOrder = 0
object WebButton1: TWebButton
Left = 456
Top = 20
Width = 96
Height = 25
Caption = 'WebButton1'
ElementClassName = 'btn btn-light'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
end
end end
object WebMessageDlg1: TWebMessageDlg object WebMessageDlg1: TWebMessageDlg
Left = 47 Left = 47
...@@ -219,6 +219,20 @@ object FViewMain: TFViewMain ...@@ -219,6 +219,20 @@ object FViewMain: TFViewMain
OnClick = btnArchiveModalCloseClick OnClick = btnArchiveModalCloseClick
end end
end end
object btnLogout: TWebButton
Left = 438
Top = 66
Width = 96
Height = 25
Caption = 'Logout'
ChildOrder = 16
ElementID = 'btn_logout'
ElementFont = efCSS
HeightStyle = ssAuto
HeightPercent = 100.000000000000000000
WidthPercent = 100.000000000000000000
OnClick = btnLogoutClick
end
object xdwcBadgeCounts: TXDataWebClient object xdwcBadgeCounts: TXDataWebClient
Connection = DMConnection.ApiConnection Connection = DMConnection.ApiConnection
Left = 44 Left = 44
......
...@@ -11,8 +11,12 @@ ...@@ -11,8 +11,12 @@
<span id="lbl_main_title" class="navbar-brand text-light mb-0 ms-1"></span> <span id="lbl_main_title" class="navbar-brand text-light mb-0 ms-1"></span>
</div> </div>
<!-- Right: Connection label --> <!-- Right: Connection / Logout -->
<span id="view.main.lblconnection" class="navbar-text text-light ms-auto"></span>
<div class="d-flex align-items-center gap-2 ms-auto">
<span id="view.main.lblconnection" class="navbar-text text-light small"></span>
<button id="btn_logout" type="button" class="btn btn-outline-light btn-sm">Logout</button>
</div>
</div> </div>
</nav> </nav>
......
...@@ -11,7 +11,6 @@ uses ...@@ -11,7 +11,6 @@ uses
type type
TFViewMain = class(TWebForm) TFViewMain = class(TWebForm)
lblUsername: TWebLabel; lblUsername: TWebLabel;
wllblLogout: TWebLinkLabel;
pnlMain: TWebPanel; pnlMain: TWebPanel;
WebMessageDlg1: TWebMessageDlg; WebMessageDlg1: TWebMessageDlg;
lblAppTitle: TWebLabel; lblAppTitle: TWebLabel;
...@@ -32,9 +31,11 @@ type ...@@ -32,9 +31,11 @@ type
btnDetailsModalClose: TWebButton; btnDetailsModalClose: TWebButton;
pnlArchive: TWebPanel; pnlArchive: TWebPanel;
btnArchiveModalClose: TWebButton; btnArchiveModalClose: TWebButton;
WebButton1: TWebButton;
btnLogout: TWebButton;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure mnuLogoutClick(Sender: TObject); procedure mnuLogoutClick(Sender: TObject);
procedure wllblLogoutClick(Sender: TObject); procedure lblLogoutClick(Sender: TObject);
procedure btnUnitsClick(Sender: TObject); procedure btnUnitsClick(Sender: TObject);
procedure btnComplaintsClick(Sender: TObject); procedure btnComplaintsClick(Sender: TObject);
procedure btnMapClick(Sender: TObject); procedure btnMapClick(Sender: TObject);
...@@ -42,6 +43,7 @@ type ...@@ -42,6 +43,7 @@ type
procedure tmrGlobalRefreshTimer(Sender: TObject); procedure tmrGlobalRefreshTimer(Sender: TObject);
procedure btnDetailsModalCloseClick(Sender: TObject); procedure btnDetailsModalCloseClick(Sender: TObject);
procedure btnArchiveModalCloseClick(Sender: TObject); procedure btnArchiveModalCloseClick(Sender: TObject);
procedure btnLogoutClick(Sender: TObject);
private private
{ Private declarations } { Private declarations }
FUserInfo: string; FUserInfo: string;
...@@ -229,7 +231,7 @@ begin ...@@ -229,7 +231,7 @@ begin
end; end;
procedure TFViewMain.wllblLogoutClick(Sender: TObject); procedure TFViewMain.lblLogoutClick(Sender: TObject);
begin begin
FLogoutProc; FLogoutProc;
end; end;
...@@ -252,6 +254,11 @@ begin ...@@ -252,6 +254,11 @@ begin
HideDetailsModal; HideDetailsModal;
end; end;
procedure TFViewMain.btnLogoutClick(Sender: TObject);
begin
FLogoutProc;
end;
procedure TFViewMain.btnMapClick(Sender: TObject); procedure TFViewMain.btnMapClick(Sender: TObject);
begin begin
ShowForm(TFViewMap); ShowForm(TFViewMap);
......
...@@ -8,7 +8,7 @@ uses ...@@ -8,7 +8,7 @@ uses
WEBLib.ExtCtrls, DB, WEBLib.WebCtrls, WEBLib.REST, VCL.TMSFNCTypes, VCL.TMSFNCUtils, WEBLib.ExtCtrls, DB, WEBLib.WebCtrls, WEBLib.REST, VCL.TMSFNCTypes, VCL.TMSFNCUtils,
VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, VCL.TMSFNCCustomControl, VCL.TMSFNCWebBrowser, VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, VCL.TMSFNCCustomControl, VCL.TMSFNCWebBrowser,
VCL.TMSFNCMaps, VCL.TMSFNCLeaflet, VCL.TMSFNCMapsCommonTypes, System.StrUtils, XData.Web.Client, VCL.TMSFNCMaps, VCL.TMSFNCLeaflet, VCL.TMSFNCMapsCommonTypes, System.StrUtils, XData.Web.Client,
XData.Web.Connection, ConnectionModule, Utils, uMapFilters; XData.Web.Connection, ConnectionModule, Utils, uMapFilters, JS, Web;
type type
TFViewMap = class(TWebForm) TFViewMap = class(TWebForm)
...@@ -48,6 +48,8 @@ type ...@@ -48,6 +48,8 @@ type
procedure ApplyPendingComplaintFocus; procedure ApplyPendingComplaintFocus;
procedure StartGeoJsonLoad; procedure StartGeoJsonLoad;
procedure LoadGeoJsonLayer(const AResponse, ALayerName: string; FitLayer: Boolean); procedure LoadGeoJsonLayer(const AResponse, ALayerName: string; FitLayer: Boolean);
function GetJsonString(obj: TJSObject; name: string): string;
function HtmlAttrEncode(const value: string): string;
public public
procedure FocusUnit(const unitId: string); procedure FocusUnit(const unitId: string);
procedure FocusComplaint(const complaintId: string); procedure FocusComplaint(const complaintId: string);
...@@ -59,9 +61,6 @@ var ...@@ -59,9 +61,6 @@ var
implementation implementation
uses
JS, Web;
{$R *.dfm} {$R *.dfm}
procedure TFViewMap.lfMapMapInitialized(Sender: TObject); procedure TFViewMap.lfMapMapInitialized(Sender: TObject);
...@@ -176,7 +175,7 @@ begin ...@@ -176,7 +175,7 @@ begin
if SameText(ALayerName, 'Towns') then if SameText(ALayerName, 'Towns') then
begin begin
P.FillColor := HTMLToColor('#ffffff'); P.FillColor := HTMLToColor('#ffffff');
P.FillOpacity := 0.05; P.FillOpacity := 0.0;
P.StrokeColor := HTMLToColor('#000000'); P.StrokeColor := HTMLToColor('#000000');
P.StrokeOpacity := 1.0; P.StrokeOpacity := 1.0;
P.StrokeWidth := 2; P.StrokeWidth := 2;
...@@ -184,7 +183,7 @@ begin ...@@ -184,7 +183,7 @@ begin
else if SameText(ALayerName, 'Villages') then else if SameText(ALayerName, 'Villages') then
begin begin
P.FillColor := HTMLToColor('#0d6efd'); P.FillColor := HTMLToColor('#0d6efd');
P.FillOpacity := 0.20; P.FillOpacity := 0.0;
P.StrokeColor := HTMLToColor('#0d6efd'); P.StrokeColor := HTMLToColor('#0d6efd');
P.StrokeOpacity := 1.0; P.StrokeOpacity := 1.0;
P.StrokeWidth := 2; P.StrokeWidth := 2;
...@@ -238,6 +237,34 @@ begin ...@@ -238,6 +237,34 @@ begin
end; end;
function TFViewMap.GetJsonString(obj: TJSObject; name: string): string;
begin
Result := '';
if obj = nil then
Exit;
if obj[name] = nil then
Exit;
Result := string(obj[name]);
if SameText(Trim(Result), 'undefined') or SameText(Trim(Result), 'null') then
Result := '';
end;
function TFViewMap.HtmlAttrEncode(const value: string): string;
begin
Result := value;
Result := StringReplace(Result, '&', '&amp;', [rfReplaceAll]);
Result := StringReplace(Result, '"', '&quot;', [rfReplaceAll]);
Result := StringReplace(Result, #39, '&#39;', [rfReplaceAll]);
Result := StringReplace(Result, '<', '&lt;', [rfReplaceAll]);
Result := StringReplace(Result, '>', '&gt;', [rfReplaceAll]);
end;
[async] procedure TFViewMap.LoadPointsAsync(showBusy: Boolean); [async] procedure TFViewMap.LoadPointsAsync(showBusy: Boolean);
var var
resp: TXDataClientResponse; resp: TXDataClientResponse;
...@@ -246,9 +273,9 @@ var ...@@ -246,9 +273,9 @@ var
i, ui: Integer; i, ui: Integer;
m: TTMSFNCMapsMarker; m: TTMSFNCMapsMarker;
lat, lng: Double; lat, lng: Double;
uName, agency: string; uName, unitBadge, agencyId, agencyName, agency: string;
unitId, callType, priorityText, statusText: string; unitId, callType, priorityText, statusText: string;
complaintId, codeDesc, priority, business: string; complaintId, codeDesc, priority, business, address: string;
pngName, iconUrl, rowsHtml: string; pngName, iconUrl, rowsHtml: string;
officer1Lname, officer1Fname, officer1Empnum: string; officer1Lname, officer1Fname, officer1Empnum: string;
officer2Lname, officer2Fname, officer2Empnum: string; officer2Lname, officer2Fname, officer2Empnum: string;
...@@ -316,24 +343,33 @@ begin ...@@ -316,24 +343,33 @@ begin
lat := Double(item['Lat']); lat := Double(item['Lat']);
lng := Double(item['Lng']); lng := Double(item['Lng']);
uName := string(item['UnitName']); uName := GetJsonString(item, 'UnitName');
agency := string(item['AgencyName']); unitId := GetJsonString(item, 'UnitId');
unitBadge := GetJsonString(item, 'UnitBadge');
if Trim(unitBadge) = '' then
unitBadge := uName;
if Trim(unitBadge) = '' then
unitBadge := unitId;
agencyId := GetJsonString(item, 'Agency');
agencyName := GetJsonString(item, 'AgencyName');
agency := agencyName;
if Trim(agency) = '' then if Trim(agency) = '' then
agency := string(item['Agency']); agency := agencyId;
unitId := string(item['UnitId']); callType := GetJsonString(item, 'CallType');
callType := string(item['CallType']); priorityText := GetJsonString(item, 'Priority');
priorityText := string(item['Priority']); statusText := GetJsonString(item, 'Status');
statusText := string(item['Status']); updateTimeText := GetJsonString(item, 'UpdateTime');
updateTimeText := string(item['UpdateTime']);
officer1Lname := string(item['Officer1Lname']); officer1Lname := GetJsonString(item, 'Officer1Lname');
officer1Fname := string(item['Officer1Fname']); officer1Fname := GetJsonString(item, 'Officer1Fname');
officer1Empnum := string(item['Officer1Empnum']); officer1Empnum := GetJsonString(item, 'Officer1Empnum');
officer2Lname := string(item['Officer2Lname']); officer2Lname := GetJsonString(item, 'Officer2Lname');
officer2Fname := string(item['Officer2Fname']); officer2Fname := GetJsonString(item, 'Officer2Fname');
officer2Empnum := string(item['Officer2Empnum']); officer2Empnum := GetJsonString(item, 'Officer2Empnum');
canShowDetailsText := ''; canShowDetailsText := '';
if item['CanShowDetails'] <> nil then if item['CanShowDetails'] <> nil then
...@@ -375,7 +411,10 @@ begin ...@@ -375,7 +411,10 @@ begin
m.Latitude := lat; m.Latitude := lat;
m.Longitude := lng; m.Longitude := lng;
m.Title := m.Title :=
'<span class="emi-marker-meta" data-marker-type="unit" data-unit-badge="' +
HtmlAttrEncode(unitBadge) +
'" style="display:none"></span>' +
'<div class="d-flex flex-column gap-1 px-1 py-1" style="width:260px;">' + '<div class="d-flex flex-column gap-1 px-1 py-1" style="width:260px;">' +
'<div class="fw-semibold small">' + '<div class="fw-semibold small">' +
'<span class="fw-bold">Unit:</span> ' + uName + '<span class="fw-bold">Unit:</span> ' + uName +
...@@ -414,8 +453,9 @@ begin ...@@ -414,8 +453,9 @@ begin
) + ) +
'</div>'; '</div>';
m.DataString := 'unit|' + unitId; m.DataString := 'unit|' + unitId + '|' + StringReplace(unitBadge, '|', '/', [rfReplaceAll]);
m.IconURL := CarIconForAgency(agency); m.IconURL := CarIconForAgency(agencyId);
end; end;
end; end;
...@@ -426,13 +466,18 @@ begin ...@@ -426,13 +466,18 @@ begin
begin begin
item := TJSObject(complaintsData[i]); item := TJSObject(complaintsData[i]);
complaintId := string(item['ComplaintId']); complaintId := GetJsonString(item, 'ComplaintId');
codeDesc := string(item['DispatchCodeDesc']); codeDesc := GetJsonString(item, 'DispatchCodeDesc');
agency := string(item['AgencyName']);
agencyId := GetJsonString(item, 'Agency');
agencyName := GetJsonString(item, 'AgencyName');
agency := agencyName;
if Trim(agency) = '' then if Trim(agency) = '' then
agency := string(item['Agency']); agency := agencyId;
priority := string(item['Priority']);
business := string(item['Business']); priority := GetJsonString(item, 'Priority');
business := GetJsonString(item, 'Business');
address := GetJsonString(item, 'Address');
lat := Double(item['Lat']); lat := Double(item['Lat']);
lng := Double(item['Lng']); lng := Double(item['Lng']);
...@@ -440,7 +485,7 @@ begin ...@@ -440,7 +485,7 @@ begin
if ((lat = 0) and (lng = 0)) or (Abs(lat) > 90) or (Abs(lng) > 180) then if ((lat = 0) and (lng = 0)) or (Abs(lat) > 90) or (Abs(lng) > 180) then
Continue; Continue;
pngName := string(item['pngName']); pngName := GetJsonString(item, 'pngName');
if Trim(pngName) <> '' then if Trim(pngName) <> '' then
iconUrl := 'assets/markers/' + pngName iconUrl := 'assets/markers/' + pngName
else else
...@@ -457,9 +502,9 @@ begin ...@@ -457,9 +502,9 @@ begin
rowsHtml := rowsHtml + rowsHtml := rowsHtml +
'<tr>' + '<tr>' +
'<td>' + string(uo['Unit']) + '</td>' + '<td>' + GetJsonString(uo, 'Unit') + '</td>' +
'<td>' + string(uo['Status']) + '</td>' + '<td>' + GetJsonString(uo, 'Status') + '</td>' +
'<td>' + string(uo['Updated']) + '</td>' + '<td>' + GetJsonString(uo, 'Updated') + '</td>' +
'</tr>'; '</tr>';
end; end;
end end
...@@ -494,7 +539,7 @@ begin ...@@ -494,7 +539,7 @@ begin
'' ''
) + ) +
'<div class="small mb-1">' + '<div class="small mb-1">' +
'<span class="fw-bold">Address:</span> ' + string(item['Address']) + '<span class="fw-bold">Address:</span> ' + address +
'</div>' + '</div>' +
'<table class="table table-sm table-bordered mb-1 emi-tip-table">' + '<table class="table table-sm table-bordered mb-1 emi-tip-table">' +
'<colgroup>' + '<colgroup>' +
...@@ -543,22 +588,36 @@ begin ...@@ -543,22 +588,36 @@ begin
'var m=' + MARKERVAR + ', o=m.options||{};' + #13#10 + 'var m=' + MARKERVAR + ', o=m.options||{};' + #13#10 +
'var rawTitle = (o && o.title) ? o.title : "";' + #13#10 + 'var rawTitle = (o && o.title) ? o.title : "";' + #13#10 +
'var ds = (o && o.datastring) ? o.datastring : "";' + #13#10 + 'var ds = (o && o.datastring) ? o.datastring : "";' + #13#10 +
'if (ds === "device") {' + #13#10 + 'if (ds === "device") {' + #13#10 +
' try { if (m.unbindTooltip) m.unbindTooltip(); } catch(e) {}' + #13#10 + ' try { if (m.unbindTooltip) m.unbindTooltip(); } catch(e) {}' + #13#10 +
' try { if (m.unbindPopup) m.unbindPopup(); } catch(e) {}' + #13#10 + ' try { if (m.unbindPopup) m.unbindPopup(); } catch(e) {}' + #13#10 +
' return;' + #13#10 + ' return;' + #13#10 +
'}' + #13#10 + '}' + #13#10 +
'o.tooltipHtml = rawTitle;' + #13#10 + 'o.tooltipHtml = rawTitle;' + #13#10 +
'o.title = "";' + #13#10 + 'o.title = "";' + #13#10 +
'var t = o.tooltipHtml || "";' + #13#10 + 'var t = o.tooltipHtml || "";' + #13#10 +
'var u = (o.icon && o.icon.options && o.icon.options.iconUrl) ? o.icon.options.iconUrl : null;' + #13#10 + 'var u = (o.icon && o.icon.options && o.icon.options.iconUrl) ? o.icon.options.iconUrl : null;' + #13#10 +
'var markerType = "";' + #13#10 +
'var unitBadgeText = "";' + #13#10 +
'try {' + #13#10 +
' var temp = document.createElement("div");' + #13#10 +
' temp.innerHTML = t;' + #13#10 +
' var meta = temp.querySelector(".emi-marker-meta");' + #13#10 +
' if (meta) {' + #13#10 +
' markerType = meta.getAttribute("data-marker-type") || "";' + #13#10 +
' unitBadgeText = meta.getAttribute("data-unit-badge") || "";' + #13#10 +
' }' + #13#10 +
'} catch(e) {}' + #13#10 +
'var isUnit = markerType === "unit";' + #13#10 +
'try { if (m.unbindTooltip) m.unbindTooltip(); } catch(e) {}' + #13#10 + 'try { if (m.unbindTooltip) m.unbindTooltip(); } catch(e) {}' + #13#10 +
'try { if (m.unbindPopup) m.unbindPopup(); } catch(e) {}' + #13#10 + 'try { if (m.unbindPopup) m.unbindPopup(); } catch(e) {}' + #13#10 +
// Note: we derive badgeText from icon filename suffix: *_2.png, *_3.png, *_4.png, *_5-9.png, etc.
'var badgeText = "";' + #13#10 + 'var badgeText = "";' + #13#10 +
'if (u) {' + #13#10 + 'if (!isUnit && u) {' + #13#10 +
' try {' + #13#10 + ' try {' + #13#10 +
' var file = u.split("/").pop();' + #13#10 + ' var file = u.split("/").pop();' + #13#10 +
' var base = file.replace(/\.[^/.]+$/, "");' + #13#10 + ' var base = file.replace(/\.[^/.]+$/, "");' + #13#10 +
...@@ -580,16 +639,19 @@ begin ...@@ -580,16 +639,19 @@ begin
'else if (badgeText === "4") badgeColor = "#047857";' + #13#10 + 'else if (badgeText === "4") badgeColor = "#047857";' + #13#10 +
'if (u) {' + #13#10 + 'if (u) {' + #13#10 +
' var html = ''<div class="emi-marker-wrap"><img src="'' + u + ''" class="emi-marker-img">'';' + #13#10 + ' var wrapClass = isUnit ? "emi-marker-wrap emi-marker-wrap-unit" : "emi-marker-wrap";' + #13#10 +
' if (badgeText) {' + #13#10 + ' var html = ''<div class="'' + wrapClass + ''"><img src="'' + u + ''" class="emi-marker-img">'';' + #13#10 +
' if (isUnit && unitBadgeText) {' + #13#10 +
' html += ''<div class="emi-unit-badge">'' + unitBadgeText + ''</div>'';' + #13#10 +
' } else if (badgeText) {' + #13#10 +
' html += ''<div class="emi-marker-badge" style="background:'' + badgeColor + '';">'' + badgeText + ''</div>'';' + #13#10 + ' html += ''<div class="emi-marker-badge" style="background:'' + badgeColor + '';">'' + badgeText + ''</div>'';' + #13#10 +
' }' + #13#10 + ' }' + #13#10 +
' html += ''</div>'';' + #13#10 + ' html += ''</div>'';' + #13#10 +
' m.setIcon(L.divIcon({' + #13#10 + ' m.setIcon(L.divIcon({' + #13#10 +
' html: html,' + #13#10 + ' html: html,' + #13#10 +
' iconSize: [32,32],' + #13#10 + ' iconSize: [32,40],' + #13#10 +
' iconAnchor: [16,32],' + #13#10 + ' iconAnchor: [16,32],' + #13#10 +
' popupAnchor: [0,-20],' + #13#10 + ' popupAnchor: [0,-24],' + #13#10 +
' className: ""' + #13#10 + ' className: ""' + #13#10 +
' }));' + #13#10 + ' }));' + #13#10 +
' try { if (m._icon) m._icon.removeAttribute("title"); } catch(e) {}' + #13#10 + ' try { if (m._icon) m._icon.removeAttribute("title"); } catch(e) {}' + #13#10 +
...@@ -639,9 +701,11 @@ begin ...@@ -639,9 +701,11 @@ begin
'vertical-align:middle;' + 'vertical-align:middle;' +
'}' + #13#10 + '}' + #13#10 +
// --- Marker Badge ------------------------------------------------------------ // --- Marker Badge ------------------------------------------------------------
'.emi-marker-wrap{position:relative;display:inline-block;}'+#13#10+ '.emi-marker-wrap{position:relative;display:inline-block;}'+#13#10+
'.emi-marker-wrap-unit{padding-top:13px;}'+#13#10+
'.emi-marker-img{display:block;}'+#13#10+ '.emi-marker-img{display:block;}'+#13#10+
'.emi-marker-badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 4px;border-radius:999px;background:var(--bs-danger);color:#fff;font:700 11px/16px system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;text-align:center;box-shadow:0 0 0 2px #fff;}' + #13#10; '.emi-marker-badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 4px;border-radius:999px;background:var(--bs-danger);color:#fff;font:700 11px/16px system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;text-align:center;box-shadow:0 0 0 2px #fff;}'+#13#10+
'.emi-unit-badge{position:absolute;top:0;left:50%;transform:translateX(-50%);min-width:34px;max-width:58px;height:15px;padding:0 5px;border-radius:4px;background:#111827;color:#fff;font:700 10px/15px system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-shadow:0 0 0 2px #fff;z-index:2;}'+#13#10;
end; end;
procedure TFViewMap.tmrLocateTimer(Sender: TObject); procedure TFViewMap.tmrLocateTimer(Sender: TObject);
...@@ -709,7 +773,7 @@ begin ...@@ -709,7 +773,7 @@ begin
for i := 0 to lfMap.Markers.Count - 1 do for i := 0 to lfMap.Markers.Count - 1 do
begin begin
m := lfMap.Markers[i]; m := lfMap.Markers[i];
if SameText(m.DataString, targetDs) then if SameText(m.DataString, targetDs) or StartsText(targetDs + '|', m.DataString) then
begin begin
coord := CreateCoordinate(m.Latitude, m.Longitude); coord := CreateCoordinate(m.Latitude, m.Longitude);
lfmap.SetCenterCoordinate(coord); lfmap.SetCenterCoordinate(coord);
......
...@@ -183,9 +183,9 @@ begin ...@@ -183,9 +183,9 @@ begin
// - complaints: m.DataString := 'complaint' // - complaints: m.DataString := 'complaint'
showMarker := True; showMarker := True;
if SameText(ds, 'unit') then if SameText(ds, 'unit') or StartsText('unit|', ds) then
showMarker := FShowUnits showMarker := FShowUnits
else if StartsText('complaint', LowerCase(ds)) then else if SameText(ds, 'complaint') or StartsText('complaint|', ds) then
showMarker := FShowComplaints showMarker := FShowComplaints
else if SameText(ds, 'device') then else if SameText(ds, 'device') then
showMarker := FShowLocation; showMarker := FShowLocation;
......
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