mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-08-25 07:22:27 +00:00
Bugfix/assign tags to devices table overflow (#364)
<!-- Thanks for contributing! Provide a description of your changes below and a general summary in the title Please look at the following checklist to ensure that your PR can be accepted quickly: --> ## Description Fixed overflow in assign tags to devices table. ## Type of Change <!--- Put an `x` in all the boxes that apply: --> - [ ] ✨ New feature (non-breaking change which adds functionality) - [x] 🛠️ Bug fix (non-breaking change which fixes an issue) - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) - [ ] 🧹 Code refactor - [ ] ✅ Build configuration change - [ ] 📝 Documentation - [ ] 🗑️ Chore
This commit is contained in:
@ -31,173 +31,178 @@ class AssignTagsTable extends StatelessWidget {
|
|||||||
|
|
||||||
DataColumn _buildDataColumn(BuildContext context, String label) {
|
DataColumn _buildDataColumn(BuildContext context, String label) {
|
||||||
return DataColumn(
|
return DataColumn(
|
||||||
label: SelectableText(label, style: context.textTheme.bodyMedium),
|
label: Expanded(
|
||||||
|
child: FittedBox(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: SelectableText(label, style: context.textTheme.bodyMedium),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocProvider<TagsBloc>(
|
return BlocProvider<TagsBloc>(
|
||||||
create: (BuildContext context) => TagsBloc(
|
create: (context) => TagsBloc(
|
||||||
RemoteTagsService(HTTPService()),
|
RemoteTagsService(HTTPService()),
|
||||||
)..add(const LoadTags()),
|
)..add(const LoadTags()),
|
||||||
child: BlocBuilder<TagsBloc, TagsState>(
|
child: BlocBuilder<TagsBloc, TagsState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) => switch (state) {
|
||||||
return switch (state) {
|
TagsLoading() || TagsInitial() => const Center(
|
||||||
TagsLoading() || TagsInitial() => const Center(
|
child: CircularProgressIndicator(),
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
),
|
TagsFailure(:final message) => Center(
|
||||||
TagsFailure(:final message) => Center(
|
child: Text(message),
|
||||||
child: Text(message),
|
),
|
||||||
),
|
TagsLoaded(:final tags) => ClipRRect(
|
||||||
TagsLoaded(:final tags) => ClipRRect(
|
borderRadius: BorderRadius.circular(20),
|
||||||
borderRadius: BorderRadius.circular(20),
|
child: DataTable(
|
||||||
child: DataTable(
|
headingRowColor: WidgetStateProperty.all(
|
||||||
headingRowColor: WidgetStateProperty.all(
|
ColorsManager.dataHeaderGrey,
|
||||||
ColorsManager.dataHeaderGrey,
|
|
||||||
),
|
|
||||||
key: ValueKey(productAllocations.length),
|
|
||||||
border: TableBorder.all(
|
|
||||||
color: ColorsManager.dataHeaderGrey,
|
|
||||||
width: 1,
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
|
||||||
columns: [
|
|
||||||
_buildDataColumn(context, '#'),
|
|
||||||
_buildDataColumn(context, 'Device'),
|
|
||||||
_buildDataColumn(context, 'Tag'),
|
|
||||||
_buildDataColumn(context, 'Location'),
|
|
||||||
],
|
|
||||||
rows: productAllocations.isEmpty
|
|
||||||
? [
|
|
||||||
DataRow(
|
|
||||||
cells: [
|
|
||||||
DataCell(
|
|
||||||
Center(
|
|
||||||
child: SelectableText(
|
|
||||||
'No Devices Available',
|
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
|
||||||
color: ColorsManager.lightGrayColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
DataCell.empty,
|
|
||||||
DataCell.empty,
|
|
||||||
DataCell.empty,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
: List.generate(productAllocations.length, (index) {
|
|
||||||
final productAllocation = productAllocations[index];
|
|
||||||
final allocationUuid = productAllocation.uuid;
|
|
||||||
|
|
||||||
final availableTags = tags
|
|
||||||
.where(
|
|
||||||
(tag) =>
|
|
||||||
!productAllocations
|
|
||||||
.where((p) =>
|
|
||||||
p.product.productType ==
|
|
||||||
productAllocation.product.productType)
|
|
||||||
.map((p) => p.tag.name.toLowerCase())
|
|
||||||
.contains(tag.name.toLowerCase()) ||
|
|
||||||
tag.uuid == productAllocation.tag.uuid,
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
final currentLocationUuid =
|
|
||||||
productLocations[allocationUuid];
|
|
||||||
final currentLocationName = currentLocationUuid == null
|
|
||||||
? 'Main Space'
|
|
||||||
: subspaces
|
|
||||||
.firstWhere((s) => s.uuid == currentLocationUuid)
|
|
||||||
.name;
|
|
||||||
|
|
||||||
return DataRow(
|
|
||||||
key: ValueKey(allocationUuid),
|
|
||||||
cells: [
|
|
||||||
DataCell(Text((index + 1).toString())),
|
|
||||||
DataCell(
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
productAllocation.product.name,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
)),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Container(
|
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(
|
|
||||||
color: ColorsManager.lightGrayColor,
|
|
||||||
width: 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: IconButton(
|
|
||||||
icon: const Icon(
|
|
||||||
Icons.close,
|
|
||||||
color: ColorsManager.lightGreyColor,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
onProductDeleted(allocationUuid);
|
|
||||||
},
|
|
||||||
tooltip: 'Delete Tag',
|
|
||||||
padding: EdgeInsets.zero,
|
|
||||||
constraints: const BoxConstraints(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
DataCell(
|
|
||||||
Container(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
width: double.infinity,
|
|
||||||
child: ProductTagField(
|
|
||||||
key: ValueKey('dropdown_$allocationUuid'),
|
|
||||||
productName: productAllocation.product.uuid,
|
|
||||||
initialValue: productAllocation.tag,
|
|
||||||
onSelected: (newTag) {
|
|
||||||
onTagSelected(allocationUuid, newTag);
|
|
||||||
},
|
|
||||||
items: availableTags,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
DataCell(
|
|
||||||
SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
child: DialogDropdown(
|
|
||||||
items: [
|
|
||||||
'Main Space',
|
|
||||||
...subspaces.map((s) => s.name)
|
|
||||||
],
|
|
||||||
selectedValue: currentLocationName,
|
|
||||||
onSelected: (newLocationName) {
|
|
||||||
final newSubspaceUuid = newLocationName ==
|
|
||||||
'Main Space'
|
|
||||||
? null
|
|
||||||
: subspaces
|
|
||||||
.firstWhere(
|
|
||||||
(s) => s.name == newLocationName)
|
|
||||||
.uuid;
|
|
||||||
onLocationSelected(
|
|
||||||
allocationUuid, newSubspaceUuid);
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
|
key: ValueKey(productAllocations.length),
|
||||||
|
border: TableBorder.all(
|
||||||
|
color: ColorsManager.dataHeaderGrey,
|
||||||
|
width: 1,
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
),
|
||||||
|
columns: [
|
||||||
|
_buildDataColumn(context, '#'),
|
||||||
|
_buildDataColumn(context, 'Device'),
|
||||||
|
_buildDataColumn(context, 'Tag'),
|
||||||
|
_buildDataColumn(context, 'Location'),
|
||||||
|
],
|
||||||
|
rows: productAllocations.isEmpty
|
||||||
|
? [
|
||||||
|
DataRow(
|
||||||
|
cells: [
|
||||||
|
DataCell(
|
||||||
|
FittedBox(
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
fit: BoxFit.scaleDown,
|
||||||
|
child: SelectableText(
|
||||||
|
'No Devices Available',
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: ColorsManager.lightGrayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell.empty,
|
||||||
|
DataCell.empty,
|
||||||
|
DataCell.empty,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
: List.generate(productAllocations.length, (index) {
|
||||||
|
final productAllocation = productAllocations[index];
|
||||||
|
final allocationUuid = productAllocation.uuid;
|
||||||
|
|
||||||
|
final availableTags = tags
|
||||||
|
.where(
|
||||||
|
(tag) =>
|
||||||
|
!productAllocations
|
||||||
|
.where((p) =>
|
||||||
|
p.product.productType ==
|
||||||
|
productAllocation.product.productType)
|
||||||
|
.map((p) => p.tag.name.toLowerCase())
|
||||||
|
.contains(tag.name.toLowerCase()) ||
|
||||||
|
tag.uuid == productAllocation.tag.uuid,
|
||||||
|
)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
final currentLocationUuid = productLocations[allocationUuid];
|
||||||
|
final currentLocationName = currentLocationUuid == null
|
||||||
|
? 'Main Space'
|
||||||
|
: subspaces
|
||||||
|
.firstWhere((s) => s.uuid == currentLocationUuid)
|
||||||
|
.name;
|
||||||
|
|
||||||
|
return DataRow(
|
||||||
|
key: ValueKey(allocationUuid),
|
||||||
|
cells: [
|
||||||
|
DataCell(Text((index + 1).toString())),
|
||||||
|
DataCell(
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
productAllocation.product.name,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Container(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
border: Border.all(
|
||||||
|
color: ColorsManager.lightGrayColor,
|
||||||
|
width: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: IconButton(
|
||||||
|
icon: const Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: ColorsManager.lightGreyColor,
|
||||||
|
size: 16,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
onProductDeleted(allocationUuid);
|
||||||
|
},
|
||||||
|
tooltip: 'Delete Tag',
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
Container(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
width: double.infinity,
|
||||||
|
child: ProductTagField(
|
||||||
|
key: ValueKey('dropdown_$allocationUuid'),
|
||||||
|
productName: productAllocation.product.uuid,
|
||||||
|
initialValue: productAllocation.tag,
|
||||||
|
onSelected: (newTag) {
|
||||||
|
onTagSelected(allocationUuid, newTag);
|
||||||
|
},
|
||||||
|
items: availableTags,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataCell(
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: DialogDropdown(
|
||||||
|
items: [
|
||||||
|
'Main Space',
|
||||||
|
...subspaces.map((s) => s.name)
|
||||||
|
],
|
||||||
|
selectedValue: currentLocationName,
|
||||||
|
onSelected: (newLocationName) {
|
||||||
|
final newSubspaceUuid = newLocationName ==
|
||||||
|
'Main Space'
|
||||||
|
? null
|
||||||
|
: subspaces
|
||||||
|
.firstWhere(
|
||||||
|
(s) => s.name == newLocationName)
|
||||||
|
.uuid;
|
||||||
|
onLocationSelected(
|
||||||
|
allocationUuid, newSubspaceUuid);
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
_ => const SizedBox.shrink(),
|
),
|
||||||
};
|
_ => const SizedBox.shrink(),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user