asset images upload for ai training.

ui_ux_rollout_merge
Sikander Saleem 3 weeks ago
parent 38f5f506e6
commit ace00bfa85

@ -275,10 +275,9 @@ class ApiManager {
} }
Future<http.Response> multiPart(String url, {Map<String, String>? headers, required Map<String, String> body, required List<Future<MultipartFile>> files}) async { Future<http.Response> multiPart(String url, {Map<String, String>? headers, required Map<String, String> body, required List<Future<MultipartFile>> files}) async {
Map<String, String> headers0 = const { Map<String, String> headers0 = _headers;
'Content-Type': 'multipart/form-data',
};
headers0["Content-Type"] = 'multipart/form-data';
headers ??= {}; headers ??= {};
headers.addAll(headers0); headers.addAll(headers0);

@ -3,13 +3,13 @@ class URLs {
static const String appReleaseBuildNumber = "44"; static const String appReleaseBuildNumber = "44";
static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsm.hmg.com"; // production url
// static const host1 = "https://atomsmdev.hmg.com"; // local DEV url // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
// static const host1 = "https://atomsmuat.hmg.com"; // local UAT url static const host1 = "https://atomsmuat.hmg.com"; // local UAT url
// static final String _baseUrl = "$_host/mobile"; // host local UAT static final String _baseUrl = "$_host/mobile"; // host local UAT
// static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis
static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM
// static final String _baseUrl = "$_host/v4/mobile"; // v4 for Demo module // static final String _baseUrl = "$_host/v4/mobile"; // v4 for Demo module
// static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation // static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation
// static final String _baseUrl = "$_host/v6/mobile"; // for asset delivery module // static final String _baseUrl = "$_host/v6/mobile"; // for asset delivery module
@ -65,6 +65,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 saveAssetImages => "$_baseUrl/Asset/SaveAssetImages"; // get
static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2
static get getAllRequestsAndCount => "$_baseUrl/CallRequest/GetAllRequestsAndCount"; // get static get getAllRequestsAndCount => "$_baseUrl/CallRequest/GetAllRequestsAndCount"; // get
static get updateUserContactInformation => "$_baseUrl/Account/UpdateContactInfo"; // get static get updateUserContactInformation => "$_baseUrl/Account/UpdateContactInfo"; // get

@ -9,6 +9,7 @@ import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/asset_by_id_model.dart'; import 'package:test_sa/models/device/asset_by_id_model.dart';
import 'package:test_sa/models/device/asset_search.dart'; import 'package:test_sa/models/device/asset_search.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import 'package:test_sa/modules/asset_delivery_module/models/technical_inpection_asset_model.dart'; import 'package:test_sa/modules/asset_delivery_module/models/technical_inpection_asset_model.dart';
@ -230,4 +231,22 @@ class AssetProvider extends ChangeNotifier {
return []; return [];
} }
} }
Future<bool> uploadAssetImages(int assetId, List<GenericAttachmentModel> attachments) async {
late Response response;
try {
response =
await ApiManager.instance.multiPart(URLs.saveAssetImages + "?AssetId=$assetId", body: {}, files: attachments.map((attachment) => MultipartFile.fromPath("Files", attachment.name!)).toList());
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
// Map<String, dynamic> assetData = json.decode(response.body)["data"];
// _assetById = AssetByIdModel.fromJson(assetData);
// return _assetById!;
return true;
}
return false;
} catch (error) {
return false;
}
}
} }

@ -8,7 +8,13 @@ import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/asset_by_id_model.dart'; import 'package:test_sa/models/device/asset_by_id_model.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.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/default_app_bar.dart';
import 'package:test_sa/views/widgets/equipment/asset_image_upload_page.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.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/failed_loading.dart'; import 'package:test_sa/views/widgets/loaders/failed_loading.dart';
@ -39,6 +45,9 @@ class _AssetDetailPageState extends State<AssetDetailPage> {
int? assetId; int? assetId;
AssetProvider? _assetProvider; AssetProvider? _assetProvider;
AssetByIdModel? assetModel;
List<GenericAttachmentModel> attachments = [];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -48,7 +57,7 @@ class _AssetDetailPageState extends State<AssetDetailPage> {
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.assetDetails), appBar: DefaultAppBar(title: context.translation.assetDetails),
body: FutureBuilder<AssetByIdModel>( body: FutureBuilder<AssetByIdModel>(
future: _assetProvider!.getAssetById(assetId!, context.translation), future: assetModel == null ? _assetProvider!.getAssetById(assetId!, context.translation) : null,
builder: (BuildContext context, AsyncSnapshot<AssetByIdModel> snapshot) { builder: (BuildContext context, AsyncSnapshot<AssetByIdModel> snapshot) {
if (snapshot.hasError) { if (snapshot.hasError) {
return FailedLoading( return FailedLoading(
@ -62,87 +71,108 @@ class _AssetDetailPageState extends State<AssetDetailPage> {
return const Center(child: ALoading()); return const Center(child: ALoading());
} else if (snapshot.hasData) {} } else if (snapshot.hasData) {}
if (snapshot.hasData) { if (snapshot.hasData) {
AssetByIdModel assetModel = snapshot.data!; assetModel = snapshot.data!;
return SingleChildScrollView( attachments = assetModel?.assetAttachments
padding: const EdgeInsets.all(16), ?.map((attachment) => GenericAttachmentModel(
child: Column( id: attachment.id,
crossAxisAlignment: CrossAxisAlignment.start, name: attachment.attachmentName,
children: [ originalName: attachment.originalName,
AspectRatio( ))
aspectRatio: 159 / 94, .toList() ??
child: Container( [];
width: 95, return Column(
height: 95, children: [
decoration: ShapeDecoration( ListView(padding: const EdgeInsets.all(16), children: [
color: AppColor.neutral30,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(assetModel.assetPhoto != null ? URLs.getFileUrl(assetModel.assetPhoto!)! : "https://www.lasteelcraft.com/images/no-image-available.png"),
)),
),
),
6.height,
Column( Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (assetModel.commissioningStatus != null) AspectRatio(
StatusLabel( aspectRatio: 159 / 94,
label: assetModel.commissioningStatus!.name, child: Container(
textColor: AppColor.getRequestStatusTextColorByName(context, assetModel.commissioningStatus!.name!), width: 95,
backgroundColor: AppColor.getRequestStatusColorByName(context, assetModel.commissioningStatus!.name!), height: 95,
decoration: ShapeDecoration(
color: AppColor.neutral30,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(assetModel?.assetPhoto != null ? URLs.getFileUrl(assetModel!.assetPhoto!)! : "https://www.lasteelcraft.com/images/no-image-available.png"),
)),
), ),
if (assetModel.commissioningStatus != null) 8.height, ),
(assetModel.modelDefinition?.assetName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-").heading5(context), 6.height,
8.height, Column(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Column( if (assetModel?.commissioningStatus != null)
crossAxisAlignment: CrossAxisAlignment.start, StatusLabel(
children: [ label: assetModel!.commissioningStatus!.name,
"${context.translation.assetNo}: ${assetModel.multiAssets!.first.assetNumber}".bodyText(context), textColor: AppColor.getRequestStatusTextColorByName(context, assetModel!.commissioningStatus!.name!),
"${context.translation.modelName}: ${assetModel.modelDefinition!.modelName}".bodyText(context), backgroundColor: AppColor.getRequestStatusColorByName(context, assetModel!.commissioningStatus!.name!),
"${context.translation.supplier}: ${assetModel.supplier?.suppliername ?? "-"}".bodyText(context), ),
"${context.translation.manufacture}: ${assetModel.modelDefinition!.manufacturerName}".bodyText(context), if (assetModel?.commissioningStatus != null) 8.height,
//"${context.translation.location}: ${assetModel.site.custName?.cleanupWhitespace?.capitalizeFirstOfEach}".bodyText(context), (assetModel?.modelDefinition?.assetName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-").heading5(context),
], 8.height,
).expanded, Row(
8.width,
Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
/// TODO: theres no [ORACLE CODE] available to preview Column(
// "${context.translation.oracleCode}: ${"-"}".bodyText(context), crossAxisAlignment: CrossAxisAlignment.start,
"${context.translation.snNo}: ${assetModel.multiAssets!.first.assetSerialNo}".bodyText(context), children: [
"${context.translation.site}: ${assetModel.site?.custName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), "${context.translation.assetNo}: ${assetModel!.multiAssets!.first.assetNumber}".bodyText(context),
"${context.translation.building}: ${assetModel.building?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), "${context.translation.modelName}: ${assetModel!.modelDefinition!.modelName}".bodyText(context),
"${context.translation.floor}: ${assetModel.floor?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), "${context.translation.supplier}: ${assetModel!.supplier?.suppliername ?? "-"}".bodyText(context),
"${context.translation.md}: ${assetModel.department?.departmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), "${context.translation.manufacture}: ${assetModel!.modelDefinition!.manufacturerName}".bodyText(context),
"${context.translation.room}: ${assetModel.room?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context), //"${context.translation.location}: ${assetModel.site.custName?.cleanupWhitespace?.capitalizeFirstOfEach}".bodyText(context),
],
).expanded,
8.width,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// TODO: theres no [ORACLE CODE] available to preview
// "${context.translation.oracleCode}: ${"-"}".bodyText(context),
"${context.translation.snNo}: ${assetModel!.multiAssets!.first.assetSerialNo}".bodyText(context),
"${context.translation.site}: ${assetModel!.site?.custName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.building}: ${assetModel!.building?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.floor}: ${assetModel!.floor?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.md}: ${assetModel!.department?.departmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.room}: ${assetModel!.room?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
],
).expanded,
], ],
).expanded, ),
8.height,
const Divider(color: AppColor.neutral30, height: 1, thickness: 1),
8.height,
"${context.translation.installationDate}: ${assetModel!.installationDate?.toAssetDetailsFormat ?? "-"}".bodyText(context),
"${context.translation.nextPmDate}: ${assetModel!.nextPMDate?.toAssetDetailsFormat ?? "-"}".bodyText(context),
"${context.translation.lastPmDate}: ${assetModel!.lastPMDate?.toAssetDetailsFormat ?? "-"}".bodyText(context),
if ((assetModel?.modelDefinition?.assetDescription ?? "").isNotEmpty) ...[
8.height,
const Divider(color: AppColor.neutral30, height: 1, thickness: 1),
8.height,
assetModel!.modelDefinition!.assetDescription!.bodyText(context),
],
FilesList(images: attachments.map((toElement) => URLs.getFileUrl(toElement.name!) ?? '').toList()),
], ],
), )
8.height,
const Divider(color: AppColor.neutral30, height: 1, thickness: 1),
8.height,
"${context.translation.installationDate}: ${assetModel.installationDate?.toAssetDetailsFormat ?? "-"}".bodyText(context),
"${context.translation.nextPmDate}: ${assetModel.nextPMDate?.toAssetDetailsFormat ?? "-"}".bodyText(context),
"${context.translation.lastPmDate}: ${assetModel.lastPMDate?.toAssetDetailsFormat ?? "-"}".bodyText(context),
if ((assetModel.modelDefinition?.assetDescription ?? "").isNotEmpty) ...[
8.height,
const Divider(color: AppColor.neutral30, height: 1, thickness: 1),
8.height,
assetModel.modelDefinition!.assetDescription!.bodyText(context),
]
], ],
) ).toShadowContainer(context),
], ]).expanded,
).toShadowContainer(context), if (context.userProvider.isEngineer)
FooterActionButton.footerContainer(
context: context,
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: "Upload Images",
onPressed: _upload,
),
),
],
); );
} }
return const Center(child: ALoading()); return const Center(child: ALoading());
@ -150,4 +180,25 @@ class _AssetDetailPageState extends State<AssetDetailPage> {
), ),
); );
} }
void _upload() async {
bool reload = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AssetImageUploadPage(
assetId: assetId!,
attachments: assetModel?.assetAttachments
?.map((attachment) => GenericAttachmentModel(
id: attachment.id,
name: attachment.attachmentName,
originalName: attachment.originalName,
))
.toList() ??
[]))) ??
false;
if (reload) {
assetModel = null;
setState(() {});
}
}
} }

@ -0,0 +1,81 @@
import 'package:flutter/material.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/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/helper/utils.dart';
import 'package:test_sa/models/generic_attachment_model.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/views/widgets/images/multi_image_picker.dart';
class AssetImageUploadPage extends StatefulWidget {
int assetId;
List<GenericAttachmentModel> attachments;
AssetImageUploadPage({Key? key, required this.assetId, required this.attachments}) : super(key: key);
@override
_AssetImageUploadPageState createState() {
return _AssetImageUploadPageState();
}
}
class _AssetImageUploadPageState extends State<AssetImageUploadPage> {
List<GenericAttachmentModel> attachments = [];
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: const DefaultAppBar(title: "Upload"),
body: Column(
children: [
ListView(
padding: const EdgeInsets.all(16),
children: [
AttachmentPicker(
label: "Upload Images",
attachment: attachments,
buttonColor: AppColor.black10,
onlyImages: true,
showAsListView: true,
buttonIcon: 'image-plus'.toSvgAsset(color: context.isDark ? AppColor.primary10 : AppColor.neutral120),
onChange: (_attachments) {
attachments = _attachments;
setState(() {});
},
).toShadowContainer(context),
],
).expanded,
FooterActionButton.footerContainer(
context: context,
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: "Upload Images",
onPressed: () async {
Utils.showUploadingDialog(context);
bool result = await Provider.of<AssetProvider>(context, listen: false).uploadAssetImages(widget.assetId, attachments);
Utils.hideLoading(context);
if (result) {
Navigator.pop(context, result);
}
},
),
),
],
));
}
}

@ -348,7 +348,7 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,spacing: 12,
children: [ children: [
AppDashedButton( AppDashedButton(
title: widget.label, title: widget.label,
@ -360,13 +360,12 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
: widget.showAsGrid : widget.showAsGrid
? showFileSourceSheet ? showFileSourceSheet
: onFilePicker), : onFilePicker),
16.height,
if (widget.attachment.isNotEmpty) if (widget.attachment.isNotEmpty)
widget.showAsListView widget.showAsListView
? ListView.separated( ? ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero, padding: const EdgeInsets.only(top: 0),
itemBuilder: (cxt, index) { itemBuilder: (cxt, index) {
File image = File(widget.attachment[index].name!); File image = File(widget.attachment[index].name!);
return MultiFilesPickerItem( return MultiFilesPickerItem(
@ -410,7 +409,7 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
); );
}, },
), ),
), ).paddingOnly(top: 0),
], ],
); );
} }

Loading…
Cancel
Save