asset tagging

main_production_asset_tracking
Sikander Saleem 5 days ago
parent 5658059543
commit e4f2089126

@ -89,7 +89,7 @@ class URLs {
static get getAssets => "$_baseUrl/Asset/GetAssets"; // get static get getAssets => "$_baseUrl/Asset/GetAssets"; // get
static get getFaultDescription => "$_baseUrl/Asset/GetDefectForModelDefinition"; // get static get getFaultDescription => "$_baseUrl/Asset/GetDefectForModelDefinition"; // get
static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get
static get assignTagToAsset => "$_baseUrl/Asset/AssignTagToAsset'"; // get static get assignTagToAsset => "$_baseUrl/Asset/AssignTagToAsset"; // get
static get getAssetColumnsMetadata => "$_baseUrl/Asset/columns/metadata"; // get asset export columns metadata static get getAssetColumnsMetadata => "$_baseUrl/Asset/columns/metadata"; // get asset export columns metadata
static get saveAssetImages => "$_baseUrl/Asset/SaveAssetImages"; // get static get saveAssetImages => "$_baseUrl/Asset/SaveAssetImages"; // get
static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2

@ -258,17 +258,15 @@ class AssetProvider extends ChangeNotifier {
} }
} }
Future<List> linkAssetWithPenguinTag(int assetId, int penguinAssetTagId) async { Future<bool> linkAssetWithPenguinTag(int assetId, int penguinAssetTagId) async {
try { try {
final response = await ApiManager.instance.post(URLs.assignTagToAsset, body: {"assetId": assetId, "penguinAssetTagId": penguinAssetTagId}); final response = await ApiManager.instance.post(URLs.assignTagToAsset, body: {"assetId": assetId, "penguinAssetTagId": penguinAssetTagId});
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
final Map<String, dynamic> jsonData = json.decode(response.body); return true;
List list = jsonData["data"];
return list;
} }
return []; return false;
} catch (error) { } catch (error) {
return []; return false;
} }
} }
} }

@ -5,6 +5,7 @@ import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/modules/asset_tracking/models/coordinates_model.dart'; import 'package:test_sa/modules/asset_tracking/models/coordinates_model.dart';
import 'package:test_sa/modules/asset_tracking/models/asset_tracking_search_model.dart'; import 'package:test_sa/modules/asset_tracking/models/asset_tracking_search_model.dart';
import 'package:test_sa/views/widgets/equipment/asset_tag_model.dart';
import 'models/asset_tracking_model.dart'; import 'models/asset_tracking_model.dart';
import 'models/floor_map_model.dart'; import 'models/floor_map_model.dart';
@ -260,19 +261,37 @@ class AssetTrackingProvider extends ChangeNotifier {
} }
int assetTagPageNumber = 1; int assetTagPageNumber = 1;
int? totalAssetTags;
List<AssetTagModel> tagList = [];
Future<List> getPenguinAssetTags(int tagStatus) async { bool isLoadingAssetTags = false;
void resetAssetTagData() {
tagList.clear();
assetTagPageNumber = 1;
totalAssetTags = null;
}
bool get isCanLoadMore => tagList.length < (totalAssetTags ?? 0);
Future getPenguinAssetTags() async {
if (isLoadingAssetTags) return;
try { try {
final response = await ApiManager.instance.get(URLs.getPenguinAssetTags + "?pageNumber=$assetTagPageNumber&tagStatus=$tagStatus"); isLoadingAssetTags = true;
notify();
final response = await ApiManager.instance.get(URLs.getPenguinAssetTags + "?pageNumber=$assetTagPageNumber&tagStatus=1");
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
final Map<String, dynamic> jsonData = json.decode(response.body); final Map<String, dynamic> jsonData = json.decode(response.body);
List list = jsonData["data"]; List list = jsonData["response"]["data"];
return list; totalAssetTags ??= jsonData["response"]["totalRows"];
tagList.addAll(list.map((item) => AssetTagModel.fromJson(item)).toList());
if (tagList.length < totalAssetTags!) {
assetTagPageNumber += 1;
}
} }
return []; } catch (error) {}
} catch (error) { isLoadingAssetTags = false;
return []; notify();
}
} }
Future<List> linkAssetWithPenguinTag(int assetId, int penguinTagId) async { Future<List> linkAssetWithPenguinTag(int assetId, int penguinTagId) async {

@ -349,7 +349,7 @@ class _AssetDetailPageState extends State<AssetDetailPage> with SingleTickerProv
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const InfoTextLabelWidget(label: '*Asset is not associated with tag', color: AppColor.red30).flexible, const InfoTextLabelWidget(label: '*Asset not linked with tracking tag', color: AppColor.red30).flexible,
Container( Container(
margin: const EdgeInsets.only(left: 12, right: 12), margin: const EdgeInsets.only(left: 12, right: 12),
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8), padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
@ -359,15 +359,9 @@ class _AssetDetailPageState extends State<AssetDetailPage> with SingleTickerProv
), ),
child: Text( child: Text(
"Link Tag", "Link Tag",
style: AppTextStyles.bodyText2.copyWith(color: AppColor.textStyleColor(context)), style: AppTextStyles.bodyText2.copyWith(color: AppColor.addItemButtonColor(context)),
), ),
).onPress(() { ).onPress(_linkAssetTag),
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => AssetTagListView(),
),
);
}),
], ],
), ),
] else ...[ ] else ...[
@ -444,4 +438,14 @@ class _AssetDetailPageState extends State<AssetDetailPage> with SingleTickerProv
setState(() {}); setState(() {});
} }
} }
void _linkAssetTag() async {
bool reload =
await Navigator.push(context, MaterialPageRoute(builder: (context) => AssetTagListView(assetId!, assetModel!.modelDefinition!.assetName!, assetModel!.multiAssets!.first.assetNumber!))) ??
false;
if (reload) {
assetModel = null;
setState(() {});
}
}
} }

@ -1,75 +1,151 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/devices_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/helper/utils.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/asset_tracking/asset_tracking_provider.dart'; import 'package:test_sa/modules/asset_tracking/asset_tracking_provider.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/views/widgets/dialogs/dialog.dart';
import 'package:test_sa/views/widgets/item_views/info_header_widget.dart';
import 'package:test_sa/views/widgets/item_views/info_text_widget.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
class AssetTagListView extends StatelessWidget { class AssetTagListView extends StatefulWidget {
AssetTagListView({Key? key}) : super(key: key); int assetId;
String assetName;
String assetNumber;
AssetTagListView(this.assetId, this.assetName, this.assetNumber, {Key? key}) : super(key: key);
@override
_AssetTagListViewState createState() {
return _AssetTagListViewState();
}
}
class _AssetTagListViewState extends State<AssetTagListView> with SingleTickerProviderStateMixin {
late AnimationController _animationController;
late AssetTrackingProvider assetTrackingProvider;
@override
void initState() {
super.initState();
assetTrackingProvider = Provider.of<AssetTrackingProvider>(context, listen: false);
assetTrackingProvider.resetAssetTagData();
_animationController = AnimationController(
duration: const Duration(milliseconds: 1200),
vsync: this,
);
_animationController.forward();
WidgetsBinding.instance.addPostFrameCallback((_) {
assetTrackingProvider.getPenguinAssetTags();
});
}
@override
void dispose() {
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: const DefaultAppBar(title: "Available Tags"), appBar: const DefaultAppBar(title: "Available Tracking Tags"),
body: SizedBox()); body: Consumer<AssetTrackingProvider>(builder: (context, provider, _) {
return provider.isLoadingAssetTags && provider.tagList.isEmpty
? const Center(child: ALoading())
: (provider.tagList.isEmpty && !provider.isLoading)
? NoDataFound(message: context.translation.noDataFound).center
: NotificationListener<ScrollNotification>(
onNotification: (scrollInfo) {
if (provider.isCanLoadMore && scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
assetTrackingProvider.getPenguinAssetTags();
}
return false;
},
child: SafeArea(
child: ListView.separated(
key: const ValueKey('asset-tag-list-view'),
padding: const EdgeInsets.all(16),
itemCount: provider.tagList.length + (provider.isLoadingAssetTags ? 1 : 0),
separatorBuilder: (listContext, itemIndex) => 12.height,
itemBuilder: (listContext, itemIndex) {
if (itemIndex == provider.tagList.length) {
return const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: ALoading(),
);
}
final delay = itemIndex * 0.08;
final animation = Tween<double>(begin: 0.0, end: 1.0).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
delay.clamp(0.0, 0.7),
(delay + 0.4).clamp(0.0, 1.0),
curve: Curves.easeOut,
),
),
);
final slideAnimation = Tween<Offset>(
begin: const Offset(0.0, 0.15),
end: Offset.zero,
).animate(
CurvedAnimation(
parent: _animationController,
curve: Interval(
delay.clamp(0.0, 0.7),
(delay + 0.4).clamp(0.0, 1.0),
curve: Curves.easeOutCubic,
),
),
);
// FutureBuilder<List>( return FadeTransition(
// future: Provider.of<AssetTrackingProvider>(context, listen: false).getPenguinAssetTags(), opacity: animation,
// builder: (BuildContext context, AsyncSnapshot<List> snapshot) { child: SlideTransition(
// if (snapshot.connectionState == ConnectionState.waiting) { position: slideAnimation,
// return const Center(child: ALoading()); child: Column(
// } else if (snapshot.hasData) {} mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// return SizedBox(); children: [
// InfoHeaderWidget(provider.tagList[itemIndex].label!),
// // return ListView.separated( InfoTextWidget(label: "TagID", value: provider.tagList[itemIndex].tagID, showEmptyValue: true),
// // key: const ValueKey('list_view'), InfoTextWidget(label: "Mac Address", value: provider.tagList[itemIndex].macAddress, showEmptyValue: true),
// // padding: const EdgeInsets.all(16), ],
// // itemCount: _searchableList.length, ).toShadowContainer(context))
// // separatorBuilder: (listContext, itemIndex) => 12.height, .onPress(() async {
// // itemBuilder: (listContext, itemIndex) { bool result = await showDialog(
// // // Calculate staggered animation delay context: context,
// // final delay = itemIndex * 0.08; builder: (_) => AAlertDialog(
// // final animation = Tween<double>(begin: 0.0, end: 1.0).animate( title: "Confirm".addTranslation,
// // CurvedAnimation( content: 'You are assigning\n'
// // parent: _animationController, '"${provider.tagList[itemIndex].label!}" -> "${widget.assetName}(${widget.assetNumber})"'
// // curve: Interval( .addTranslation,
// // delay.clamp(0.0, 0.7), button1Text: "Assign",
// // (delay + 0.4).clamp(0.0, 1.0), ),
// // curve: Curves.easeOut, );
// // ), if (result) {
// // ), Utils.showLoading(context);
// // ); result = await Provider.of<AssetProvider>(context, listen: false).linkAssetWithPenguinTag(widget.assetId, provider.tagList[itemIndex].id!);
// // Utils.hideLoading(context);
// // final slideAnimation = Tween<Offset>( if (result) {
// // begin: const Offset(0.0, 0.15), Navigator.pop(context, result);
// // end: Offset.zero, }
// // ).animate( }
// // CurvedAnimation( }),
// // parent: _animationController, );
// // curve: Interval( },
// // delay.clamp(0.0, 0.7), ),
// // (delay + 0.4).clamp(0.0, 1.0), ),
// // curve: Curves.easeOutCubic, );
// // ), }));
// // ),
// // );
// //
// // return FadeTransition(
// // opacity: animation,
// // child: SlideTransition(
// // position: slideAnimation,
// // child: AssetItemListView(
// // device: _searchableList[itemIndex],
// // onPressed: (device) {
// // widget.fromBottomBar ? Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.id) : Navigator.of(context).pop(device);
// // },
// // ),
// // ),
// // );
// // },
// // );
// }));
} }
} }

@ -0,0 +1,44 @@
class AssetTagModel {
int? id;
String? tagID;
String? label;
String? macAddress;
String? type;
String? status;
String? assetName;
String? assetNumber;
AssetTagModel(
{this.id,
this.tagID,
this.label,
this.macAddress,
this.type,
this.status,
this.assetName,
this.assetNumber});
AssetTagModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
tagID = json['tagID'];
label = json['label'];
macAddress = json['macAddress'];
type = json['type'];
status = json['status'];
assetName = json['assetName'];
assetNumber = json['assetNumber'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tagID'] = this.tagID;
data['label'] = this.label;
data['macAddress'] = this.macAddress;
data['type'] = this.type;
data['status'] = this.status;
data['assetName'] = this.assetName;
data['assetNumber'] = this.assetNumber;
return data;
}
}
Loading…
Cancel
Save