Commit d1a82903 by Mac Stephens

add business to complaint popup and forms, fix zoom issue for view on map,…

add business to complaint popup and forms, fix zoom issue for view on map, remove refresh spinner, update summary arrow, update buf removal from district, stack buttons on unit details, general style fixes
parent 8190ffe0
...@@ -179,8 +179,8 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -179,8 +179,8 @@ object ApiDatabaseModule: TApiDatabaseModule
'' ''
'') '')
ReadOnly = True ReadOnly = True
Left = 82 Left = 76
Top = 186 Top = 188
object uqUnitListUNITID: TFloatField object uqUnitListUNITID: TFloatField
FieldName = 'UNITID' FieldName = 'UNITID'
end end
...@@ -391,7 +391,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -391,7 +391,7 @@ object ApiDatabaseModule: TApiDatabaseModule
' ca.APARTMENT,' ' ca.APARTMENT,'
' ca.CITY,' ' ca.CITY,'
' ca.BUSINESS,' ' ca.BUSINESS,'
' ca.DISPATCHDISTRICT,' ' cd.CODE_DESC AS DISPATCHDISTRICT,'
' ca.DISPATCHSECTOR,' ' ca.DISPATCHSECTOR,'
' ca.ADDRESSDISTRICT,' ' ca.ADDRESSDISTRICT,'
' ca.ADDRESSSECTOR,' ' ca.ADDRESSSECTOR,'
...@@ -417,20 +417,17 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -417,20 +417,17 @@ object ApiDatabaseModule: TApiDatabaseModule
'LEFT JOIN CD_CALLPRIORITIES cp ON cp.CODE = ca.PRIORITY AND cp.A' + 'LEFT JOIN CD_CALLPRIORITIES cp ON cp.CODE = ca.PRIORITY AND cp.A' +
'GENCY = ca.AGENCY' 'GENCY = ca.AGENCY'
'LEFT JOIN CD_DISTRICT cd ON cd.AGENCYCODE = ca.DISPATCHDI' + 'JOIN CD_DISTRICT cd ON cd.AGENCYCODE = ca.DISPATCHDI' +
'STRICT' 'STRICT'
'LEFT JOIN CD_SECTOR cs ON cs.AGENCYCODE = ca.DISPATCHSE' + 'LEFT JOIN CD_SECTOR cs ON cs.AGENCYCODE = ca.DISPATCHSE' +
'CTOR AND cs.CODE_TYPE = cd.AGENCYCODE ' 'CTOR AND cs.CODE_TYPE = cd.AGENCYCODE'
'WHERE ca.COMPLAINT IS NOT NULL' 'WHERE ca.COMPLAINT IS NOT NULL'
'ORDER BY cd.CODE_DESC, ct.DATEREPORTED DESC, ca.PRIORITY DESC;')
'ORDER BY ca.DISPATCHDISTRICT, ct.DATEREPORTED DESC, ca.PRIORITY ' +
'DESC'
'')
ReadOnly = True ReadOnly = True
OnCalcFields = uqComplaintListCalcFields OnCalcFields = uqComplaintListCalcFields
Left = 78 Left = 78
Top = 242 Top = 244
object uqComplaintListCOMPLAINTID: TFloatField object uqComplaintListCOMPLAINTID: TFloatField
FieldName = 'COMPLAINTID' FieldName = 'COMPLAINTID'
Required = True Required = True
...@@ -568,8 +565,9 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -568,8 +565,9 @@ object ApiDatabaseModule: TApiDatabaseModule
' ca.PRIORITY,' ' ca.PRIORITY,'
' ca.DISPATCHCODE,' ' ca.DISPATCHCODE,'
' cdc.CODE_DESC AS DISPATCH_CODE_DESC,' ' cdc.CODE_DESC AS DISPATCH_CODE_DESC,'
' ca.DISPATCHDISTRICT,' ' cd.CODE_DESC AS DISPATCHDISTRICT,'
' ca.ADDRESS,' ' ca.ADDRESS,'
' ca.BUSINESS,'
' ct.DATEREPORTED,' ' ct.DATEREPORTED,'
' ct.DATERECEIVED,' ' ct.DATERECEIVED,'
' ct.DATEDISPATCHED,' ' ct.DATEDISPATCHED,'
...@@ -598,6 +596,8 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -598,6 +596,8 @@ object ApiDatabaseModule: TApiDatabaseModule
' ON ca.COMPLAINTID = ct.COMPLAINTID' ' ON ca.COMPLAINTID = ct.COMPLAINTID'
'LEFT JOIN CD_DISPATCHCODES cdc' 'LEFT JOIN CD_DISPATCHCODES cdc'
' ON ca.DISPATCHCODE = cdc.CODE' ' ON ca.DISPATCHCODE = cdc.CODE'
'JOIN CD_DISTRICT cd'
' ON cd.AGENCYCODE = ca.DISPATCHDISTRICT'
'LEFT JOIN ADDRESS a' 'LEFT JOIN ADDRESS a'
' ON ca.ADDRESSID = a.ADDRESSID' ' ON ca.ADDRESSID = a.ADDRESSID'
'WHERE ca.COMPLAINTID = :COMPLAINTID;') 'WHERE ca.COMPLAINTID = :COMPLAINTID;')
...@@ -608,7 +608,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -608,7 +608,7 @@ object ApiDatabaseModule: TApiDatabaseModule
item item
DataType = ftUnknown DataType = ftUnknown
Name = 'COMPLAINTID' Name = 'COMPLAINTID'
Value = nil Value = Null
end> end>
object uqComplaintDetailsCOMPLAINTID: TFloatField object uqComplaintDetailsCOMPLAINTID: TFloatField
FieldName = 'COMPLAINTID' FieldName = 'COMPLAINTID'
...@@ -636,7 +636,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -636,7 +636,7 @@ object ApiDatabaseModule: TApiDatabaseModule
end end
object uqComplaintDetailsDISPATCHDISTRICT: TStringField object uqComplaintDetailsDISPATCHDISTRICT: TStringField
FieldName = 'DISPATCHDISTRICT' FieldName = 'DISPATCHDISTRICT'
Size = 6 Size = 120
end end
object uqComplaintDetailsADDRESS: TStringField object uqComplaintDetailsADDRESS: TStringField
FieldName = 'ADDRESS' FieldName = 'ADDRESS'
...@@ -709,6 +709,10 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -709,6 +709,10 @@ object ApiDatabaseModule: TApiDatabaseModule
FieldName = 'CITY' FieldName = 'CITY'
ReadOnly = True ReadOnly = True
end end
object uqComplaintDetailsBUSINESS: TStringField
FieldName = 'BUSINESS'
Size = 35
end
end end
object ucENTCAD: TUniConnection object ucENTCAD: TUniConnection
ProviderName = 'Oracle' ProviderName = 'Oracle'
...@@ -726,29 +730,24 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -726,29 +730,24 @@ object ApiDatabaseModule: TApiDatabaseModule
SQL.Strings = ( SQL.Strings = (
'SELECT' 'SELECT'
' ca.COMPLAINTID,' ' ca.COMPLAINTID,'
' ca.DISPATCHDISTRICT,' ' cd.CODE_DESC AS DISPATCHDISTRICT,'
' ca.PRIORITY AS PRIORITY,' ' ca.PRIORITY AS PRIORITY,'
' ca.BUSINESS,'
' cdc.MOBILE_MAP_CATEGORY AS DISPATCHCODECATEGORY,' ' cdc.MOBILE_MAP_CATEGORY AS DISPATCHCODECATEGORY,'
'' ''
' CASE ' ' SDO_CS.TRANSFORM('
' WHEN ca.XCOORD IS NOT NULL AND ca.YCOORD IS NOT NULL THEN'
' SDO_CS.TRANSFORM('
' SDO_GEOMETRY(2001, 2262, SDO_POINT_TYPE(ca.XCOORD, ca.YC' + ' SDO_GEOMETRY(2001, 2262, SDO_POINT_TYPE(ca.XCOORD, ca.YCOORD' +
'OORD, NULL), NULL, NULL),' ', NULL), NULL, NULL),'
' 4326' ' 4326'
' ).sdo_point.x' ' ).sdo_point.x AS LNG,'
' END AS LNG,'
'' ''
' CASE ' ' SDO_CS.TRANSFORM('
' WHEN ca.XCOORD IS NOT NULL AND ca.YCOORD IS NOT NULL THEN'
' SDO_CS.TRANSFORM('
' SDO_GEOMETRY(2001, 2262, SDO_POINT_TYPE(ca.XCOORD, ca.YC' + ' SDO_GEOMETRY(2001, 2262, SDO_POINT_TYPE(ca.XCOORD, ca.YCOORD' +
'OORD, NULL), NULL, NULL),' ', NULL), NULL, NULL),'
' 4326' ' 4326'
' ).sdo_point.y' ' ).sdo_point.y AS LAT,'
' END AS LAT,'
'' ''
' cdc.CODE_DESC AS DISPATCH_CODE_DESC,' ' cdc.CODE_DESC AS DISPATCH_CODE_DESC,'
' ca.ADDRESS AS ADDRESS' ' ca.ADDRESS AS ADDRESS'
...@@ -757,10 +756,14 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -757,10 +756,14 @@ object ApiDatabaseModule: TApiDatabaseModule
' ON ct.COMPLAINTID = ca.COMPLAINTID' ' ON ct.COMPLAINTID = ca.COMPLAINTID'
'LEFT JOIN CD_DISPATCHCODES cdc' 'LEFT JOIN CD_DISPATCHCODES cdc'
' ON cdc.CODE = ca.DISPATCHCODE' ' ON cdc.CODE = ca.DISPATCHCODE'
'WHERE ca.COMPLAINT IS NOT NULL ' 'JOIN CD_DISTRICT cd'
' AND ca.XCOORD IS NOT NULL ' ' ON cd.AGENCYCODE = ca.DISPATCHDISTRICT'
'WHERE ca.COMPLAINT IS NOT NULL'
' AND ca.XCOORD IS NOT NULL'
' AND ca.YCOORD IS NOT NULL;' ' AND ca.YCOORD IS NOT NULL;'
'' ''
''
''
'') '')
ReadOnly = True ReadOnly = True
OnCalcFields = uqMapComplaintsCalcFields OnCalcFields = uqMapComplaintsCalcFields
...@@ -772,7 +775,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -772,7 +775,7 @@ object ApiDatabaseModule: TApiDatabaseModule
end end
object uqMapComplaintsDISPATCHDISTRICT: TStringField object uqMapComplaintsDISPATCHDISTRICT: TStringField
FieldName = 'DISPATCHDISTRICT' FieldName = 'DISPATCHDISTRICT'
Size = 6 Size = 120
end end
object uqMapComplaintsLNG: TFloatField object uqMapComplaintsLNG: TFloatField
FieldName = 'LNG' FieldName = 'LNG'
...@@ -808,6 +811,10 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -808,6 +811,10 @@ object ApiDatabaseModule: TApiDatabaseModule
FieldName = 'pngName' FieldName = 'pngName'
Calculated = True Calculated = True
end end
object uqMapComplaintsBUSINESS: TStringField
FieldName = 'BUSINESS'
Size = 35
end
end end
object uqBadgeCounts: TUniQuery object uqBadgeCounts: TUniQuery
Connection = ucENTCAD Connection = ucENTCAD
...@@ -854,6 +861,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -854,6 +861,7 @@ object ApiDatabaseModule: TApiDatabaseModule
' AND c.YCOORD IS NOT NULL' ' AND c.YCOORD IS NOT NULL'
')' ')'
'ORDER BY ca.COMPLAINTID, ca.DATEDISPATCHED;') 'ORDER BY ca.COMPLAINTID, ca.DATEDISPATCHED;')
ReadOnly = True
Left = 464 Left = 464
Top = 202 Top = 202
object uqMapComplaintUnitsListCOMPLAINTID: TFloatField object uqMapComplaintUnitsListCOMPLAINTID: TFloatField
...@@ -920,6 +928,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -920,6 +928,7 @@ object ApiDatabaseModule: TApiDatabaseModule
'and (ctx.strsuffix is null or c.strsuffix = ctx.strsuffix)' 'and (ctx.strsuffix is null or c.strsuffix = ctx.strsuffix)'
'and (ctx.city is null or c.city = ctx.city)' 'and (ctx.city is null or c.city = ctx.city)'
'order by c.datereported desc') 'order by c.datereported desc')
ReadOnly = True
Left = 328 Left = 328
Top = 72 Top = 72
ParamData = < ParamData = <
...@@ -945,6 +954,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -945,6 +954,7 @@ object ApiDatabaseModule: TApiDatabaseModule
'from dis_contact c' 'from dis_contact c'
'join ctx on c.addressid = ctx.addressid' 'join ctx on c.addressid = ctx.addressid'
'left join cd_contact_type ct on c.contact_type = ct.code') 'left join cd_contact_type ct on c.contact_type = ct.code')
ReadOnly = True
Left = 330 Left = 330
Top = 130 Top = 130
ParamData = < ParamData = <
...@@ -1022,6 +1032,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -1022,6 +1032,7 @@ object ApiDatabaseModule: TApiDatabaseModule
' distance,' ' distance,'
' decode(w.code, '#39'POL'#39', 1, '#39'FIR'#39', 2, 3),' ' decode(w.code, '#39'POL'#39', 1, '#39'FIR'#39', 2, 3),'
' wt.code_desc') ' wt.code_desc')
ReadOnly = True
Left = 488 Left = 488
Top = 76 Top = 76
ParamData = < ParamData = <
...@@ -1057,7 +1068,8 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -1057,7 +1068,8 @@ object ApiDatabaseModule: TApiDatabaseModule
'LEFT JOIN PERSONNEL p2 ON dua.OFFICER2ID = p2.PF_NAMEID' 'LEFT JOIN PERSONNEL p2 ON dua.OFFICER2ID = p2.PF_NAMEID'
'LEFT JOIN UNITS_CURRENT@AVL_LINK uc ON dua.UNITID = uc.UNITID' 'LEFT JOIN UNITS_CURRENT@AVL_LINK uc ON dua.UNITID = uc.UNITID'
'WHERE dua.UNITID = :UNITID') 'WHERE dua.UNITID = :UNITID')
Left = 192 ReadOnly = True
Left = 194
Top = 312 Top = 312
ParamData = < ParamData = <
item item
...@@ -1136,6 +1148,7 @@ object ApiDatabaseModule: TApiDatabaseModule ...@@ -1136,6 +1148,7 @@ object ApiDatabaseModule: TApiDatabaseModule
'from ENTCAD.DIS_UNIT_LOG dul' 'from ENTCAD.DIS_UNIT_LOG dul'
'where dul.UNITID = :UNITID' 'where dul.UNITID = :UNITID'
'order by dul."TIMESTAMP" desc') 'order by dul."TIMESTAMP" desc')
ReadOnly = True
Left = 190 Left = 190
Top = 374 Top = 374
ParamData = < ParamData = <
......
...@@ -170,6 +170,8 @@ type ...@@ -170,6 +170,8 @@ type
uqUnitLogsCOMPLAINT_NUM: TStringField; uqUnitLogsCOMPLAINT_NUM: TStringField;
uqUnitLogsLOG_TEXT: TStringField; uqUnitLogsLOG_TEXT: TStringField;
uqMapUnitsDIS_UNITID: TFloatField; uqMapUnitsDIS_UNITID: TFloatField;
uqMapComplaintsBUSINESS: TStringField;
uqComplaintDetailsBUSINESS: TStringField;
procedure uqComplaintListCalcFields(DataSet: TDataSet); procedure uqComplaintListCalcFields(DataSet: TDataSet);
procedure uqMapComplaintsCalcFields(DataSet: TDataSet); procedure uqMapComplaintsCalcFields(DataSet: TDataSet);
private private
......
...@@ -17,7 +17,6 @@ type ...@@ -17,7 +17,6 @@ type
procedure AfterConstruction; override; procedure AfterConstruction; override;
procedure BeforeDestruction; override; procedure BeforeDestruction; override;
function GetComplaintMemos(const CfsId: string): TJSONObject; function GetComplaintMemos(const CfsId: string): TJSONObject;
function DispatchDistrictLetter(const value: string): string;
public public
function GetBadgeCounts: TJSONObject; function GetBadgeCounts: TJSONObject;
function GetComplaintList: TJSONObject; function GetComplaintList: TJSONObject;
...@@ -153,13 +152,14 @@ begin ...@@ -153,13 +152,14 @@ begin
item:=TJSONObject.Create; item:=TJSONObject.Create;
item.AddPair('ComplaintId',ApiDB.uqMapComplaintsCOMPLAINTID.AsString); item.AddPair('ComplaintId',ApiDB.uqMapComplaintsCOMPLAINTID.AsString);
item.AddPair('DispatchDistrict', DispatchDistrictLetter(ApiDB.uqMapComplaintsDISPATCHDISTRICT.AsString)); item.AddPair('DispatchDistrict', ApiDB.uqMapComplaintsDISPATCHDISTRICT.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);
item.AddPair('priorityKey',ApiDB.uqMapComplaintspriorityKey.AsString); item.AddPair('priorityKey',ApiDB.uqMapComplaintspriorityKey.AsString);
item.AddPair('pngName',ApiDB.uqMapComplaintspngName.AsString); item.AddPair('pngName',ApiDB.uqMapComplaintspngName.AsString);
item.AddPair('Address',ApiDB.uqMapComplaintsADDRESS.AsString); item.AddPair('Address',ApiDB.uqMapComplaintsADDRESS.AsString);
item.AddPair('Business',ApiDB.uqMapComplaintsBUSINESS.AsString);
complaintId:=ApiDB.uqMapComplaintsCOMPLAINTID.AsString; complaintId:=ApiDB.uqMapComplaintsCOMPLAINTID.AsString;
if UnitsByComplaintMap.TryGetValue(complaintId,unitArray) then if UnitsByComplaintMap.TryGetValue(complaintId,unitArray) then
...@@ -331,9 +331,10 @@ begin ...@@ -331,9 +331,10 @@ begin
item.AddPair('Priority', ApiDB.uqComplaintListPRIORITY.AsString); item.AddPair('Priority', ApiDB.uqComplaintListPRIORITY.AsString);
item.AddPair('DispatchCodeDesc', ApiDB.uqComplaintListDISPATCH_CODE_DESC.AsString); item.AddPair('DispatchCodeDesc', ApiDB.uqComplaintListDISPATCH_CODE_DESC.AsString);
item.AddPair('Address', ApiDB.uqComplaintListADDRESS.AsString); item.AddPair('Address', ApiDB.uqComplaintListADDRESS.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', DispatchDistrictLetter(curDistrict)); item.AddPair('DispatchDistrict', curDistrict);
item.AddPair('DateReported', ApiDB.uqComplaintListDATEREPORTED.AsString); item.AddPair('DateReported', ApiDB.uqComplaintListDATEREPORTED.AsString);
data.AddElement(item); data.AddElement(item);
...@@ -465,8 +466,9 @@ begin ...@@ -465,8 +466,9 @@ begin
obj.AddPair('Priority', ApiDB.uqComplaintDetailsPRIORITY.AsString); obj.AddPair('Priority', ApiDB.uqComplaintDetailsPRIORITY.AsString);
obj.AddPair('DispatchCode', ApiDB.uqComplaintDetailsDISPATCHCODE.AsString); obj.AddPair('DispatchCode', ApiDB.uqComplaintDetailsDISPATCHCODE.AsString);
obj.AddPair('DispatchCodeDesc', ApiDB.uqComplaintDetailsDISPATCH_CODE_DESC.AsString); obj.AddPair('DispatchCodeDesc', ApiDB.uqComplaintDetailsDISPATCH_CODE_DESC.AsString);
obj.AddPair('DispatchDistrict', DispatchDistrictLetter(ApiDB.uqComplaintDetailsDISPATCHDISTRICT.AsString)); obj.AddPair('DispatchDistrict', ApiDB.uqComplaintDetailsDISPATCHDISTRICT.AsString);
obj.AddPair('Address', ApiDB.uqComplaintDetailsADDRESS.AsString); obj.AddPair('Address', ApiDB.uqComplaintDetailsADDRESS.AsString);
obj.AddPair('Business',ApiDB.uqComplaintDetailsBUSINESS.AsString);
obj.AddPair('History', ApiDB.uqComplaintDetailsHISTORY.AsString); obj.AddPair('History', ApiDB.uqComplaintDetailsHISTORY.AsString);
obj.AddPair('Contacts', ApiDB.uqComplaintDetailsCONTACTS.AsString); obj.AddPair('Contacts', ApiDB.uqComplaintDetailsCONTACTS.AsString);
obj.AddPair('Warnings', ApiDB.uqComplaintDetailsWARNINGS.AsString); obj.AddPair('Warnings', ApiDB.uqComplaintDetailsWARNINGS.AsString);
...@@ -604,6 +606,9 @@ begin ...@@ -604,6 +606,9 @@ begin
try try
while not Eof do while not Eof do
begin begin
if returnedCount >= 50 then
Break;
rowObj := TJSONObject.Create; rowObj := TJSONObject.Create;
dataArr.AddElement(rowObj); dataArr.AddElement(rowObj);
...@@ -893,18 +898,6 @@ begin ...@@ -893,18 +898,6 @@ begin
end; end;
function TApiService.DispatchDistrictLetter(const value: string): string;
var
s: string;
begin
s := Trim(value);
if s = '' then
Exit('');
Result := s[Length(s)];
end;
initialization initialization
RegisterServiceType(TApiService); RegisterServiceType(TApiService);
......
[Settings] [Settings]
LogFileNum=597 LogFileNum=610
webClientVersion=0.1.0 webClientVersion=0.1.0
...@@ -365,7 +365,7 @@ object FViewComplaintDetails: TFViewComplaintDetails ...@@ -365,7 +365,7 @@ object FViewComplaintDetails: TFViewComplaintDetails
Top = 430 Top = 430
Width = 96 Width = 96
Height = 25 Height = 25
Caption = 'View On Map' Caption = 'Map'
ChildOrder = 1 ChildOrder = 1
ElementID = 'btn_complaint_view_on_map' ElementID = 'btn_complaint_view_on_map'
ElementFont = efCSS ElementFont = efCSS
......
...@@ -7,16 +7,21 @@ ...@@ -7,16 +7,21 @@
<!-- Summary header --> <!-- Summary header -->
<div class="card border-0 shadow-sm mb-2"> <div class="card border-0 shadow-sm mb-2">
<div class="card-header bg-white py-2"> <div class="card-header bg-white py-2">
<button <button
class="btn btn-link text-decoration-none p-0 w-100 d-flex align-items-center justify-content-between" class="btn btn-link text-decoration-none p-0 w-100 d-flex align-items-center justify-content-between summary-toggle"
type="button" type="button"
data-bs-toggle="collapse" data-bs-toggle="collapse"
data-bs-target="#cdetails_summary" data-bs-target="#cdetails_summary"
aria-expanded="true" aria-expanded="true"
aria-controls="cdetails_summary"> aria-controls="cdetails_summary">
<span class="fw-semibold text-dark" id="lbl_summary_title">Summary</span> <span class="fw-semibold text-dark" id="lbl_summary_title">Summary</span>
<i class="fa fa-chevron-down"></i>
</button> <span class="summary-chevron" aria-hidden="true">
<svg class="summary-chevron-icon" viewBox="0 0 16 16" focusable="false">
<path fill="currentColor" d="M7.646 5.354a.5.5 0 0 1 .708 0l5 5a.5.5 0 0 1-.708.708L8 6.414 3.354 11.06a.5.5 0 1 1-.708-.708l5-5z"/>
</svg>
</span>
</button>
</div> </div>
</div> </div>
...@@ -48,11 +53,12 @@ ...@@ -48,11 +53,12 @@
<th scope="row" class="fw-semibold text-nowrap pe-2 w-auto">Address:</th> <th scope="row" class="fw-semibold text-nowrap pe-2 w-auto">Address:</th>
<td class="w-100" id="lbl_address"></td> <td class="w-100" id="lbl_address"></td>
</tr> </tr>
<tr id="row_business" class="d-none">
<th scope="row" class="fw-semibold text-nowrap pe-2 w-auto">Business:</th>
<td class="w-100" id="lbl_business"></td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
......
...@@ -531,6 +531,7 @@ var ...@@ -531,6 +531,7 @@ var
resp: TXDataClientResponse; resp: TXDataClientResponse;
rootObj: TJSObject; rootObj: TJSObject;
dataObj: TJSObject; dataObj: TJSObject;
businessRowEl: TJSHTMLElement;
complaintText: string; complaintText: string;
priorityText: string; priorityText: string;
...@@ -538,6 +539,7 @@ var ...@@ -538,6 +539,7 @@ var
dispatchDescText: string; dispatchDescText: string;
dispatchDistrictText: string; dispatchDistrictText: string;
addressText: string; addressText: string;
businessText: string;
dateDispatchedText: string; dateDispatchedText: string;
dateArrivedText: string; dateArrivedText: string;
...@@ -563,6 +565,9 @@ begin ...@@ -563,6 +565,9 @@ begin
dispatchDescText := string(dataObj['DispatchCodeDesc']); dispatchDescText := string(dataObj['DispatchCodeDesc']);
dispatchDistrictText := string(dataObj['DispatchDistrict']); dispatchDistrictText := string(dataObj['DispatchDistrict']);
addressText := string(dataObj['Address']); addressText := string(dataObj['Address']);
businessText := '';
if dataObj['Business'] <> nil then
businessText := string(dataObj['Business']);
FCfsId := string(dataObj['CFSId']); FCfsId := string(dataObj['CFSId']);
statusText := ''; statusText := '';
...@@ -590,6 +595,16 @@ begin ...@@ -590,6 +595,16 @@ begin
SetTextById('lbl_dispatch_code', dispatchDescText); SetTextById('lbl_dispatch_code', dispatchDescText);
SetTextById('lbl_dispatch_district', dispatchDistrictText); SetTextById('lbl_dispatch_district', dispatchDistrictText);
SetTextById('lbl_address', addressText); SetTextById('lbl_address', addressText);
SetTextById('lbl_business', businessText);
businessRowEl := TJSHTMLElement(document.getElementById('row_business'));
if businessRowEl <> nil then
begin
if Trim(businessText) = '' then
businessRowEl.classList.add('d-none')
else
businessRowEl.classList.remove('d-none');
end;
historyFlag := ''; historyFlag := '';
contactsFlag := ''; contactsFlag := '';
......
...@@ -42,23 +42,22 @@ object FViewComplaints: TFViewComplaints ...@@ -42,23 +42,22 @@ object FViewComplaints: TFViewComplaints
Style = lsListGroup Style = lsListGroup
DataSource = wdsComplaints DataSource = wdsComplaints
ItemTemplate = ItemTemplate =
'<div class="list-section-header small fw-semibold bg-secondary ' + '<div class="list-section-header small fw-semibold bg-secondary t' +
'text-white rounded-1 px-2 mb-1"> (%DistrictHeader%)</div><div ' + 'ext-white rounded-1 px-2 mb-1">(%DistrictHeader%)</div><div clas' +
'class="card border shadow-sm position-relative" style=" --bs' + 's="card border shadow-sm" style="--bs-card-bg:(%PriorityColor%);' +
'-card-bg: (%PriorityColor%); --bs-card-color: (%PriorityTextC' + '--bs-card-color:(%PriorityTextColor%);"><div class="card-body py' +
'olor%); "> <div class="card-body py-2 px-3"> <div class="fw' + '-2 px-3 d-flex gap-2"><div class="flex-grow-1"><div class="fw-bo' +
'-bold text-uppercase small"> (%Priority%): (%DispatchCodeDe' + 'ld text-uppercase small">(%Priority%): (%DispatchCodeDesc%)</div' +
'sc%) </div> <div class="small">(%Address%)</div> <div c' + '><div class="small">(%Address%)</div><div class="small d-none co' +
'lass="small text-opacity-75"> (%Complaint%): (%Status%)&nbs' + 'mplaint-business" data-business="(%Business%)">(%Business%)</div' +
'p;&nbsp;(%DistrictSector%) </div> <div class="small text-o' + '><div class="small text-opacity-75">(%Complaint%): (%Status%)&nb' +
'pacity-75">(%DateReported%)</div> </div> <div class="position-' + 'sp;&nbsp;(%DistrictSector%)</div><div class="small text-opacity-' +
'absolute top-50 end-0 translate-middle-y pe-2 d-flex flex-column' + '75">(%DateReported%)</div></div><div class="d-flex flex-column j' +
' gap-1"> <button type="button" class="btn btn-prima' + 'ustify-content-center gap-1"><button type="button" class="btn bt' +
'ry btn-sm complaint-details-btn" data-id="(%ComplaintId%)" ' + 'n-primary btn-sm complaint-details-btn" data-id="(%ComplaintId%)' +
' > Details </button> <button type="button" ' + '">Details</button><button type="button" class="btn btn-primary b' +
' class="btn btn-primary btn-sm btn-complaint-map" data-id=' + 'tn-sm btn-complaint-map" data-id="(%ComplaintId%)">View On Map</' +
'"(%ComplaintId%)" > View On Map </button> </div></di' + 'button></div></div></div>'
'v>'
ListSource = wdsComplaints ListSource = wdsComplaints
end end
object xdwcComplaints: TXDataWebClient object xdwcComplaints: TXDataWebClient
...@@ -88,6 +87,9 @@ object FViewComplaints: TFViewComplaints ...@@ -88,6 +87,9 @@ object FViewComplaints: TFViewComplaints
object xdwdsComplaintsAddress: TStringField object xdwdsComplaintsAddress: TStringField
FieldName = 'Address' FieldName = 'Address'
end end
object xdwdsComplaintsBusiness: TStringField
FieldName = 'Business'
end
object xdwdsComplaintsStatus: TStringField object xdwdsComplaintsStatus: TStringField
FieldName = 'Status' FieldName = 'Status'
end end
......
...@@ -32,6 +32,7 @@ type ...@@ -32,6 +32,7 @@ type
xdwdsComplaintsPriorityTextColor: TStringField; xdwdsComplaintsPriorityTextColor: TStringField;
xdwdsComplaintsDistrictSector: TStringField; xdwdsComplaintsDistrictSector: TStringField;
tmrRefresh: TWebTimer; tmrRefresh: TWebTimer;
xdwdsComplaintsBusiness: TStringField;
procedure WebFormCreate(Sender: TObject); procedure WebFormCreate(Sender: TObject);
procedure btnRefreshClick(Sender: TObject); procedure btnRefreshClick(Sender: TObject);
procedure tmrRefreshTimer(Sender: TObject); procedure tmrRefreshTimer(Sender: TObject);
...@@ -41,6 +42,7 @@ type ...@@ -41,6 +42,7 @@ type
FLoading: Boolean; FLoading: Boolean;
[async] procedure GetComplaints; [async] procedure GetComplaints;
procedure HandleListClick(e: TJSMouseEvent); procedure HandleListClick(e: TJSMouseEvent);
procedure ShowHideBusinessRows;
public public
property OnShowDetails: TSelectProc read FSelectProc write FSelectProc; property OnShowDetails: TSelectProc read FSelectProc write FSelectProc;
end; end;
...@@ -73,6 +75,26 @@ begin ...@@ -73,6 +75,26 @@ begin
end; end;
end; end;
procedure TFViewComplaints.ShowHideBusinessRows;
var
nodes: TJSNodeList;
i: Integer;
el: TJSHTMLElement;
businessText: string;
begin
nodes := document.querySelectorAll('.complaint-business');
for i := 0 to nodes.length - 1 do
begin
el := TJSHTMLElement(nodes.item(i));
businessText := string(el.getAttribute('data-business'));
if Trim(businessText) <> '' then
el.classList.remove('d-none')
else
el.classList.add('d-none');
end;
end;
procedure TFViewComplaints.HandleListClick(e: TJSMouseEvent); procedure TFViewComplaints.HandleListClick(e: TJSMouseEvent);
var var
el: TJSElement; el: TJSElement;
...@@ -111,11 +133,7 @@ begin ...@@ -111,11 +133,7 @@ begin
e.stopPropagation; e.stopPropagation;
asm asm
try { pas['View.Main'].FViewMain.ShowMapFocusComplaint(complaintId);
pas['View.Main'].FViewMain.ShowMapFocusComplaint(complaintId);
} catch (e) {
console.log('ShowMapFocusComplaint failed', e);
}
end; end;
end; end;
end; end;
...@@ -127,46 +145,48 @@ begin ...@@ -127,46 +145,48 @@ begin
Document.removeEventListener('click', @HandleListClick); Document.removeEventListener('click', @HandleListClick);
end; end;
//Note: jjHTML for individual complaint cards can be found in the twebdblistcontrol HTMLString property //Note: HTML for individual complaint cards can be found in the twebdblistcontrol HTMLString property
procedure TFViewComplaints.btnRefreshClick(Sender: TObject); procedure TFViewComplaints.btnRefreshClick(Sender: TObject);
begin begin
GetComplaints; GetComplaints;
end; end;
procedure TFViewComplaints.GetComplaints; [async] procedure TFViewComplaints.GetComplaints;
var var
xdcResponse: TXDataClientResponse; xdcResponse: TXDataClientResponse;
respObj: TJSObject; respObj: TJSObject;
complaintsCount: Integer; complaintsCount: Integer;
begin begin
if FLoading then Exit; if FLoading then
FLoading := True; Exit;
FLoading := True;
ShowSpinner('spinner');
try try
try try
xdcResponse := await(xdwcComplaints.RawInvokeAsync('IApiService.GetComplaintList', [])); xdcResponse := await(xdwcComplaints.RawInvokeAsync('IApiService.GetComplaintList', []));
respObj := TJSObject(xdcResponse.Result); respObj := TJSObject(xdcResponse.Result);
xdwdsComplaints.Close; xdwdsComplaints.Close;
xdwdsComplaints.SetJsonData(respObj['data']); xdwdsComplaints.SetJsonData(respObj['data']);
xdwdsComplaints.Open; xdwdsComplaints.Open;
ShowHideBusinessRows;
complaintsCount := Integer(respObj['count']); complaintsCount := Integer(respObj['count']);
lblEntries.Caption := Format('%d active complaints', [complaintsCount]); lblEntries.Caption := Format('%d active complaints', [complaintsCount]);
except except
on E: EXDataClientRequestException do on E: EXDataClientRequestException do
begin
Utils.ShowErrorModal(E.ErrorResult.ErrorMessage); Utils.ShowErrorModal(E.ErrorResult.ErrorMessage);
end; on E: Exception do
Utils.ShowErrorModal(E.Message);
end; end;
finally finally
HideSpinner('spinner');
FLoading := False;
end; end;
FLoading := False;
HideSpinner('spinner');
end; end;
procedure TFViewComplaints.tmrRefreshTimer(Sender: TObject); procedure TFViewComplaints.tmrRefreshTimer(Sender: TObject);
begin begin
GetComplaints; GetComplaints;
......
...@@ -81,6 +81,7 @@ object FViewMap: TFViewMap ...@@ -81,6 +81,7 @@ object FViewMap: TFViewMap
object tmrLocate: TWebTimer object tmrLocate: TWebTimer
Enabled = False Enabled = False
Interval = 100 Interval = 100
OnTimer = tmrLocateTimer
Left = 174 Left = 174
Top = 74 Top = 74
end end
......
...@@ -27,22 +27,24 @@ type ...@@ -27,22 +27,24 @@ type
procedure lfMapCustomizeCSS(Sender: TObject; var ACustomizeCSS: string); procedure lfMapCustomizeCSS(Sender: TObject; var ACustomizeCSS: string);
procedure tmrRefreshTimer(Sender: TObject); procedure tmrRefreshTimer(Sender: TObject);
procedure btnFindLocationClick(Sender: TObject); procedure btnFindLocationClick(Sender: TObject);
procedure tmrLocateTimer(Sender: TObject);
private private
userLocationMarker: TTMSFNCMapsMarker; userLocationMarker: TTMSFNCMapsMarker;
geoWatchId: Integer; geoWatchId: Integer;
FUnitsLoaded: Boolean; FUnitsLoaded: Boolean;
FComplaintsLoaded: Boolean; FComplaintsLoaded: Boolean;
FZoomPending: Boolean;
FLoadingPoints: Boolean; FLoadingPoints: Boolean;
FDeviceCentered: Boolean;
mapFilters: TMapFilters; mapFilters: TMapFilters;
FPendingUnitId: string; FPendingUnitId: string;
FPendingComplaintId: string; FPendingComplaintId: string;
[async] procedure LoadPointsAsync; FPendingFocusCoord: TTMSFNCMapsCoordinateRec;
FPendingFocusZoom: Integer;
FDoFocusZoom: Boolean;
[async] procedure LoadPointsAsync(showBusy: Boolean);
function CarIconForDistrict(const DistrictCode: string): string; function CarIconForDistrict(const DistrictCode: string): string;
procedure UpdateDeviceLocation(lat, lng: Double); procedure UpdateDeviceLocation(lat, lng: Double);
procedure StartDeviceLocation; procedure StartDeviceLocation;
procedure StopDeviceLocation;
procedure ApplyPendingUnitFocus; procedure ApplyPendingUnitFocus;
procedure ApplyPendingComplaintFocus; procedure ApplyPendingComplaintFocus;
public public
...@@ -65,7 +67,6 @@ begin ...@@ -65,7 +67,6 @@ begin
ShowSpinner('spinner'); ShowSpinner('spinner');
FUnitsLoaded := False; FUnitsLoaded := False;
FComplaintsLoaded := False; FComplaintsLoaded := False;
FDeviceCentered := False;
httpReqGeoJson.Execute; httpReqGeoJson.Execute;
asm asm
window.showComplaintDetails = function (id) { window.showComplaintDetails = function (id) {
...@@ -103,12 +104,9 @@ begin ...@@ -103,12 +104,9 @@ begin
userLocationMarker.Latitude := lat; userLocationMarker.Latitude := lat;
userLocationMarker.Longitude := lng; userLocationMarker.Longitude := lng;
end; end;
procedure TFViewMap.StartDeviceLocation; procedure TFViewMap.StartDeviceLocation;
begin begin
asm asm
...@@ -148,25 +146,10 @@ begin ...@@ -148,25 +146,10 @@ begin
end; end;
procedure TFViewMap.StopDeviceLocation;
begin
asm
const self = this;
if (self.geoWatchId != null && self.geoWatchId !== 0 && navigator.geolocation) {
try { navigator.geolocation.clearWatch(self.geoWatchId); } catch(e) {}
self.geoWatchId = 0;
}
end;
end;
[async] procedure TFViewMap.httpReqGeoJsonResponse(Sender: TObject; AResponse: string); [async] procedure TFViewMap.httpReqGeoJsonResponse(Sender: TObject; AResponse: string);
var var
i: Integer; i: Integer;
P: TTMSFNCMapsPolygon; P: TTMSFNCMapsPolygon;
nm: string;
begin begin
lfMap.BeginUpdate; lfMap.BeginUpdate;
try try
...@@ -217,7 +200,7 @@ begin ...@@ -217,7 +200,7 @@ begin
lfMap.EndUpdate; lfMap.EndUpdate;
end; end;
await(LoadPointsAsync); await(LoadPointsAsync(True));
if mapFilters = nil then if mapFilters = nil then
begin begin
...@@ -246,7 +229,7 @@ begin ...@@ -246,7 +229,7 @@ begin
end; end;
[async] procedure TFViewMap.LoadPointsAsync; [async] procedure TFViewMap.LoadPointsAsync(showBusy: Boolean);
var var
resp: TXDataClientResponse; resp: TXDataClientResponse;
root, item, uo: TJSObject; root, item, uo: TJSObject;
...@@ -256,7 +239,7 @@ var ...@@ -256,7 +239,7 @@ var
lat, lng: Double; lat, lng: Double;
uName, dist: string; uName, dist: string;
unitId, callType, priorityText, statusText: string; unitId, callType, priorityText, statusText: string;
complaintId, codeDesc, dispatchDist, priority: string; complaintId, codeDesc, dispatchDist, priority, business: 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;
...@@ -272,7 +255,9 @@ begin ...@@ -272,7 +255,9 @@ begin
Exit; Exit;
FLoadingPoints := True; FLoadingPoints := True;
ShowSpinner('spinner');
if showBusy then
ShowSpinner('spinner');
try try
FUnitsLoaded := False; FUnitsLoaded := False;
FComplaintsLoaded := False; FComplaintsLoaded := False;
...@@ -435,6 +420,7 @@ begin ...@@ -435,6 +420,7 @@ begin
codeDesc := string(item['DispatchCodeDesc']); codeDesc := string(item['DispatchCodeDesc']);
dispatchDist := string(item['DispatchDistrict']); dispatchDist := string(item['DispatchDistrict']);
priority := string(item['Priority']); priority := string(item['Priority']);
business := string(item['Business']);
lat := Double(item['Lat']); lat := Double(item['Lat']);
lng := Double(item['Lng']); lng := Double(item['Lng']);
...@@ -489,6 +475,12 @@ begin ...@@ -489,6 +475,12 @@ begin
'<div class="small">' + '<div class="small">' +
'<span class="fw-bold">Dispatch District:</span> ' + dispatchDist + '<span class="fw-bold">Dispatch District:</span> ' + dispatchDist +
'</div>' + '</div>' +
IfThen(Trim(business) <> '',
'<div class="small">' +
'<span class="fw-bold">Business:</span> ' + business +
'</div>',
''
) +
'<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> ' + string(item['Address']) +
'</div>' + '</div>' +
...@@ -526,13 +518,13 @@ begin ...@@ -526,13 +518,13 @@ begin
ApplyPendingUnitFocus; ApplyPendingUnitFocus;
ApplyPendingComplaintFocus; ApplyPendingComplaintFocus;
finally finally
HideSpinner('spinner'); if showBusy then
FLoadingPoints := False; HideSpinner('spinner');
FLoadingPoints := False;
end; end;
end; end;
procedure TFViewMap.lfMapCustomizeMarker(Sender: TObject; var ACustomizeMarker: string); procedure TFViewMap.lfMapCustomizeMarker(Sender: TObject; var ACustomizeMarker: string);
begin begin
ACustomizeMarker := ACustomizeMarker :=
...@@ -640,12 +632,25 @@ begin ...@@ -640,12 +632,25 @@ begin
'.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;
end; end;
procedure TFViewMap.tmrLocateTimer(Sender: TObject);
begin
tmrLocate.Enabled := False;
if not FDoFocusZoom then
Exit;
lfMap.SetCenterCoordinate(FPendingFocusCoord);
lfMap.SetZoomLevel(FPendingFocusZoom);
FDoFocusZoom := False;
end;
procedure TFViewMap.tmrRefreshTimer(Sender: TObject); procedure TFViewMap.tmrRefreshTimer(Sender: TObject);
begin begin
if FLoadingPoints then if FLoadingPoints then
Exit; Exit;
LoadPointsAsync; LoadPointsAsync(False);
end; end;
procedure TFViewMap.btnFindLocationClick(Sender: TObject); procedure TFViewMap.btnFindLocationClick(Sender: TObject);
...@@ -664,7 +669,7 @@ procedure TFViewMap.FocusUnit(const unitId: string); ...@@ -664,7 +669,7 @@ procedure TFViewMap.FocusUnit(const unitId: string);
begin begin
FPendingUnitId := Trim(unitId); FPendingUnitId := Trim(unitId);
if mapFilters <> nil then if mapFilters <> nil then
LoadPointsAsync; LoadPointsAsync(True);
end; end;
...@@ -672,7 +677,7 @@ procedure TFViewMap.FocusComplaint(const complaintId: string); ...@@ -672,7 +677,7 @@ procedure TFViewMap.FocusComplaint(const complaintId: string);
begin begin
FPendingComplaintId := Trim(complaintId); FPendingComplaintId := Trim(complaintId);
if mapFilters <> nil then if mapFilters <> nil then
LoadPointsAsync; LoadPointsAsync(True);
end; end;
...@@ -686,15 +691,25 @@ var ...@@ -686,15 +691,25 @@ var
begin begin
if Trim(FPendingUnitId) = '' then if Trim(FPendingUnitId) = '' then
Exit; Exit;
targetDs := 'unit|' + FPendingUnitId; targetDs := 'unit|' + FPendingUnitId;
found := False; found := False;
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) then
begin begin
coord := CreateCoordinate(m.Latitude, m.Longitude); coord := CreateCoordinate(m.Latitude, m.Longitude);
lfMap.SetCenterCoordinate(coord); lfmap.SetCenterCoordinate(coord);
FPendingFocusCoord := coord;
FPendingFocusZoom := 17;
FDoFocusZoom := True;
tmrLocate.Interval := 250;
tmrLocate.Enabled := True;
found := True; found := True;
Break; Break;
end; end;
...@@ -704,7 +719,6 @@ begin ...@@ -704,7 +719,6 @@ begin
FPendingUnitId := ''; FPendingUnitId := '';
end; end;
procedure TFViewMap.ApplyPendingComplaintFocus; procedure TFViewMap.ApplyPendingComplaintFocus;
var var
i: Integer; i: Integer;
...@@ -725,7 +739,15 @@ begin ...@@ -725,7 +739,15 @@ begin
if SameText(m.DataString, targetDs) then if SameText(m.DataString, targetDs) then
begin begin
coord := CreateCoordinate(m.Latitude, m.Longitude); coord := CreateCoordinate(m.Latitude, m.Longitude);
lfMap.SetCenterCoordinate(coord); lfmap.SetCenterCoordinate(coord);
FPendingFocusCoord := coord;
FPendingFocusZoom := 17;
FDoFocusZoom := True;
tmrLocate.Interval := 250;
tmrLocate.Enabled := True;
found := True; found := True;
Break; Break;
end; end;
...@@ -735,5 +757,7 @@ begin ...@@ -735,5 +757,7 @@ begin
FPendingComplaintId := ''; FPendingComplaintId := '';
end; end;
end. end.
...@@ -57,7 +57,7 @@ object FViewUnitDetails: TFViewUnitDetails ...@@ -57,7 +57,7 @@ object FViewUnitDetails: TFViewUnitDetails
Top = 326 Top = 326
Width = 96 Width = 96
Height = 25 Height = 25
Caption = 'View On Map' Caption = 'Map'
ChildOrder = 1 ChildOrder = 1
ElementID = 'btn_unit_view_on_map' ElementID = 'btn_unit_view_on_map'
ElementFont = efCSS ElementFont = efCSS
......
...@@ -7,16 +7,21 @@ ...@@ -7,16 +7,21 @@
<!-- Summary header --> <!-- Summary header -->
<div class="card border-0 shadow-sm mb-2"> <div class="card border-0 shadow-sm mb-2">
<div class="card-header bg-white py-2"> <div class="card-header bg-white py-2">
<button <button
class="btn btn-link text-decoration-none p-0 w-100 d-flex align-items-center justify-content-between" class="btn btn-link text-decoration-none p-0 w-100 d-flex align-items-center justify-content-between summary-toggle"
type="button" type="button"
data-bs-toggle="collapse" data-bs-toggle="collapse"
data-bs-target="#udetails_summary" data-bs-target="#udetails_summary"
aria-expanded="true" aria-expanded="true"
aria-controls="udetails_summary"> aria-controls="udetails_summary">
<span class="fw-semibold text-dark" id="lbl_summary_title">Summary</span> <span class="fw-semibold text-dark" id="lbl_summary_title">Summary</span>
<i class="fa fa-chevron-down"></i>
</button> <span class="summary-chevron" aria-hidden="true">
<svg class="summary-chevron-icon" viewBox="0 0 16 16" focusable="false">
<path fill="currentColor" d="M7.646 5.354a.5.5 0 0 1 .708 0l5 5a.5.5 0 0 1-.708.708L8 6.414 3.354 11.06a.5.5 0 1 1-.708-.708l5-5z"/>
</svg>
</span>
</button>
</div> </div>
</div> </div>
...@@ -91,7 +96,7 @@ ...@@ -91,7 +96,7 @@
type="button" type="button"
class="btn btn-primary btn-sm shadow position-fixed" class="btn btn-primary btn-sm shadow position-fixed"
style="right: 12px; bottom: 72px; z-index: 1040;"> style="right: 12px; bottom: 72px; z-index: 1040;">
View On Map Map
</button> </button>
</div> </div>
......
...@@ -39,24 +39,21 @@ object FViewUnits: TFViewUnits ...@@ -39,24 +39,21 @@ object FViewUnits: TFViewUnits
Style = lsListGroup Style = lsListGroup
DataSource = wdsUnits DataSource = wdsUnits
ItemTemplate = ItemTemplate =
'<div class="list-section-header small fw-semibold bg-body-secon' + '<div class="list-section-header small fw-semibold bg-body-second' +
'dary text-dark rounded-1 px-2 mb-1"> (%DistrictHeader%)</div><d' + 'ary text-dark rounded-1 px-2 mb-1">(%DistrictHeader%)</div><div ' +
'iv class="card border shadow-sm position-relative"> <div class=' + 'class="card border shadow-sm"> <div class="card-body py-2 px-3 ' +
'"card-body py-2 px-3"> <!-- Unit + Status --> <div class="' + 'd-flex gap-2"> <div class="flex-grow-1"> <div class="fw-' +
'fw-bold text-uppercase small"> (%UnitName%)&nbsp;-&nbsp;(%S' + 'bold text-uppercase small">(%UnitName%)&nbsp;-&nbsp;(%Status%)</' +
'tatus%) </div> <!-- Location --> <div class="small text' + 'div> <div class="small text-body-secondary mb-1">(%Location' +
'-body-secondary mb-1">(%Location%)</div> <!-- Call type --> ' + '%)</div> <div class="small">(%CallType%)</div> <hr cla' +
' <div class="small">(%CallType%)</div> <!-- Divider line -->' + 'ss="unit-divider my-1" style="width: 80px; margin-left: 0" /> ' +
' <hr class="unit-divider my-1" style="width: 80px; margin-lef' + ' <div class="small officer1">(%Officer1%)</div> <div clas' +
't: 0" /> <!-- Officers --> <div class="small officer1">(%O' + 's="small officer2">(%Officer2%)</div> </div> <div class="d' +
'fficer1%)</div> <div class="small officer2">(%Officer2%)</div' + '-flex flex-column justify-content-center gap-1"> <button ty' +
'> </div> <!-- Vertically centered Details button on the right ' + 'pe="button" class="btn btn-primary btn-sm btn-unit-details" data' +
'--> <div class="position-absolute top-50 end-0 translate-middle' + '-unitid="(%UnitId%)">Details</button> <button type="button"' +
'-y pe-2"> <button type="button" class="btn btn-prim' + ' class="btn btn-primary btn-sm btn-unit-map" data-unitid="(%Unit' +
'ary btn-sm btn-unit-details" data-unitid="(%UnitId%)" > ' + 'Id%)">View On Map</button> </div> </div></div>'
' Details </button> <button type="button" class=' +
'"btn btn-primary btn-sm btn-unit-map" data-unitid="(%Unit' +
'Id%)"> View On Map </button> </div></div>'
ListSource = wdsUnits ListSource = wdsUnits
end end
object wdsUnits: TWebDataSource object wdsUnits: TWebDataSource
......
...@@ -72,3 +72,16 @@ html, body { ...@@ -72,3 +72,16 @@ html, body {
.tab-hidden { display: none !important; } .tab-hidden { display: none !important; }
.summary-chevron-icon {
width: 1rem;
height: 1rem;
display: block;
transition: transform 0.15s ease-in-out;
}
/* Expanded => show DOWN (rotate base UP chevron) */
.summary-toggle[aria-expanded="true"] .summary-chevron-icon {
transform: rotate(180deg);
}
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