|
|
|
|
@ -125,9 +125,9 @@ class _MapTrackingPageState extends State<MapTrackingPage> {
|
|
|
|
|
provider.coordinates = [];
|
|
|
|
|
provider.assetsOnTheFloorList = [];
|
|
|
|
|
provider.notify();
|
|
|
|
|
|
|
|
|
|
provider.getAssetsFromPenguinByFloor();
|
|
|
|
|
|
|
|
|
|
Utils.showLoading(context);
|
|
|
|
|
await provider.getAssetsFromPenguinByFloor();
|
|
|
|
|
Utils.hideLoading(context);
|
|
|
|
|
if (provider.selectedFloor != null) {
|
|
|
|
|
getFloorMap(provider.selectedFloor!.id!);
|
|
|
|
|
provider.getZoneFromPenguin();
|
|
|
|
|
@ -481,9 +481,6 @@ class _MapTrackingPageState extends State<MapTrackingPage> {
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
// if (!inAppView || )
|
|
|
|
|
if (markers.isNotEmpty) MarkerLayer(markers: markers),
|
|
|
|
|
],
|
|
|
|
|
if (inAppView && _geojson == null)
|
|
|
|
|
Selector<AssetTrackingProvider, List<Coordinates>>(
|
|
|
|
|
@ -503,19 +500,64 @@ class _MapTrackingPageState extends State<MapTrackingPage> {
|
|
|
|
|
_lastFittedCoordinatesKey = key;
|
|
|
|
|
_fitCameraToPoints(list);
|
|
|
|
|
}
|
|
|
|
|
List<Polygon> zonesPolygons = [
|
|
|
|
|
Polygon(
|
|
|
|
|
label: assetTrackingProvider.selectedBuilding?.label ?? "",
|
|
|
|
|
labelStyle: AppTextStyles.bodyText2.copyWith(color: AppColor.textColor(context)),
|
|
|
|
|
points: list,
|
|
|
|
|
color: AppColor.red30.withOpacity(0.3),
|
|
|
|
|
borderColor: AppColor.red30,
|
|
|
|
|
borderStrokeWidth: 2.0,
|
|
|
|
|
),
|
|
|
|
|
];
|
|
|
|
|
return PolygonLayer(polygons: zonesPolygons, hitNotifier: _polygonHitNotifier);
|
|
|
|
|
final buildingLabel = assetTrackingProvider.selectedBuilding?.label ?? "";
|
|
|
|
|
|
|
|
|
|
// Assets fetched without floorIds => all assets of the selected building.
|
|
|
|
|
return Selector<AssetTrackingProvider, List<AssetTrackingModel>>(
|
|
|
|
|
selector: (_, provider) => List<AssetTrackingModel>.of(provider.assetsOnTheFloorList),
|
|
|
|
|
builder: (_, buildingAssets, __) {
|
|
|
|
|
final zone = GeoZone(
|
|
|
|
|
properties: {'name': buildingLabel.isEmpty ? "Building" : buildingLabel},
|
|
|
|
|
points: list,
|
|
|
|
|
assets: buildingAssets,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final buildingPolygon = Polygon<Object>(
|
|
|
|
|
label: buildingLabel,
|
|
|
|
|
labelStyle: AppTextStyles.bodyText2.copyWith(color: AppColor.textColor(context)),
|
|
|
|
|
labelPlacementCalculator: const PolygonLabelPlacementCalculator.simpleCentroid(),
|
|
|
|
|
points: list,
|
|
|
|
|
color: AppColor.red30.withOpacity(0.3),
|
|
|
|
|
borderColor: AppColor.red30,
|
|
|
|
|
borderStrokeWidth: 2.0,
|
|
|
|
|
hitValue: zone,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return Stack(
|
|
|
|
|
children: [
|
|
|
|
|
GestureDetector(
|
|
|
|
|
onTap: _onFeatureTapped,
|
|
|
|
|
child: PolygonLayer(polygons: [buildingPolygon], hitNotifier: _polygonHitNotifier),
|
|
|
|
|
),
|
|
|
|
|
// Hide the count badge while asset pins are shown (same as floor view).
|
|
|
|
|
if (buildingAssets.isNotEmpty && markers.isEmpty)
|
|
|
|
|
MarkerLayer(
|
|
|
|
|
markers: [
|
|
|
|
|
Marker(
|
|
|
|
|
point: buildingPolygon.labelPosition,
|
|
|
|
|
width: 21,
|
|
|
|
|
height: 33,
|
|
|
|
|
// Sit the badge just above the building label so they don't overlap.
|
|
|
|
|
alignment: Alignment.topCenter,
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.only(bottom: 12),
|
|
|
|
|
child: GestureDetector(
|
|
|
|
|
onTap: () => _showZoneDetails(zone),
|
|
|
|
|
child: _ZoneCountBadge(count: buildingAssets.length),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
if (_geojson != null && inAppView)
|
|
|
|
|
// Selected asset pins (floor map or building outline).
|
|
|
|
|
if (markers.isNotEmpty) MarkerLayer(markers: markers),
|
|
|
|
|
// Assets panel: shown for both floor view and building-only view.
|
|
|
|
|
if (inAppView)
|
|
|
|
|
Positioned(
|
|
|
|
|
bottom: 0,
|
|
|
|
|
left: 0,
|
|
|
|
|
@ -523,6 +565,7 @@ class _MapTrackingPageState extends State<MapTrackingPage> {
|
|
|
|
|
child: Selector<AssetTrackingProvider, List<AssetTrackingModel>>(
|
|
|
|
|
selector: (_, myModel) => myModel.assetsOnTheFloorList,
|
|
|
|
|
builder: (_, assetsOnTheFloorList, __) {
|
|
|
|
|
final scope = _geojson != null ? "Floor" : "Building";
|
|
|
|
|
return assetsOnTheFloorList.isEmpty
|
|
|
|
|
? const SizedBox()
|
|
|
|
|
: Container(
|
|
|
|
|
@ -533,12 +576,12 @@ class _MapTrackingPageState extends State<MapTrackingPage> {
|
|
|
|
|
border: Border.all(color: AppColor.tabBarBorder(context)),
|
|
|
|
|
borderRadius: BorderRadius.circular(20),
|
|
|
|
|
),
|
|
|
|
|
child: UpwardExpansionTile(title: InfoTextLabelWidget(label: "${assetsOnTheFloorList.length} Assets found on this floor"), children: [
|
|
|
|
|
child: UpwardExpansionTile(title: InfoTextLabelWidget(label: "${assetsOnTheFloorList.length} Assets found on this ${scope.toLowerCase()}"), children: [
|
|
|
|
|
LimitedBox(
|
|
|
|
|
maxHeight: 120,
|
|
|
|
|
child: MultipleItemDropDownMenu<AssetTrackingModel, NullableLoadingProvider>(
|
|
|
|
|
context: context,
|
|
|
|
|
title: 'Assets on The Floor',
|
|
|
|
|
title: 'Assets on The $scope',
|
|
|
|
|
hintMsg: 'Search By Label or Serial Number',
|
|
|
|
|
initialValue: [],
|
|
|
|
|
showShadow: false,
|
|
|
|
|
@ -694,6 +737,8 @@ class _MapTrackingPageState extends State<MapTrackingPage> {
|
|
|
|
|
label: "View",
|
|
|
|
|
disableButton: assetProvider.selectedSite == null || assetProvider.selectedBuilding == null,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
_onViewPressed(assetTrackingProvider);
|
|
|
|
|
return;
|
|
|
|
|
expansibleController.collapse();
|
|
|
|
|
assetTrackingProvider.coordinates.clear();
|
|
|
|
|
assetTrackingProvider.assetsOnTheFloorList.clear();
|
|
|
|
|
|