|
|
|
|
@ -4,6 +4,7 @@ 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/site.dart';
|
|
|
|
|
import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart';
|
|
|
|
|
import 'package:test_sa/new_views/app_style/app_color.dart';
|
|
|
|
|
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
|
|
|
|
|
@ -48,12 +49,15 @@ class _AssetInventoryDetailViewState extends State<AssetInventoryDetailView> {
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
|
children: [
|
|
|
|
|
//
|
|
|
|
|
StatusLabel(
|
|
|
|
|
label: sessionModel.statusName,
|
|
|
|
|
id: sessionModel.statusId,
|
|
|
|
|
radius: 4,
|
|
|
|
|
textColor: AppColor.green15,
|
|
|
|
|
backgroundColor: AppColor.greenStatus(context),
|
|
|
|
|
textColor: AppColor.getRequestStatusTextColorByName(context, sessionModel.statusName),
|
|
|
|
|
backgroundColor: AppColor.getRequestStatusColorByName(context, sessionModel.statusName),
|
|
|
|
|
// textColor: AppColor.green15,
|
|
|
|
|
// backgroundColor: AppColor.greenStatus(context),
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
sessionModel.createdDate!.toString().toServiceRequestCardFormat,
|
|
|
|
|
@ -64,7 +68,7 @@ class _AssetInventoryDetailViewState extends State<AssetInventoryDetailView> {
|
|
|
|
|
),
|
|
|
|
|
8.height,
|
|
|
|
|
Text(
|
|
|
|
|
context.translation.requestDetails,
|
|
|
|
|
'Session Details'.addTranslation,
|
|
|
|
|
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
|
|
|
|
|
),
|
|
|
|
|
8.height,
|
|
|
|
|
@ -100,64 +104,139 @@ class _AssetInventoryDetailViewState extends State<AssetInventoryDetailView> {
|
|
|
|
|
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
|
|
|
|
|
),
|
|
|
|
|
8.height,
|
|
|
|
|
ListView.separated(
|
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
padding: EdgeInsets.zero,
|
|
|
|
|
itemCount: sites.length,
|
|
|
|
|
itemBuilder: (cxt, siteIndex) {
|
|
|
|
|
final site = sites[siteIndex];
|
|
|
|
|
final buildingNames = (site.buildings ?? []).map((b) => b.name).where((name) => name != null && name!.trim().isNotEmpty).join(', ');
|
|
|
|
|
final floorNames = (site.buildings ?? []).expand((b) => b.floors ?? []).map((f) => f.name).where((name) => name != null && name!.trim().isNotEmpty).join(', ');
|
|
|
|
|
final departmentNames =
|
|
|
|
|
(site.buildings ?? []).expand((b) => b.floors ?? []).expand((f) => f.departments ?? []).map((d) => d.name).where((name) => name != null && name!.trim().isNotEmpty).join(', ');
|
|
|
|
|
final roomNames = (site.buildings ?? [])
|
|
|
|
|
.expand((b) => b.floors ?? [])
|
|
|
|
|
.expand((f) => f.departments ?? [])
|
|
|
|
|
.expand((d) => d.rooms ?? [])
|
|
|
|
|
.map((r) => r.name)
|
|
|
|
|
.where((name) => name != null && name!.trim().isNotEmpty)
|
|
|
|
|
.join(', ');
|
|
|
|
|
|
|
|
|
|
return Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
SiteHierarchyView(
|
|
|
|
|
sites: sites,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
).toShadowContainer(context, padding: 12, borderRadius: 20);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SiteHierarchyView extends StatelessWidget {
|
|
|
|
|
final List<Site> sites;
|
|
|
|
|
|
|
|
|
|
const SiteHierarchyView({super.key, required this.sites});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return ListView.builder(
|
|
|
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
itemCount: sites.length,
|
|
|
|
|
itemBuilder: (context, index) {
|
|
|
|
|
final site = sites[index];
|
|
|
|
|
return HierarchyTile(
|
|
|
|
|
title: site.name ?? '-',
|
|
|
|
|
children: (site.buildings ?? [])
|
|
|
|
|
.map((b) => HierarchyTile(
|
|
|
|
|
title: b.name ?? '-',
|
|
|
|
|
children: (b.floors ?? [])
|
|
|
|
|
.map((f) => HierarchyTile(
|
|
|
|
|
title: f.name ?? '-',
|
|
|
|
|
children: (f.departments ?? [])
|
|
|
|
|
.map((d) => HierarchyTile(
|
|
|
|
|
title: d.name ?? '-',
|
|
|
|
|
children: (d.rooms ?? [])
|
|
|
|
|
.map((r) => LeafTile(title: r.name ?? '-'))
|
|
|
|
|
.toList(),
|
|
|
|
|
))
|
|
|
|
|
.toList(),
|
|
|
|
|
))
|
|
|
|
|
.toList(),
|
|
|
|
|
))
|
|
|
|
|
.toList(),
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
class HierarchyTile extends StatefulWidget {
|
|
|
|
|
final String title;
|
|
|
|
|
final List<Widget> children;
|
|
|
|
|
final double indent;
|
|
|
|
|
|
|
|
|
|
const HierarchyTile({
|
|
|
|
|
super.key,
|
|
|
|
|
required this.title,
|
|
|
|
|
this.children = const [],
|
|
|
|
|
this.indent = 0,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
State<HierarchyTile> createState() => _HierarchyTileState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _HierarchyTileState extends State<HierarchyTile> {
|
|
|
|
|
bool expanded = false;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
final hasChildren = widget.children.isNotEmpty;
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: EdgeInsets.only(left: widget.indent,top: 10.toScreenHeight),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
GestureDetector(
|
|
|
|
|
behavior: HitTestBehavior.opaque,
|
|
|
|
|
onTap: hasChildren ? () => setState(() => expanded = !expanded) : null,
|
|
|
|
|
child: Row(
|
|
|
|
|
children: [
|
|
|
|
|
if (hasChildren)
|
|
|
|
|
// expanded? 'expended_arrow_icon'.toSvgAsset(color: AppColor.neutral50,width: 8,height:13): 'collesped_arrow_icon'.toSvgAsset(color: AppColor.neutral50,width: 8,height:13)
|
|
|
|
|
Icon(
|
|
|
|
|
expanded ? Icons.expand_more : Icons.chevron_right,
|
|
|
|
|
size: 25.toScreenHeight,
|
|
|
|
|
color: AppColor.neutral50,
|
|
|
|
|
)
|
|
|
|
|
else
|
|
|
|
|
SizedBox(width: 18.toScreenWidth),
|
|
|
|
|
SizedBox(width: 15.toScreenWidth),
|
|
|
|
|
Text(
|
|
|
|
|
site.name ?? '-',
|
|
|
|
|
style: AppTextStyles.heading6.copyWith(
|
|
|
|
|
color: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
'${context.translation.building}: ${buildingNames.isNotEmpty ? buildingNames : '-'}',
|
|
|
|
|
style: AppTextStyles.bodyText.copyWith(
|
|
|
|
|
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
'${context.translation.floor}: ${floorNames.isNotEmpty ? floorNames : '-'}',
|
|
|
|
|
style: AppTextStyles.bodyText.copyWith(
|
|
|
|
|
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
'${context.translation.department}: ${departmentNames.isNotEmpty ? departmentNames : '-'}',
|
|
|
|
|
style: AppTextStyles.bodyText.copyWith(
|
|
|
|
|
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Text(
|
|
|
|
|
'${context.translation.room}: ${roomNames.isNotEmpty ? roomNames : '-'}',
|
|
|
|
|
style: AppTextStyles.bodyText.copyWith(
|
|
|
|
|
color: context.isDark ? AppColor.neutral10 : AppColor.neutral120,
|
|
|
|
|
),
|
|
|
|
|
widget.title,
|
|
|
|
|
style:AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
separatorBuilder: (cxt, index) => const Divider().defaultStyle(context),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
).toShadowContainer(context, padding: 12, borderRadius: 20);
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
if (expanded)
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 20, top: 6),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: widget.children
|
|
|
|
|
.map((child) => child is HierarchyTile
|
|
|
|
|
? HierarchyTile(
|
|
|
|
|
title: (child).title,
|
|
|
|
|
indent: 0,
|
|
|
|
|
children: (child).children,
|
|
|
|
|
)
|
|
|
|
|
: child)
|
|
|
|
|
.toList(),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
class LeafTile extends StatelessWidget {
|
|
|
|
|
final String title;
|
|
|
|
|
|
|
|
|
|
const LeafTile({super.key, required this.title});
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.only(left: 22, top: 4, bottom: 4),
|
|
|
|
|
child: Text(
|
|
|
|
|
title,
|
|
|
|
|
style: const TextStyle(fontSize: 13, color: Colors.black87),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|