mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
changed chip to list
This commit is contained in:
@ -72,7 +72,7 @@ class LinkSpaceModelDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(8.0),
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
),
|
),
|
||||||
child: SpaceModelCardWidget(model: model),
|
child: SpaceModelCardWidget(model: model,),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -69,7 +69,7 @@ class SpaceModelPage extends StatelessWidget {
|
|||||||
final model = spaceModels[index];
|
final model = spaceModels[index];
|
||||||
return Container(
|
return Container(
|
||||||
margin: const EdgeInsets.all(8.0),
|
margin: const EdgeInsets.all(8.0),
|
||||||
child: SpaceModelCardWidget(model: model),
|
child: SpaceModelCardWidget(model:model),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -0,0 +1,66 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/ellipsis_item_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/flexible_item_widget.dart';
|
||||||
|
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class DynamicProductWidget extends StatelessWidget {
|
||||||
|
final Map<String, int> productTagCount;
|
||||||
|
final double maxWidth;
|
||||||
|
final double maxHeight;
|
||||||
|
|
||||||
|
const DynamicProductWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.productTagCount,
|
||||||
|
required this.maxWidth,
|
||||||
|
required this.maxHeight,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const double itemSpacing = 8.0;
|
||||||
|
const double lineSpacing = 8.0;
|
||||||
|
const double textPadding = 16.0;
|
||||||
|
const double itemHeight = 40.0;
|
||||||
|
|
||||||
|
List<Widget> productWidgets = [];
|
||||||
|
double currentLineWidth = 0.0;
|
||||||
|
double currentHeight = itemHeight;
|
||||||
|
|
||||||
|
for (final product in productTagCount.entries) {
|
||||||
|
final String prodType = product.key;
|
||||||
|
final int count = product.value;
|
||||||
|
|
||||||
|
final TextPainter textPainter = TextPainter(
|
||||||
|
text: TextSpan(
|
||||||
|
text: 'x$count',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(color: ColorsManager.spaceColor),
|
||||||
|
),
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
)..layout();
|
||||||
|
|
||||||
|
final double itemWidth = textPainter.width + textPadding + 20;
|
||||||
|
|
||||||
|
if (currentLineWidth + itemWidth + itemSpacing > maxWidth) {
|
||||||
|
currentHeight += itemHeight + lineSpacing;
|
||||||
|
if (currentHeight > maxHeight) {
|
||||||
|
productWidgets.add(const EllipsisItemWidget());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentLineWidth = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
productWidgets.add(FlexibleItemWidget(prodType: prodType, count: count));
|
||||||
|
currentLineWidth += itemWidth + itemSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Wrap(
|
||||||
|
spacing: itemSpacing,
|
||||||
|
runSpacing: lineSpacing,
|
||||||
|
children: productWidgets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/room_name_widget.dart';
|
||||||
|
|
||||||
|
class DynamicRoomWidget extends StatelessWidget {
|
||||||
|
final List<SubspaceTemplateModel>? subspaceModels;
|
||||||
|
final double maxWidth;
|
||||||
|
final double maxHeight;
|
||||||
|
|
||||||
|
const DynamicRoomWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.subspaceModels,
|
||||||
|
required this.maxWidth,
|
||||||
|
required this.maxHeight,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
const double itemSpacing = 8.0;
|
||||||
|
const double lineSpacing = 8.0;
|
||||||
|
const double textPadding = 16.0;
|
||||||
|
const double itemHeight = 30.0;
|
||||||
|
|
||||||
|
List<Widget> roomWidgets = [];
|
||||||
|
double currentLineWidth = 0.0;
|
||||||
|
double currentHeight = itemHeight;
|
||||||
|
|
||||||
|
for (final subspace in subspaceModels!) {
|
||||||
|
final TextPainter textPainter = TextPainter(
|
||||||
|
text: TextSpan(
|
||||||
|
text: subspace.subspaceName,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
textDirection: TextDirection.ltr,
|
||||||
|
)..layout();
|
||||||
|
|
||||||
|
final double itemWidth = textPainter.width + textPadding;
|
||||||
|
|
||||||
|
if (currentLineWidth + itemWidth + itemSpacing > maxWidth) {
|
||||||
|
currentHeight += itemHeight + lineSpacing;
|
||||||
|
if (currentHeight > maxHeight) {
|
||||||
|
roomWidgets.add(const RoomNameWidget(name: "..."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentLineWidth = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
roomWidgets.add(RoomNameWidget(name: subspace.subspaceName));
|
||||||
|
currentLineWidth += itemWidth + itemSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Wrap(
|
||||||
|
spacing: itemSpacing,
|
||||||
|
runSpacing: lineSpacing,
|
||||||
|
children: roomWidgets,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class EllipsisItemWidget extends StatelessWidget {
|
||||||
|
const EllipsisItemWidget({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.textFieldGreyColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(color: ColorsManager.transparentColor),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
"...",
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(color: ColorsManager.spaceColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class FlexibleItemWidget extends StatelessWidget {
|
||||||
|
final String prodType;
|
||||||
|
final int count;
|
||||||
|
|
||||||
|
const FlexibleItemWidget({
|
||||||
|
Key? key,
|
||||||
|
required this.prodType,
|
||||||
|
required this.count,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.textFieldGreyColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(color: ColorsManager.transparentColor),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
prodType,
|
||||||
|
width: 15,
|
||||||
|
height: 16,
|
||||||
|
),
|
||||||
|
const SizedBox(width: 4),
|
||||||
|
Text(
|
||||||
|
'x$count',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(color: ColorsManager.spaceColor),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
class RoomNameWidget extends StatelessWidget {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
const RoomNameWidget({Key? key, required this.name}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.textFieldGreyColor,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
border: Border.all(color: ColorsManager.transparentColor),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
name,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(color: ColorsManager.spaceColor),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/subspace_chip_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_product_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dynamic_room_widget.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/room_name_widget.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class SpaceModelCardWidget extends StatelessWidget {
|
class SpaceModelCardWidget extends StatelessWidget {
|
||||||
@ -32,111 +33,81 @@ class SpaceModelCardWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: ColorsManager.whiteColors,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
boxShadow: [
|
boxShadow: [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: ColorsManager.lightGrayColor.withOpacity(0.5),
|
color: Colors.grey.withOpacity(0.5),
|
||||||
spreadRadius: 2,
|
spreadRadius: 2,
|
||||||
blurRadius: 5,
|
blurRadius: 5,
|
||||||
offset: const Offset(0, 3),
|
offset: const Offset(0, 3),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
padding: const EdgeInsets.fromLTRB(16.0, 14.0, 8.0, 8.0),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Text(
|
||||||
child: Text(
|
model.modelName,
|
||||||
model.modelName,
|
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
color: Colors.black,
|
||||||
color: ColorsManager.blackColor,
|
fontWeight: FontWeight.bold,
|
||||||
fontWeight: FontWeight.bold,
|
),
|
||||||
),
|
maxLines: 1,
|
||||||
maxLines: 1,
|
overflow: TextOverflow.ellipsis,
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
|
// Left Container
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Wrap(
|
flex: 1, // Distribute space proportionally
|
||||||
spacing: 3.0,
|
child: Container(
|
||||||
runSpacing: 3.0,
|
padding: const EdgeInsets.all(8.0),
|
||||||
children: [
|
child: LayoutBuilder(
|
||||||
for (var subspace in model.subspaceModels!
|
builder: (context, constraints) {
|
||||||
.take(calculateTakeCount(context)))
|
return Align(
|
||||||
SubspaceChipWidget(subspace: subspace.subspaceName),
|
alignment: Alignment.topLeft,
|
||||||
],
|
child: DynamicRoomWidget(
|
||||||
|
subspaceModels: model.subspaceModels,
|
||||||
|
maxWidth: constraints.maxWidth,
|
||||||
|
maxHeight: constraints.maxHeight,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (productTagCount.isNotEmpty)
|
Container(
|
||||||
Container(
|
width: 1.0, // Thickness of the line
|
||||||
width: 1,
|
color: ColorsManager.softGray, // Subtle grey color
|
||||||
height: double.infinity,
|
margin: const EdgeInsets.symmetric(
|
||||||
color: ColorsManager.softGray,
|
vertical: 6.0), // Top and bottom spacing
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 4.0),
|
), // Right Container
|
||||||
),
|
|
||||||
const SizedBox(width: 7),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Wrap(
|
flex: 1, // Distribute space proportionally
|
||||||
spacing: 4.0,
|
child: Container(
|
||||||
runSpacing: 4.0,
|
padding: const EdgeInsets.all(8.0),
|
||||||
children: productTagCount.entries.map((entry) {
|
child: LayoutBuilder(
|
||||||
final prodType = entry.key;
|
builder: (context, constraints) {
|
||||||
final count = entry.value;
|
return Align(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
return Chip(
|
child: DynamicProductWidget(
|
||||||
label: Row(
|
productTagCount: productTagCount,
|
||||||
mainAxisSize: MainAxisSize.min,
|
maxWidth: constraints.maxWidth,
|
||||||
children: [
|
maxHeight: constraints.maxHeight));
|
||||||
SvgPicture.asset(
|
},
|
||||||
prodType,
|
),
|
||||||
width: 15,
|
|
||||||
height: 16,
|
|
||||||
),
|
|
||||||
const SizedBox(width: 4),
|
|
||||||
Text(
|
|
||||||
'x$count', // Product count
|
|
||||||
style: const TextStyle(fontSize: 12),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
side: const BorderSide(
|
|
||||||
color: ColorsManager.transparentColor,
|
|
||||||
width: 0,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 5),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculateTakeCount(BuildContext context) {
|
|
||||||
double screenWidth = MediaQuery.of(context).size.width;
|
|
||||||
// Adjust the count based on the screen width
|
|
||||||
if (screenWidth > 1500) {
|
|
||||||
return 3; // For large screens
|
|
||||||
} else if (screenWidth > 1200) {
|
|
||||||
return 2;
|
|
||||||
} else {
|
|
||||||
return 1; // For smaller screens
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class SubspaceChipWidget extends StatelessWidget {
|
class SubspaceChipWidget extends StatelessWidget {
|
||||||
final String subspace;
|
final String subspace;
|
||||||
|
|
||||||
@ -11,24 +14,25 @@ class SubspaceChipWidget extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Chip(
|
return Container(
|
||||||
label: Text(
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||||
subspace,
|
decoration: BoxDecoration(
|
||||||
overflow: TextOverflow.ellipsis,
|
color: ColorsManager.textFieldGreyColor,
|
||||||
maxLines: 1,
|
|
||||||
),
|
|
||||||
backgroundColor: ColorsManager.textFieldGreyColor,
|
|
||||||
labelStyle: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.bodySmall
|
|
||||||
?.copyWith(color: ColorsManager.spaceColor),
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
side: const BorderSide(
|
border: Border.all(
|
||||||
color: ColorsManager.transparentColor,
|
color: ColorsManager.transparentColor,
|
||||||
width: 0,
|
width: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
child: Text(
|
||||||
|
subspace,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodySmall
|
||||||
|
?.copyWith(color: ColorsManager.spaceColor),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user