diff --git a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart index 85be3bf3..873c7dd6 100644 --- a/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart +++ b/lib/pages/spaces_management/assign_tag_models/views/assign_tag_models_dialog.dart @@ -1,9 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:syncrow_web/common/dialog_dropdown.dart'; -import 'package:syncrow_web/common/tag_dialog_textfield_dropdown.dart'; -import 'package:syncrow_web/pages/common/buttons/cancel_button.dart'; -import 'package:syncrow_web/pages/common/buttons/default_button.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; @@ -12,11 +8,9 @@ import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assig import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.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/subspace_template_model.dart'; -import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart'; -import 'package:syncrow_web/pages/spaces_management/tag_model/views/add_device_type_model_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; -import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart'; -import 'package:uuid/uuid.dart'; + +import 'widgets/assign_tags_tables_widget.dart'; class AssignTagModelsDialog extends StatelessWidget { final List? products; @@ -53,8 +47,10 @@ class AssignTagModelsDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final List locations = - (subspaces ?? []).map((subspace) => subspace.subspaceName).toList()..add('Main Space'); + final List locations = (subspaces ?? []) + .map((subspace) => subspace.subspaceName) + .toList() + ..add('Main Space'); return BlocProvider( create: (_) => AssignTagModelBloc(projectTags) @@ -78,137 +74,9 @@ class AssignTagModelsDialog extends StatelessWidget { content: SingleChildScrollView( child: Column( children: [ - ClipRRect( - borderRadius: BorderRadius.circular(20), - child: DataTable( - headingRowColor: WidgetStateProperty.all(ColorsManager.dataHeaderGrey), - key: ValueKey(state.tags.length), - border: TableBorder.all( - color: ColorsManager.dataHeaderGrey, - width: 1, - borderRadius: BorderRadius.circular(20), - ), - columns: [ - DataColumn( - label: Text('#', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Device', - style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - numeric: false, - label: - Text('Tag', style: Theme.of(context).textTheme.bodyMedium)), - DataColumn( - label: Text('Location', - style: Theme.of(context).textTheme.bodyMedium)), - ], - rows: state.tags.isEmpty - ? [ - DataRow(cells: [ - DataCell( - Center( - child: Text('No Devices Available', - style: - Theme.of(context).textTheme.bodyMedium?.copyWith( - color: ColorsManager.lightGrayColor, - )), - ), - ), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - const DataCell(SizedBox()), - ]) - ] - : List.generate(state.tags.length, (index) { - final tag = state.tags[index]; - final controller = controllers[index]; - - return DataRow( - cells: [ - DataCell(Text((index + 1).toString())), - DataCell( - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - tag.product?.name ?? 'Unknown', - overflow: TextOverflow.ellipsis, - )), - const SizedBox(width: 10), - Container( - width: 20.0, - height: 20.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: ColorsManager.lightGrayColor, - width: 1.0, - ), - ), - child: IconButton( - icon: const Icon( - Icons.close, - color: ColorsManager.lightGreyColor, - size: 16, - ), - onPressed: () { - context.read().add( - DeleteTagModel( - tagToDelete: tag, tags: state.tags)); - controllers.removeAt(index); - }, - tooltip: 'Delete Tag', - padding: EdgeInsets.zero, - constraints: const BoxConstraints(), - ), - ), - ], - ), - ), - DataCell( - Container( - alignment: Alignment - .centerLeft, // Align cell content to the left - child: SizedBox( - width: double.infinity, - child: TagDialogTextfieldDropdown( - key: ValueKey( - 'dropdown_${const Uuid().v4()}_$index'), - product: tag.product?.uuid ?? 'Unknown', - items: state.updatedTags, - initialValue: tag, - onSelected: (value) { - controller.text = value.tag ?? ''; - context.read().add(UpdateTag( - index: index, - tag: value, - )); - }, - ), - ), - ), - ), - DataCell( - SizedBox( - width: double.infinity, - child: DialogDropdown( - items: locations, - selectedValue: tag.location ?? 'Main Space', - onSelected: (value) { - context - .read() - .add(UpdateLocation( - index: index, - location: value, - )); - }, - )), - ), - ], - ); - }), - ), + AssignTagsTable( + controllers: controllers, + locations: locations, ), if (state.errorMessage != null) Text(state.errorMessage!, @@ -220,102 +88,17 @@ class AssignTagModelsDialog extends StatelessWidget { ), ), actions: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - const SizedBox(width: 10), - Expanded( - child: Builder( - builder: (buttonContext) => CancelButton( - label: 'Add New Device', - onPressed: () async { - final updatedTags = List.from(state.tags); - final result = - TagHelper.updateSubspaceTagModels(updatedTags, subspaces); - - final processedTags = result['updatedTags'] as List; - final processedSubspaces = List.from( - result['subspaces'] as List); - - if (context.mounted) { - Navigator.of(context).pop(); - - await showDialog( - barrierDismissible: false, - context: context, - builder: (dialogContext) => AddDeviceTypeModelWidget( - products: products, - subspaces: processedSubspaces, - isCreate: false, - initialSelectedProducts: - TagHelper.createInitialSelectedProducts( - processedTags, processedSubspaces), - allTags: allTags, - spaceName: spaceName, - otherSpaceModels: otherSpaceModels, - spaceTagModels: processedTags, - pageContext: pageContext, - projectTags: projectTags, - spaceModel: SpaceTemplateModel( - modelName: spaceName, - tags: updatedTags, - uuid: spaceModel?.uuid, - internalId: spaceModel?.internalId, - subspaceModels: processedSubspaces)), - ); - } - }, - ), - ), - ), - const SizedBox(width: 10), - Expanded( - child: DefaultButton( - borderRadius: 10, - backgroundColor: ColorsManager.secondaryColor, - foregroundColor: state.isSaveEnabled - ? ColorsManager.whiteColors - : ColorsManager.whiteColorsWithOpacity, - onPressed: state.isSaveEnabled - ? () async { - final updatedTags = List.from(state.tags); - - final result = - TagHelper.updateSubspaceTagModels(updatedTags, subspaces); - - final processedTags = result['updatedTags'] as List; - final processedSubspaces = List.from( - result['subspaces'] as List); - - Navigator.of(context).popUntil((route) => route.isFirst); - - await showDialog( - context: context, - builder: (BuildContext dialogContext) { - return CreateSpaceModelDialog( - products: products, - allSpaceModels: allSpaceModels, - allTags: allTags, - projectTags: projectTags, - pageContext: pageContext, - otherSpaceModels: otherSpaceModels, - spaceModel: SpaceTemplateModel( - modelName: spaceName, - tags: processedTags, - uuid: spaceModel?.uuid, - internalId: spaceModel?.internalId, - subspaceModels: processedSubspaces), - ); - }, - ); - } - : null, - child: const Text('Save'), - ), - ), - const SizedBox(width: 10), - ], - ), + // RowOfNextCancelWidget( + // subspaces: subspaces, + // products: products, + // allTags: allTags, + // spaceName: spaceName, + // otherSpaceModels: otherSpaceModels, + // pageContext: pageContext, + // projectTags: projectTags, + // spaceModel: spaceModel, + // allSpaceModels: allSpaceModels, + // ), ], ); } else if (state is AssignTagModelLoading) { diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart new file mode 100644 index 00000000..9b2a1367 --- /dev/null +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/RowOfCancelSaveWidget.dart @@ -0,0 +1,152 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import '../../../../../utils/color_manager.dart'; +import '../../../../common/buttons/cancel_button.dart'; +import '../../../../common/buttons/default_button.dart'; +import '../../../all_spaces/model/product_model.dart'; +import '../../../all_spaces/model/tag.dart'; +import '../../../helper/tag_helper.dart'; +import '../../../space_model/models/space_template_model.dart'; +import '../../../space_model/models/subspace_template_model.dart'; +import '../../../space_model/widgets/dialog/create_space_model_dialog.dart'; +import '../../../tag_model/views/add_device_type_model_widget.dart'; +import '../../bloc/assign_tag_model_bloc.dart'; +import '../../bloc/assign_tag_model_state.dart'; + +class RowOfSaveCancelWidget extends StatelessWidget { + const RowOfSaveCancelWidget({ + super.key, + required this.subspaces, + required this.products, + required this.allTags, + required this.spaceName, + required this.otherSpaceModels, + required this.pageContext, + required this.projectTags, + required this.spaceModel, + required this.allSpaceModels, + }); + + final List? subspaces; + final List? products; + final List? allTags; + final String spaceName; + final List? otherSpaceModels; + final BuildContext? pageContext; + final List projectTags; + final SpaceTemplateModel? spaceModel; + final List? allSpaceModels; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is AssignTagModelLoaded) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + const SizedBox(width: 10), + Expanded( + child: Builder( + builder: (buttonContext) => CancelButton( + label: 'Add New Device', + onPressed: () async { + final updatedTags = List.from(state.tags); + final result = TagHelper.updateSubspaceTagModels( + updatedTags, subspaces); + + final processedTags = result['updatedTags'] as List; + final processedSubspaces = + List.from( + result['subspaces'] as List); + + if (context.mounted) { + Navigator.of(context).pop(); + + await showDialog( + barrierDismissible: false, + context: context, + builder: (dialogContext) => AddDeviceTypeModelWidget( + products: products, + subspaces: processedSubspaces, + isCreate: false, + initialSelectedProducts: + TagHelper.createInitialSelectedProducts( + processedTags, processedSubspaces), + allTags: allTags, + spaceName: spaceName, + otherSpaceModels: otherSpaceModels, + spaceTagModels: processedTags, + pageContext: pageContext, + projectTags: projectTags, + spaceModel: SpaceTemplateModel( + modelName: spaceName, + tags: updatedTags, + uuid: spaceModel?.uuid, + internalId: spaceModel?.internalId, + subspaceModels: processedSubspaces)), + ); + } + }, + ), + ), + ), + const SizedBox(width: 10), + Expanded( + child: DefaultButton( + borderRadius: 10, + backgroundColor: ColorsManager.secondaryColor, + foregroundColor: state.isSaveEnabled + ? ColorsManager.whiteColors + : ColorsManager.whiteColorsWithOpacity, + onPressed: state.isSaveEnabled + ? () async { + final updatedTags = List.from(state.tags); + + final result = TagHelper.updateSubspaceTagModels( + updatedTags, subspaces); + + final processedTags = + result['updatedTags'] as List; + final processedSubspaces = + List.from( + result['subspaces'] as List); + + Navigator.of(context) + .popUntil((route) => route.isFirst); + + await showDialog( + context: context, + builder: (BuildContext dialogContext) { + return CreateSpaceModelDialog( + products: products, + allSpaceModels: allSpaceModels, + allTags: allTags, + projectTags: projectTags, + pageContext: pageContext, + otherSpaceModels: otherSpaceModels, + spaceModel: SpaceTemplateModel( + modelName: spaceName, + tags: processedTags, + uuid: spaceModel?.uuid, + internalId: spaceModel?.internalId, + subspaceModels: processedSubspaces), + ); + }, + ); + } + : null, + child: const Text('Save'), + ), + ), + const SizedBox(width: 10), + ], + ); + } else { + return const SizedBox(); + } + }, + ); + } +} diff --git a/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart new file mode 100644 index 00000000..eaddc26c --- /dev/null +++ b/lib/pages/spaces_management/assign_tag_models/views/widgets/assign_tags_tables_widget.dart @@ -0,0 +1,172 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:uuid/uuid.dart'; + +import '../../../../../common/dialog_dropdown.dart'; +import '../../../../../common/tag_dialog_textfield_dropdown.dart'; +import '../../../../../utils/color_manager.dart'; +import '../../bloc/assign_tag_model_bloc.dart'; +import '../../bloc/assign_tag_model_event.dart'; +import '../../bloc/assign_tag_model_state.dart'; + +class AssignTagsTable extends StatelessWidget { + const AssignTagsTable({ + super.key, + required this.controllers, + required this.locations, + }); + + final List controllers; + final List locations; + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is AssignTagModelLoaded) { + return ClipRRect( + borderRadius: BorderRadius.circular(20), + child: DataTable( + headingRowColor: + WidgetStateProperty.all(ColorsManager.dataHeaderGrey), + key: ValueKey(state.tags.length), + border: TableBorder.all( + color: ColorsManager.dataHeaderGrey, + width: 1, + borderRadius: BorderRadius.circular(20), + ), + columns: [ + DataColumn( + label: Text('#', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + label: Text('Device', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + numeric: false, + label: Text('Tag', + style: Theme.of(context).textTheme.bodyMedium)), + DataColumn( + label: Text('Location', + style: Theme.of(context).textTheme.bodyMedium)), + ], + rows: state.tags.isEmpty + ? [ + DataRow(cells: [ + DataCell( + Center( + child: Text('No Devices Available', + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith( + color: ColorsManager.lightGrayColor, + )), + ), + ), + const DataCell(SizedBox()), + const DataCell(SizedBox()), + const DataCell(SizedBox()), + ]) + ] + : List.generate(state.tags.length, (index) { + final tag = state.tags[index]; + final controller = controllers[index]; + + return DataRow( + cells: [ + DataCell(Text((index + 1).toString())), + DataCell( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + tag.product?.name ?? 'Unknown', + overflow: TextOverflow.ellipsis, + )), + const SizedBox(width: 10), + Container( + width: 20.0, + height: 20.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: ColorsManager.lightGrayColor, + width: 1.0, + ), + ), + child: IconButton( + icon: const Icon( + Icons.close, + color: ColorsManager.lightGreyColor, + size: 16, + ), + onPressed: () { + context.read().add( + DeleteTagModel( + tagToDelete: tag, + tags: state.tags)); + controllers.removeAt(index); + }, + tooltip: 'Delete Tag', + padding: EdgeInsets.zero, + constraints: const BoxConstraints(), + ), + ), + ], + ), + ), + DataCell( + Container( + alignment: Alignment + .centerLeft, // Align cell content to the left + child: SizedBox( + width: double.infinity, + child: TagDialogTextfieldDropdown( + key: ValueKey( + 'dropdown_${const Uuid().v4()}_$index'), + product: tag.product?.uuid ?? 'Unknown', + items: state.updatedTags, + initialValue: tag, + onSelected: (value) { + controller.text = value.tag ?? ''; + context + .read() + .add(UpdateTag( + index: index, + tag: value, + )); + }, + ), + ), + ), + ), + DataCell( + SizedBox( + width: double.infinity, + child: DialogDropdown( + items: locations, + selectedValue: tag.location ?? 'Main Space', + onSelected: (value) { + context + .read() + .add(UpdateLocation( + index: index, + location: value, + )); + }, + )), + ), + ], + ); + }), + ), + ); + } else { + return const SizedBox(); + } + }, + ); + } +}