mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
add ok_candel row of buttons in seperated widget also text field widget
This commit is contained in:
@ -12,6 +12,9 @@ import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_
|
|||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
|
import 'widgets/ok_cancel_sub_space_widget.dart';
|
||||||
|
import 'widgets/textfield_sub_space_dialog_widget.dart';
|
||||||
|
|
||||||
class CreateSubSpaceDialog extends StatefulWidget {
|
class CreateSubSpaceDialog extends StatefulWidget {
|
||||||
final String dialogTitle;
|
final String dialogTitle;
|
||||||
final List<SubspaceModel>? existingSubSpaces;
|
final List<SubspaceModel>? existingSubSpaces;
|
||||||
@ -33,14 +36,7 @@ class CreateSubSpaceDialog extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CreateSubSpaceDialogState extends State<CreateSubSpaceDialog> {
|
class _CreateSubSpaceDialogState extends State<CreateSubSpaceDialog> {
|
||||||
late final TextEditingController _subspaceNameController;
|
final TextEditingController _subspaceNameController = TextEditingController();
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_subspaceNameController = TextEditingController();
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_subspaceNameController.dispose();
|
_subspaceNameController.dispose();
|
||||||
@ -96,84 +92,9 @@ class _CreateSubSpaceDialogState extends State<CreateSubSpaceDialog> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Container(
|
TextFieldSubSpaceDialogWidget(
|
||||||
width: context.screenWidth * 0.35,
|
subspaceNameController: _subspaceNameController,
|
||||||
padding: const EdgeInsets.symmetric(
|
subSpaces: state.subSpaces,
|
||||||
vertical: 10,
|
|
||||||
horizontal: 16,
|
|
||||||
),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: ColorsManager.boxColor,
|
|
||||||
borderRadius: BorderRadius.circular(10),
|
|
||||||
),
|
|
||||||
child: Wrap(
|
|
||||||
spacing: 8,
|
|
||||||
runSpacing: 8,
|
|
||||||
alignment: WrapAlignment.start,
|
|
||||||
crossAxisAlignment: WrapCrossAlignment.center,
|
|
||||||
children: [
|
|
||||||
...state.subSpaces.asMap().entries.map(
|
|
||||||
(entry) {
|
|
||||||
final index = entry.key;
|
|
||||||
final subSpace = entry.value;
|
|
||||||
|
|
||||||
final lowerName =
|
|
||||||
subSpace.subspaceName.toLowerCase();
|
|
||||||
|
|
||||||
final duplicateIndices = state.subSpaces
|
|
||||||
.asMap()
|
|
||||||
.entries
|
|
||||||
.where((e) =>
|
|
||||||
e.value.subspaceName.toLowerCase() ==
|
|
||||||
lowerName)
|
|
||||||
.map((e) => e.key)
|
|
||||||
.toList();
|
|
||||||
final isDuplicate = duplicateIndices.length > 1 &&
|
|
||||||
duplicateIndices.indexOf(index) != 0;
|
|
||||||
return SubspaceChip(
|
|
||||||
subSpace: SubspaceTemplateModel(
|
|
||||||
subspaceName: entry.value.subspaceName,
|
|
||||||
disabled: entry.value.disabled,
|
|
||||||
),
|
|
||||||
isDuplicate: isDuplicate,
|
|
||||||
onDeleted: () => context.read<SubSpaceBloc>().add(
|
|
||||||
RemoveSubSpace(subSpace),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 200,
|
|
||||||
child: TextField(
|
|
||||||
controller: _subspaceNameController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
border: InputBorder.none,
|
|
||||||
hintText: state.subSpaces.isEmpty
|
|
||||||
? 'Please enter the name'
|
|
||||||
: null,
|
|
||||||
hintStyle: context.textTheme.bodySmall?.copyWith(
|
|
||||||
color: ColorsManager.lightGrayColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onSubmitted: (value) {
|
|
||||||
final trimmedValue = value.trim();
|
|
||||||
if (trimmedValue.isNotEmpty) {
|
|
||||||
context.read<SubSpaceBloc>().add(
|
|
||||||
AddSubSpace(
|
|
||||||
SubspaceModel(
|
|
||||||
subspaceName: trimmedValue,
|
|
||||||
disabled: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_subspaceNameController.clear();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
style: context.textTheme.bodyMedium,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (state.errorMessage.isNotEmpty)
|
if (state.errorMessage.isNotEmpty)
|
||||||
Padding(
|
Padding(
|
||||||
@ -186,58 +107,10 @@ class _CreateSubSpaceDialogState extends State<CreateSubSpaceDialog> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Row(
|
OkCancelSubSpaceWidget(
|
||||||
children: [
|
subspaceNameController: _subspaceNameController,
|
||||||
Expanded(
|
errorMessage: state.errorMessage,
|
||||||
child: CancelButton(
|
onSave: widget.onSave,
|
||||||
label: 'Cancel',
|
|
||||||
onPressed: () async {
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: DefaultButton(
|
|
||||||
onPressed: state.errorMessage.isEmpty
|
|
||||||
? () async {
|
|
||||||
final trimmedValue =
|
|
||||||
_subspaceNameController.text.trim();
|
|
||||||
|
|
||||||
final subSpacesBloc =
|
|
||||||
context.read<SubSpaceBloc>();
|
|
||||||
if (trimmedValue.isNotEmpty) {
|
|
||||||
subSpacesBloc.add(
|
|
||||||
AddSubSpace(
|
|
||||||
SubspaceModel(
|
|
||||||
subspaceName: trimmedValue,
|
|
||||||
disabled: false,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
_subspaceNameController.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
await Future.delayed(
|
|
||||||
const Duration(milliseconds: 10));
|
|
||||||
final subSpaces =
|
|
||||||
subSpacesBloc.state.subSpaces;
|
|
||||||
// if (subSpaces.isNotEmpty) {
|
|
||||||
widget.onSave?.call(subSpaces);
|
|
||||||
// }
|
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
backgroundColor: ColorsManager.secondaryColor,
|
|
||||||
borderRadius: 10,
|
|
||||||
foregroundColor: state.errorMessage.isNotEmpty
|
|
||||||
? ColorsManager.whiteColorsWithOpacity
|
|
||||||
: ColorsManager.whiteColors,
|
|
||||||
child: const Text('OK'),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart';
|
||||||
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
|
||||||
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
|
|
||||||
|
import '../../bloc/subspace_bloc.dart';
|
||||||
|
import '../../bloc/subspace_event.dart';
|
||||||
|
|
||||||
|
class OkCancelSubSpaceWidget extends StatelessWidget {
|
||||||
|
const OkCancelSubSpaceWidget({
|
||||||
|
super.key,
|
||||||
|
required this.subspaceNameController,
|
||||||
|
required this.onSave,
|
||||||
|
required this.errorMessage,
|
||||||
|
});
|
||||||
|
|
||||||
|
final TextEditingController subspaceNameController;
|
||||||
|
final void Function(List<SubspaceModel>?)? onSave;
|
||||||
|
final String errorMessage;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: CancelButton(
|
||||||
|
label: 'Cancel',
|
||||||
|
onPressed: () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: DefaultButton(
|
||||||
|
onPressed: errorMessage.isEmpty
|
||||||
|
? () async {
|
||||||
|
final trimmedValue = subspaceNameController.text.trim();
|
||||||
|
|
||||||
|
final subSpacesBloc = context.read<SubSpaceBloc>();
|
||||||
|
if (trimmedValue.isNotEmpty) {
|
||||||
|
subSpacesBloc.add(
|
||||||
|
AddSubSpace(
|
||||||
|
SubspaceModel(
|
||||||
|
subspaceName: trimmedValue,
|
||||||
|
disabled: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
subspaceNameController.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
await Future.delayed(const Duration(milliseconds: 10));
|
||||||
|
final subSpaces = subSpacesBloc.state.subSpaces;
|
||||||
|
onSave?.call(subSpaces);
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
backgroundColor: ColorsManager.secondaryColor,
|
||||||
|
borderRadius: 10,
|
||||||
|
foregroundColor: errorMessage.isNotEmpty
|
||||||
|
? ColorsManager.whiteColorsWithOpacity
|
||||||
|
: ColorsManager.whiteColors,
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:syncrow_web/utils/extension/build_context_x.dart';
|
||||||
|
|
||||||
|
import '../../../../../utils/color_manager.dart';
|
||||||
|
import '../../../all_spaces/model/subspace_model.dart';
|
||||||
|
import '../../../create_subspace_model/widgets/subspace_chip.dart';
|
||||||
|
import '../../../space_model/models/subspace_template_model.dart';
|
||||||
|
import '../../bloc/subspace_bloc.dart';
|
||||||
|
import '../../bloc/subspace_event.dart';
|
||||||
|
|
||||||
|
class TextFieldSubSpaceDialogWidget extends StatelessWidget {
|
||||||
|
const TextFieldSubSpaceDialogWidget({
|
||||||
|
super.key,
|
||||||
|
required TextEditingController subspaceNameController,
|
||||||
|
required this.subSpaces,
|
||||||
|
}) : _subspaceNameController = subspaceNameController;
|
||||||
|
|
||||||
|
final TextEditingController _subspaceNameController;
|
||||||
|
final List<SubspaceModel> subSpaces;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
width: context.screenWidth * 0.35,
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 10,
|
||||||
|
horizontal: 16,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: ColorsManager.boxColor,
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 8,
|
||||||
|
runSpacing: 8,
|
||||||
|
alignment: WrapAlignment.start,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
...subSpaces.asMap().entries.map(
|
||||||
|
(entry) {
|
||||||
|
final index = entry.key;
|
||||||
|
final subSpace = entry.value;
|
||||||
|
|
||||||
|
final lowerName = subSpace.subspaceName.toLowerCase();
|
||||||
|
|
||||||
|
final duplicateIndices = subSpaces
|
||||||
|
.asMap()
|
||||||
|
.entries
|
||||||
|
.where((e) => e.value.subspaceName.toLowerCase() == lowerName)
|
||||||
|
.map((e) => e.key)
|
||||||
|
.toList();
|
||||||
|
final isDuplicate = duplicateIndices.length > 1 &&
|
||||||
|
duplicateIndices.indexOf(index) != 0;
|
||||||
|
return SubspaceChip(
|
||||||
|
subSpace: SubspaceTemplateModel(
|
||||||
|
subspaceName: entry.value.subspaceName,
|
||||||
|
disabled: entry.value.disabled,
|
||||||
|
),
|
||||||
|
isDuplicate: isDuplicate,
|
||||||
|
onDeleted: () => context.read<SubSpaceBloc>().add(
|
||||||
|
RemoveSubSpace(subSpace),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 200,
|
||||||
|
child: TextField(
|
||||||
|
controller: _subspaceNameController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
border: InputBorder.none,
|
||||||
|
hintText: subSpaces.isEmpty ? 'Please enter the name' : null,
|
||||||
|
hintStyle: context.textTheme.bodySmall?.copyWith(
|
||||||
|
color: ColorsManager.lightGrayColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onSubmitted: (value) {
|
||||||
|
final trimmedValue = value.trim();
|
||||||
|
if (trimmedValue.isNotEmpty) {
|
||||||
|
context.read<SubSpaceBloc>().add(
|
||||||
|
AddSubSpace(
|
||||||
|
SubspaceModel(
|
||||||
|
subspaceName: trimmedValue,
|
||||||
|
disabled: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
_subspaceNameController.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: context.textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user