asset inventory module ready for qa
parent
c19fdb173b
commit
8578319cc3
@ -1,144 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:test_sa/extensions/int_extensions.dart';
|
||||
import 'package:test_sa/extensions/text_extensions.dart';
|
||||
import 'package:test_sa/new_views/app_style/app_color.dart';
|
||||
import 'package:test_sa/views/app_style/sizing.dart';
|
||||
|
||||
class AutoCompleteGenericField<T extends Object> extends StatefulWidget {
|
||||
final String? label;
|
||||
final String initialValue;
|
||||
final bool clearAfterPick;
|
||||
final Future<List<T>> Function(String query) onSearch;
|
||||
final String Function(T item) displayString;
|
||||
final Function(T item) onPick;
|
||||
|
||||
const AutoCompleteGenericField({
|
||||
Key? key,
|
||||
this.label,
|
||||
required this.initialValue,
|
||||
required this.onSearch,
|
||||
required this.displayString,
|
||||
required this.onPick,
|
||||
this.clearAfterPick = true,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<AutoCompleteGenericField<T>> createState() => _AutoCompleteGenericFieldState<T>();
|
||||
}
|
||||
|
||||
class _AutoCompleteGenericFieldState<T extends Object> extends State<AutoCompleteGenericField<T>> {
|
||||
late TextEditingController _controller;
|
||||
List<T> _options = [];
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_controller = TextEditingController(text: widget.initialValue);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant AutoCompleteGenericField<T> oldWidget) {
|
||||
if (widget.initialValue != oldWidget.initialValue) {
|
||||
_controller.text = widget.initialValue;
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
Future<void> _search(String query) async {
|
||||
if (query.isEmpty) {
|
||||
setState(() => _options = []);
|
||||
return;
|
||||
}
|
||||
setState(() => _isLoading = true);
|
||||
try {
|
||||
final results = await widget.onSearch(query);
|
||||
setState(() => _options = results);
|
||||
} finally {
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
|
||||
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.background(context),
|
||||
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
|
||||
),
|
||||
child: RawAutocomplete<T>(
|
||||
// textEditingController: _controller,
|
||||
optionsBuilder: (TextEditingValue textEditingValue) => _options,
|
||||
displayStringForOption: widget.displayString,
|
||||
fieldViewBuilder: (context, fieldTextEditingController, fieldFocusNode, onFieldSubmitted) {
|
||||
return TextField(
|
||||
controller: _controller,
|
||||
focusNode: fieldFocusNode,
|
||||
style: AppTextStyles.bodyText.copyWith(color: AppColor.black10),
|
||||
textAlign: TextAlign.start,
|
||||
decoration: InputDecoration(
|
||||
border: border,
|
||||
disabledBorder: border,
|
||||
focusedBorder: border,
|
||||
enabledBorder: border,
|
||||
errorBorder: border,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: 16.toScreenWidth),
|
||||
// suffixIcon: _isLoading
|
||||
// ? const Padding(
|
||||
// padding: EdgeInsets.all(8.0),
|
||||
// child: SizedBox(width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2)),
|
||||
// )
|
||||
// : const Icon(Icons.search, size: 18),
|
||||
filled: true,
|
||||
fillColor: AppColor.fieldBgColor(context),
|
||||
labelText: widget.label,
|
||||
labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.textColor(context)),
|
||||
),
|
||||
textInputAction: TextInputAction.search,
|
||||
onChanged: (text) => _search(text),
|
||||
onSubmitted: (_) => onFieldSubmitted(),
|
||||
);
|
||||
},
|
||||
onSelected: (T selection) {
|
||||
if (widget.clearAfterPick) {
|
||||
_controller.clear();
|
||||
} else {
|
||||
_controller.text = widget.displayString(selection);
|
||||
}
|
||||
widget.onPick(selection);
|
||||
},
|
||||
optionsViewBuilder: (context, onSelected, options) {
|
||||
return Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Material(
|
||||
elevation: 4,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 200, minWidth: 200),
|
||||
child: ListView.builder(
|
||||
padding: EdgeInsets.zero,
|
||||
itemCount: options.length,
|
||||
itemBuilder: (context, index) {
|
||||
final option = options.elementAt(index);
|
||||
return ListTile(
|
||||
title: Text(widget.displayString(option)),
|
||||
onTap: () => onSelected(option),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:test_sa/extensions/context_extension.dart';
|
||||
import 'package:test_sa/extensions/int_extensions.dart';
|
||||
import 'package:test_sa/models/lookup.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
|
||||
import 'package:test_sa/new_views/app_style/app_color.dart';
|
||||
import 'package:test_sa/views/app_style/sizing.dart';
|
||||
import '../../../extensions/text_extensions.dart';
|
||||
import '../../../new_views/app_style/app_text_style.dart';
|
||||
|
||||
class LookUpAutoCompleteField extends StatefulWidget {
|
||||
final String initialValue;
|
||||
final String label;
|
||||
final num? assetId;
|
||||
final bool forAssetName;
|
||||
final bool forSupplier;
|
||||
final bool clearAfterPick, isManufacturer;
|
||||
final Function(Lookup) onPick;
|
||||
final Function(String) onChanged;
|
||||
//need to pass directly url
|
||||
const LookUpAutoCompleteField(
|
||||
{Key? key,
|
||||
this.isManufacturer = false,
|
||||
required this.initialValue,
|
||||
required this.label,
|
||||
this.forAssetName = false,
|
||||
this.forSupplier = false,
|
||||
this.assetId,
|
||||
required this.onPick,
|
||||
this.clearAfterPick = true,
|
||||
required this.onChanged})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
_AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState();
|
||||
}
|
||||
|
||||
class _AutoCompletePartsFieldState extends State<LookUpAutoCompleteField> {
|
||||
AssetInventoryProvider? assetInventoryProvider;
|
||||
late TextEditingController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_controller = TextEditingController(text: widget.initialValue);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(covariant LookUpAutoCompleteField oldWidget) {
|
||||
if (widget.initialValue != oldWidget.initialValue) {
|
||||
_controller = TextEditingController(text: widget.initialValue);
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
assetInventoryProvider ??= Provider.of<AssetInventoryProvider>(context);
|
||||
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
color: AppColor.background(context),
|
||||
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
|
||||
// boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
|
||||
),
|
||||
child: Autocomplete<Lookup>(
|
||||
optionsBuilder: (TextEditingValue textEditingValue) async {
|
||||
if (textEditingValue.text.isEmpty) {
|
||||
return const Iterable<Lookup>.empty();
|
||||
}
|
||||
return (await assetInventoryProvider!.getAutoCompleteDetails(query: textEditingValue.text, isManufacturer: widget.isManufacturer, type: widget.forAssetName?1:widget.forSupplier?2:0));
|
||||
},
|
||||
displayStringForOption: (Lookup option) => option.name ?? "",
|
||||
fieldViewBuilder: (BuildContext context, TextEditingController fieldTextEditingController, FocusNode fieldFocusNode, VoidCallback onFieldSubmitted) {
|
||||
return TextField(
|
||||
controller: _controller,
|
||||
focusNode: fieldFocusNode,
|
||||
style: AppTextStyles.bodyText.copyWith(color: AppColor.black10),
|
||||
textAlign: TextAlign.start,
|
||||
decoration: InputDecoration(
|
||||
border: border,
|
||||
disabledBorder: border,
|
||||
focusedBorder: border,
|
||||
enabledBorder: border,
|
||||
errorBorder: border,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: 16.toScreenWidth),
|
||||
constraints: const BoxConstraints(),
|
||||
suffixIconConstraints: const BoxConstraints(minWidth: 0),
|
||||
filled: true,
|
||||
fillColor: AppColor.fieldBgColor(context),
|
||||
errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60),
|
||||
floatingLabelStyle: AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20),
|
||||
labelText: widget.label,
|
||||
labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.textColor(context)),
|
||||
),
|
||||
textInputAction: TextInputAction.search,
|
||||
onChanged: (text) {
|
||||
widget.onChanged(text);
|
||||
fieldTextEditingController.text = text;
|
||||
},
|
||||
onSubmitted: (String value) {
|
||||
onFieldSubmitted();
|
||||
},
|
||||
);
|
||||
},
|
||||
onSelected: (Lookup selection) {
|
||||
if (widget.clearAfterPick) {
|
||||
_controller.clear();
|
||||
} else {
|
||||
_controller.text = selection.name ?? '';
|
||||
}
|
||||
widget.onPick(selection);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1,77 +1,131 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/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/models/new_models/work_order_detail_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_form_view.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
|
||||
import 'package:test_sa/new_views/app_style/app_color.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
|
||||
|
||||
import 'asset_detail_card_view.dart';
|
||||
|
||||
class AssetInventoryScanAssetView extends StatefulWidget {
|
||||
int sessionId ;
|
||||
AssetInventoryScanAssetView({Key? key,required this.sessionId}) : super(key: key);
|
||||
int sessionId;
|
||||
|
||||
AssetInventoryScanAssetView({Key? key, required this.sessionId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<AssetInventoryScanAssetView> createState() => _AssetInventoryScanAssetViewState();
|
||||
}
|
||||
|
||||
|
||||
class _AssetInventoryScanAssetViewState extends State<AssetInventoryScanAssetView> {
|
||||
late AssetInventoryProvider assetInventoryProvider;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
assetInventoryProvider = Provider.of<AssetInventoryProvider>(context,listen:false);
|
||||
assetInventoryProvider = Provider.of<AssetInventoryProvider>(context, listen: false);
|
||||
super.initState();
|
||||
}
|
||||
Future<void> getAssetList({bool reset = false}) async {
|
||||
if (reset) {
|
||||
assetInventoryProvider.pageNo = 1;
|
||||
assetInventoryProvider.assetInventoryResponse = null;
|
||||
}
|
||||
|
||||
Future<void> getAssetList({bool loadMore = false}) async {
|
||||
await assetInventoryProvider.getAssetsInSession(
|
||||
sessionId: widget.sessionId,
|
||||
loadMore: loadMore,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<AssetInventoryProvider>(
|
||||
builder: (context, provider, _) {
|
||||
if (provider.isLoading && provider.assetInventoryResponse == null) {
|
||||
//TODO need use existing loader if found..
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
final assets = provider.assetInventoryResponse?.assetList ?? [];
|
||||
if (assets.isEmpty) {
|
||||
return const Center(child: NoDataFound());
|
||||
}
|
||||
return LazyLoading(
|
||||
nextPage: provider.nextPage,
|
||||
onLazyLoad: () async {
|
||||
await getAssetList();
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: (scrollInfo) {
|
||||
if (!provider.isNextPageLoading &&
|
||||
provider.nextPage &&
|
||||
scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
|
||||
getAssetList(loadMore: true);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: assets.length + (provider.isNextPageLoading ? 1 : 0),
|
||||
itemBuilder: (context, index) {
|
||||
return AssetDetailCardView(assetInventoryModel: assets[index]);
|
||||
if (index == assets.length) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
return AssetDetailCardView(
|
||||
assetInventoryModel: assets[index],
|
||||
onDeletePress: () async {
|
||||
await provider.deleteAssetISession(id: assets[index].id ?? 0).then((success) async {
|
||||
if (success) {
|
||||
await provider.getAssetsInSession(sessionId: widget.sessionId);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => 12.height,
|
||||
itemCount: assets.length,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _addAsset(BuildContext context) {
|
||||
//TODO need to confirm navigation...
|
||||
Navigator.push(context, MaterialPageRoute(builder: (contxt) => AssetInventoryFormView()));
|
||||
}
|
||||
// Widget build(BuildContext context) {
|
||||
// return Consumer<AssetInventoryProvider>(
|
||||
// builder: (context, provider, _) {
|
||||
// if (provider.isLoading && provider.assetInventoryResponse == null) {
|
||||
// //TODO need use existing loader if found..
|
||||
// return const Center(child: CircularProgressIndicator());
|
||||
// }
|
||||
// final assets = provider.assetInventoryResponse?.assetList ?? [];
|
||||
// if (assets.isEmpty) {
|
||||
// return const Center(child: NoDataFound());
|
||||
// }
|
||||
// return LazyLoading(
|
||||
// nextPage: provider.nextPage,
|
||||
// onLazyLoad: () async {
|
||||
// log('Loading next page...');
|
||||
// await getAssetList(loadMore: true);
|
||||
// },
|
||||
// child: ListView.separated(
|
||||
// padding: const EdgeInsets.all(16),
|
||||
// itemBuilder: (context, index) {
|
||||
// if (index == assets.length) {
|
||||
// // bottom loader
|
||||
// return const Padding(
|
||||
// padding: EdgeInsets.symmetric(vertical: 16),
|
||||
// child: Center(child: CircularProgressIndicator()),
|
||||
// );
|
||||
// }
|
||||
// return AssetDetailCardView(
|
||||
// assetInventoryModel: assets[index],
|
||||
// onDeletePress: () async {
|
||||
// await provider.deleteAssetISession(id: assets[index].id ?? 0).then((success) async {
|
||||
// if (success) {
|
||||
// await provider.getAssetsInSession(sessionId: widget.sessionId);
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// separatorBuilder: (context, index) => 12.height,
|
||||
// itemCount: assets.length + (provider.nextPage ? 1 : 0),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
@ -0,0 +1,311 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:test_sa/controllers/providers/api/all_requests_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/text_extensions.dart';
|
||||
import 'package:test_sa/extensions/widget_extensions.dart';
|
||||
import 'package:test_sa/models/new_models/building.dart';
|
||||
import 'package:test_sa/models/new_models/department.dart';
|
||||
import 'package:test_sa/models/new_models/floor.dart';
|
||||
import 'package:test_sa/models/new_models/room_model.dart';
|
||||
import 'package:test_sa/models/new_models/site.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/pages/asset_detail_card_view.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_form_view.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
|
||||
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
|
||||
import 'package:test_sa/new_views/app_style/app_color.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.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/providers/loading_list_notifier.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
||||
|
||||
class SiteInformationView extends StatefulWidget {
|
||||
SessionModel sessionModel;
|
||||
|
||||
SiteInformationView({Key? key, required this.sessionModel}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SiteInformationView> createState() => _SiteInformationViewState();
|
||||
}
|
||||
|
||||
class _SiteInformationViewState extends State<SiteInformationView> {
|
||||
AssetInventoryModel assetInventoryModel = AssetInventoryModel();
|
||||
bool showMarkAsComplete = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: DefaultAppBar(
|
||||
title: 'Inventory Session Request'.addTranslation,
|
||||
titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
children: [
|
||||
ListView(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
|
||||
children: [
|
||||
siteInfoCard(context, widget.sessionModel),
|
||||
12.height,
|
||||
assetDetailList(),
|
||||
8.height,
|
||||
],
|
||||
).expanded,
|
||||
FooterActionButton.footerContainer(
|
||||
context: context,
|
||||
child: AppFilledButton(
|
||||
buttonColor: AppColor.primary10,
|
||||
label: 'Add Asset'.addTranslation,
|
||||
onPressed: () => _addAsset(),
|
||||
// buttonColor: AppColor.primary10,
|
||||
),
|
||||
),
|
||||
if (showMarkAsComplete)
|
||||
AppFilledButton(
|
||||
buttonColor: AppColor.green70,
|
||||
label: 'Mark as completed'.addTranslation,
|
||||
onPressed: () => _markAsCompleted(),
|
||||
// buttonColor: AppColor.primary10,
|
||||
).paddingOnly(start: 16, end: 16),
|
||||
// FooterActionButton.footerContainer(
|
||||
// context: context,
|
||||
// child: AppFilledButton(
|
||||
// buttonColor: AppColor.green70,
|
||||
// label: 'Mark as completed'.addTranslation,
|
||||
// onPressed: () => _markAsCompleted(),
|
||||
// // buttonColor: AppColor.primary10,
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
void _addAsset() async {
|
||||
if (await validateRequest()) {
|
||||
assetInventoryModel.sessionId = widget.sessionModel.id;
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (contxt) => AssetInventoryFormView(
|
||||
assetInventoryModel: assetInventoryModel,
|
||||
sessionTypeValue: widget.sessionModel.sessionTypeValue,
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
void _markAsCompleted() async {
|
||||
if (await validateRequest()) {
|
||||
assetInventoryModel.sessionId = widget.sessionModel.id;
|
||||
AssetInventoryProvider provider = Provider.of<AssetInventoryProvider>(context, listen: false);
|
||||
Map<String, dynamic> payload = {
|
||||
"sessionId": widget.sessionModel.id,
|
||||
"siteId": assetInventoryModel.site?.id,
|
||||
"buildingId": assetInventoryModel.building?.id,
|
||||
"floorId": assetInventoryModel.floor?.id,
|
||||
"departmentId": assetInventoryModel.department?.id,
|
||||
"roomId": assetInventoryModel.room?.id,
|
||||
};
|
||||
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
||||
await provider.markAsComplete(payload: payload).then((success) {
|
||||
Navigator.pop(context);
|
||||
log('success $success');
|
||||
if (success) {
|
||||
///TODO need to confirm need to call this or not ..
|
||||
// AllRequestsProvider allRequestsProvider = Provider.of<AllRequestsProvider>(context, listen: false);
|
||||
// allRequestsProvider.reset();
|
||||
// allRequestsProvider.getAllRequests(context, typeTransaction: 8);
|
||||
///Need to call push and remove until...
|
||||
Navigator.pop(context);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Widget assetDetailList() {
|
||||
return Consumer<AssetInventoryProvider>(
|
||||
builder: (context, provider, _) {
|
||||
if (provider.isLoading) {
|
||||
return SizedBox(height: 300.toScreenHeight, child: const CircularProgressIndicator(color: AppColor.primary10).center);
|
||||
}
|
||||
final assets = provider.siteFilterAssetList;
|
||||
return NotificationListener<ScrollNotification>(
|
||||
onNotification: (scrollInfo) {
|
||||
if (!provider.isNextPageLoading && provider.nextPage && scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
|
||||
getAssetFilteredList(loadMore: true);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return AssetDetailCardView(
|
||||
assetInventoryModel: assets[index],
|
||||
onDeletePress: () async {
|
||||
log('Delete icon press');
|
||||
await provider.deleteAssetISession(id: assets[index].id ?? 0).then((success) async {
|
||||
if (success) {
|
||||
await getAssetFilteredList();
|
||||
await provider.getAssetsInSession(
|
||||
sessionId: widget.sessionModel.id ?? 0,
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) => 12.height,
|
||||
itemCount: assets.length,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget siteInfoCard(BuildContext context, SessionModel sessionModel) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
12.height,
|
||||
SingleItemDropDownMenu<Site, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.site,
|
||||
initialValue: assetInventoryModel.site,
|
||||
showShadow: false,
|
||||
staticData: sessionModel.assetInventorySites,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
showAsBottomSheet: true,
|
||||
onSelect: (value) {
|
||||
assetInventoryModel.site = value;
|
||||
assetInventoryModel.building = null;
|
||||
assetInventoryModel.floor = null;
|
||||
assetInventoryModel.department = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Building, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.building,
|
||||
initialValue: assetInventoryModel.building,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetInventoryModel.site?.buildings?.isNotEmpty ?? false,
|
||||
staticData: assetInventoryModel.site?.buildings ?? [],
|
||||
onSelect: (value) {
|
||||
assetInventoryModel.building = value;
|
||||
assetInventoryModel.floor = null;
|
||||
assetInventoryModel.department = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Floor, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.floor,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
initialValue: assetInventoryModel.floor,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetInventoryModel.building?.floors?.isNotEmpty ?? false,
|
||||
staticData: assetInventoryModel.building?.floors ?? [],
|
||||
onSelect: (value) {
|
||||
assetInventoryModel.floor = value;
|
||||
assetInventoryModel.department = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Department, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.department,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
initialValue: assetInventoryModel.department,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetInventoryModel.floor?.departments?.isNotEmpty ?? false,
|
||||
staticData: assetInventoryModel.floor?.departments ?? [],
|
||||
onSelect: (value) {
|
||||
assetInventoryModel.department = value;
|
||||
assetInventoryModel.room = null;
|
||||
showMarkAsComplete = true;
|
||||
setState(() {});
|
||||
getAssetFilteredList();
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Rooms, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.room,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
initialValue: assetInventoryModel.room,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetInventoryModel.department?.rooms?.isNotEmpty ?? false,
|
||||
staticData: assetInventoryModel.department?.rooms ?? [],
|
||||
onSelect: (value) {
|
||||
assetInventoryModel.room = value;
|
||||
setState(() {});
|
||||
if (assetInventoryModel.room != null) {
|
||||
getAssetFilteredList();
|
||||
}
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
],
|
||||
).toShadowContainer(context);
|
||||
}
|
||||
|
||||
Future<bool> validateRequest() async {
|
||||
if (assetInventoryModel.site == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Site");
|
||||
return false;
|
||||
}
|
||||
if (assetInventoryModel.building == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Building");
|
||||
return false;
|
||||
}
|
||||
if (assetInventoryModel.floor == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Floor");
|
||||
return false;
|
||||
}
|
||||
if (assetInventoryModel.department == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Department");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> getAssetFilteredList({bool loadMore = false}) async {
|
||||
AssetInventoryProvider provider = Provider.of<AssetInventoryProvider>(context, listen: false);
|
||||
Map<String, dynamic> payload = {
|
||||
"sessionId": widget.sessionModel.id,
|
||||
"siteId": assetInventoryModel.site?.id,
|
||||
"buildingId": assetInventoryModel.building?.id,
|
||||
"floorId": assetInventoryModel.floor?.id,
|
||||
"departmentId": assetInventoryModel.department?.id,
|
||||
"roomId": assetInventoryModel.room?.id,
|
||||
};
|
||||
await provider.getInventoryDetailsByFilter(payload: payload, loadMore: loadMore);
|
||||
}
|
||||
}
|
||||
@ -1,257 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:provider/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/text_extensions.dart';
|
||||
import 'package:test_sa/extensions/widget_extensions.dart';
|
||||
import 'package:test_sa/models/device/asset.dart';
|
||||
import 'package:test_sa/models/new_models/building.dart';
|
||||
import 'package:test_sa/models/new_models/department.dart';
|
||||
import 'package:test_sa/models/new_models/floor.dart';
|
||||
import 'package:test_sa/models/new_models/room_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/pages/asset_detail_card_view.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_form_view.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
|
||||
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
|
||||
import 'package:test_sa/new_views/app_style/app_color.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_filled_button.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/providers/loading_list_notifier.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
|
||||
|
||||
import '../../../models/new_models/site.dart';
|
||||
|
||||
class PickSiteInformationView extends StatefulWidget {
|
||||
SessionModel sessionModel;
|
||||
|
||||
PickSiteInformationView({Key? key, required this.sessionModel}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<PickSiteInformationView> createState() => _PickSiteInformationViewState();
|
||||
}
|
||||
|
||||
class _PickSiteInformationViewState extends State<PickSiteInformationView> {
|
||||
// TODO need to use only one model AssetInventoryModel everywhere after completing flow .
|
||||
Asset assetLocation = Asset();
|
||||
|
||||
void _onSave() async {}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: DefaultAppBar(
|
||||
title: 'Inventory Session Request'.addTranslation,
|
||||
titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
ListView(
|
||||
padding: const EdgeInsets.only(left: 16, right: 16, top: 16),
|
||||
children: [
|
||||
siteInfoCard(context, widget.sessionModel),
|
||||
12.height,
|
||||
//TODO need to implement when api is working ...
|
||||
// assetDetailList(),
|
||||
// 12.height,
|
||||
AppFilledButton(
|
||||
label: "Add Asset".addTranslation,
|
||||
maxWidth: true,
|
||||
|
||||
|
||||
height: 70,
|
||||
textColor: AppColor.textColor(context),
|
||||
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
|
||||
icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)),
|
||||
showIcon: true,
|
||||
onPressed: _addAsset,
|
||||
),
|
||||
12.height,
|
||||
],
|
||||
).expanded,
|
||||
FooterActionButton.footerContainer(
|
||||
context: context,
|
||||
child: AppFilledButton(buttonColor: AppColor.primary10, label: context.translation.save, maxWidth: true, onPressed: _onSave),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
void _addAsset() {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (contxt) => AssetInventoryFormView(
|
||||
assetLocation: assetLocation,
|
||||
)));
|
||||
}
|
||||
|
||||
Future<void> getAssetList({bool reset = false}) async {
|
||||
AssetInventoryProvider assetInventoryProvider = Provider.of<AssetInventoryProvider>(context,listen: false);
|
||||
if (reset) {
|
||||
assetInventoryProvider.pageNo = 1;
|
||||
assetInventoryProvider.assetInventoryResponse = null;
|
||||
}
|
||||
await assetInventoryProvider.getAssetsInSession(
|
||||
sessionId: widget.sessionModel.id??0,
|
||||
);
|
||||
}
|
||||
|
||||
Widget assetDetailList() {
|
||||
return Consumer<AssetInventoryProvider>(
|
||||
builder: (context, provider,child) {
|
||||
return Consumer<AssetInventoryProvider>(
|
||||
builder: (context, provider, _) {
|
||||
if (provider.isLoading && provider.assetInventoryResponse == null) {
|
||||
//TODO need use existing loader if found..
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
final assets = provider.assetInventoryResponse?.assetList ?? [];
|
||||
if (assets.isEmpty) {
|
||||
return const Center(child: NoDataFound());
|
||||
}
|
||||
return LazyLoading(
|
||||
nextPage: provider.nextPage,
|
||||
onLazyLoad: () async {
|
||||
await getAssetList();
|
||||
},
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.all(16),
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) {
|
||||
return AssetDetailCardView(assetInventoryModel: assets[index]);
|
||||
},
|
||||
separatorBuilder: (context, index) => 12.height,
|
||||
itemCount: assets.length,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget siteInfoCard(BuildContext context, SessionModel sessionModel) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
12.height,
|
||||
SingleItemDropDownMenu<Site, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.site,
|
||||
initialValue: assetLocation.site,
|
||||
showShadow: false,
|
||||
staticData: sessionModel.assetInventorySites,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
showAsBottomSheet: true,
|
||||
onSelect: (value) {
|
||||
assetLocation.site = value;
|
||||
assetLocation.building = null;
|
||||
assetLocation.floor = null;
|
||||
assetLocation.department = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Building, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.building,
|
||||
initialValue: assetLocation.building,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetLocation.site?.buildings?.isNotEmpty ?? false,
|
||||
staticData: assetLocation.site?.buildings ?? [],
|
||||
onSelect: (value) {
|
||||
assetLocation.building = value;
|
||||
assetLocation.floor = null;
|
||||
assetLocation.department = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Floor, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.floor,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
initialValue: assetLocation.floor,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetLocation.building?.floors?.isNotEmpty ?? false,
|
||||
staticData: assetLocation.building?.floors ?? [],
|
||||
onSelect: (value) {
|
||||
assetLocation.floor = value;
|
||||
assetLocation.department = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Department, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.department,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
initialValue: assetLocation.department,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetLocation.floor?.departments?.isNotEmpty ?? false,
|
||||
staticData: assetLocation.floor?.departments ?? [],
|
||||
onSelect: (value) {
|
||||
assetLocation.department = value;
|
||||
assetLocation.room = null;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
SingleItemDropDownMenu<Rooms, NullableLoadingProvider>(
|
||||
context: context,
|
||||
title: context.translation.room,
|
||||
showShadow: false,
|
||||
showAsBottomSheet: true,
|
||||
initialValue: assetLocation.room,
|
||||
backgroundColor: AppColor.fieldBgColor(context),
|
||||
enabled: assetLocation.department?.rooms?.isNotEmpty ?? false,
|
||||
staticData: assetLocation.department?.rooms ?? [],
|
||||
onSelect: (value) {
|
||||
assetLocation.room = value;
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
8.height,
|
||||
],
|
||||
).toShadowContainer(context);
|
||||
}
|
||||
|
||||
Future<bool> validateRequest() async {
|
||||
if (assetLocation.site == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Site");
|
||||
return false;
|
||||
}
|
||||
if (assetLocation.building == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Building");
|
||||
return false;
|
||||
}
|
||||
if (assetLocation.floor == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Floor");
|
||||
return false;
|
||||
}
|
||||
if (assetLocation.department == null) {
|
||||
await Fluttertoast.showToast(msg: "Please Select Department");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,276 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:test_sa/controllers/api_routes/urls.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/text_extensions.dart';
|
||||
import 'package:test_sa/extensions/widget_extensions.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart';
|
||||
import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart';
|
||||
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
|
||||
import 'package:test_sa/views/widgets/equipment/asset_item_listview.dart';
|
||||
import 'package:test_sa/views/widgets/horizontal_list_widget.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
|
||||
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
|
||||
import '../../../models/device/asset.dart';
|
||||
import '../../../models/device/asset_search.dart';
|
||||
import '../../../new_views/app_style/app_color.dart';
|
||||
import '../../../new_views/common_widgets/app_lazy_loading.dart';
|
||||
import '../../../new_views/common_widgets/custom_app_bar.dart';
|
||||
|
||||
class SearchAssetView extends StatefulWidget {
|
||||
static const String id = "asset_search_view";
|
||||
final num sessionId;
|
||||
|
||||
const SearchAssetView({Key? key, required this.sessionId}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<SearchAssetView> createState() => _SearchAssetViewState();
|
||||
}
|
||||
|
||||
class _SearchAssetViewState extends State<SearchAssetView> {
|
||||
int _selectedIndex = 0;
|
||||
DeviceSearch? search;
|
||||
late TextEditingController _searchController;
|
||||
late AssetInventoryProvider _assetInventoryProvider;
|
||||
final List<AssetInventoryModel> _searchableList = [];
|
||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
bool _isFirst = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_searchController = TextEditingController();
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_searchController.dispose();
|
||||
_assetInventoryProvider.searchReset();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<String> searchBy = [
|
||||
context.translation.assetName,
|
||||
context.translation.model,
|
||||
context.translation.manufacture,
|
||||
context.translation.snNumber,
|
||||
context.translation.siteName,
|
||||
// 'Building Name'.addTranslation,
|
||||
// 'Floor Name'.addTranslation,
|
||||
'Department Name'.addTranslation,
|
||||
|
||||
///need to check if want to add more filters
|
||||
];
|
||||
|
||||
_assetInventoryProvider = Provider.of<AssetInventoryProvider>(context, listen: false);
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: CustomAppBar(
|
||||
title: context.translation.searchAsset,
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
HorizontalListWidget(
|
||||
list: searchBy,
|
||||
callBackFunction: (index) {
|
||||
setState(() {
|
||||
_selectedIndex = index;
|
||||
});
|
||||
},
|
||||
).paddingOnly(top: 16, bottom: 0),
|
||||
Form(
|
||||
key: _formKey,
|
||||
child: AppTextFormField(
|
||||
controller: _searchController,
|
||||
textInputAction: TextInputAction.search,
|
||||
labelText: "${context.translation.searchBy} ${searchBy[_selectedIndex]}",
|
||||
onAction: _search,
|
||||
onChange: (text) {
|
||||
_searchController.text = text;
|
||||
_searchController.selection = TextSelection.fromPosition(TextPosition(offset: _searchController.text.length));
|
||||
setState(() {});
|
||||
},
|
||||
onSaved: (value) {
|
||||
setState(() {
|
||||
search = DeviceSearch();
|
||||
});
|
||||
_setValue(value);
|
||||
},
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.search),
|
||||
splashColor: Colors.transparent,
|
||||
onPressed: _searchController.text.isNotEmpty ? _search : null,
|
||||
color: AppColor.neutral20,
|
||||
).paddingOnly(end: 0),
|
||||
).paddingOnly(top: 16, start: 16, end: 16, bottom: 8),
|
||||
),
|
||||
Expanded(
|
||||
child: _searchableList.isEmpty
|
||||
? _isFirst
|
||||
? const SizedBox()
|
||||
: NoDataFound(message: context.translation.noDeviceFound)
|
||||
: LazyLoading(
|
||||
nextPage: _assetInventoryProvider.nextPage,
|
||||
onLazyLoad: () async {
|
||||
if (_searchController.text.isNotEmpty) {
|
||||
await _assetInventoryProvider.getAssets(search: search, isSearchBy: true, sessionId: widget.sessionId);
|
||||
setState(() {
|
||||
_searchableList.clear();
|
||||
_searchableList.addAll(_assetInventoryProvider.searchDevices);
|
||||
});
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
ListView.separated(
|
||||
itemCount: _searchableList.length,
|
||||
separatorBuilder: (listContext, itemIndex) => 8.height,
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemBuilder: (listContext, itemIndex) {
|
||||
// bool isSelected = selectedAssets.contains(_searchableList[itemIndex].id!);
|
||||
// String title = isSelected ? "UnSelect" : "Select";
|
||||
return InventoryAssetItemListView(
|
||||
device: _searchableList[itemIndex],
|
||||
// isSelected: isSelected,
|
||||
onPressed: (device) {
|
||||
// Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(device);
|
||||
},
|
||||
// selectButton: Text(title, style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context))),
|
||||
);
|
||||
},
|
||||
).expanded,
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
|
||||
void _search() async {
|
||||
FocusScope.of(context).unfocus();
|
||||
_formKey.currentState!.save();
|
||||
_assetInventoryProvider.searchReset();
|
||||
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
|
||||
await _assetInventoryProvider.getAssets(search: search, isSearchBy: true, sessionId: widget.sessionId);
|
||||
setState(() {
|
||||
_searchableList.clear();
|
||||
_searchableList.addAll(_assetInventoryProvider.searchDevices);
|
||||
_isFirst = false;
|
||||
});
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
_setValue(value) {
|
||||
/// todo : check oracle code (no matched parameter)
|
||||
/// //ontext.translation.assetName,
|
||||
// context.translation.model,
|
||||
// context.translation.manufacture,
|
||||
// context.translation.snNumber,
|
||||
// context.translation.siteName,
|
||||
// // 'Building Name'.addTranslation,
|
||||
// // 'Floor Name'.addTranslation,
|
||||
// 'Department Name'.addTranslation,
|
||||
switch (_selectedIndex) {
|
||||
case 0:
|
||||
search!.assetName = value;
|
||||
break;
|
||||
case 1:
|
||||
search!.model = value;
|
||||
break;
|
||||
case 2:
|
||||
search!.manufacturer = value;
|
||||
break;
|
||||
case 3:
|
||||
search!.assetSerialNumber = value;
|
||||
break;
|
||||
case 4:
|
||||
search!.site = value;
|
||||
break;
|
||||
case 5:
|
||||
search!.department = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// bool _showResetButton() {
|
||||
// return (_searchController?.text?.isNotEmpty ?? false);
|
||||
// }
|
||||
}
|
||||
|
||||
class InventoryAssetItemListView extends StatelessWidget {
|
||||
final AssetInventoryModel device;
|
||||
final Function(AssetInventoryModel) onPressed;
|
||||
final Widget? selectButton;
|
||||
final bool isSelected;
|
||||
|
||||
const InventoryAssetItemListView({Key? key, required this.device, required this.onPressed, this.selectButton, this.isSelected = false}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 95,
|
||||
height: 95,
|
||||
decoration: ShapeDecoration(
|
||||
color: context.isDark ? AppColor.neutral50 : AppColor.neutral30,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: NetworkImage(device.photo != null ? URLs.getFileUrl(device.photo!)! : "https://www.lasteelcraft.com/images/no-image-available.png"),
|
||||
)),
|
||||
),
|
||||
15.width,
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
device.assetName!.cleanupWhitespace.capitalizeFirstOfEach.heading6(context),
|
||||
8.height,
|
||||
"${context.translation.assetNumber} : ${device.assetNumber}".bodyText(context),
|
||||
"${context.translation.modelName} : ${device.model}".cleanupWhitespace.capitalizeFirstOfEach.bodyText(context),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
"${context.translation.serialNo} : ${device.serialNo}".bodyText(context).expanded,
|
||||
4.width,
|
||||
selectButton ??
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
context.translation.viewDetails,
|
||||
style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)),
|
||||
),
|
||||
4.width,
|
||||
Icon(
|
||||
Icons.arrow_forward,
|
||||
color: AppColor.blueStatus(context),
|
||||
size: 14,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
).expanded
|
||||
],
|
||||
).toShadowContainer(context, padding: 12, borderColor: isSelected ? AppColor.blueStatus(context) : Colors.transparent).onPress(() => onPressed(device));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue