mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-11 07:38:05 +00:00
Compare commits
2 Commits
bugfix/fix
...
roles_perm
Author | SHA1 | Date | |
---|---|---|---|
9a6bf5cbaf | |||
51fbe64209 |
@ -1,8 +1,6 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
import 'package:syncrow_web/services/devices_mang_api.dart';
|
import 'package:syncrow_web/services/devices_mang_api.dart';
|
||||||
|
|
||||||
part 'device_managment_event.dart';
|
part 'device_managment_event.dart';
|
||||||
@ -34,20 +32,7 @@ class DeviceManagementBloc extends Bloc<DeviceManagementEvent, DeviceManagementS
|
|||||||
Future<void> _onFetchDevices(FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
Future<void> _onFetchDevices(FetchDevices event, Emitter<DeviceManagementState> emit) async {
|
||||||
emit(DeviceManagementLoading());
|
emit(DeviceManagementLoading());
|
||||||
try {
|
try {
|
||||||
List<AllDevicesModel> devices = [];
|
final devices = await DevicesManagementApi().fetchDevices(event.communityId, event.spaceId);
|
||||||
_devices.clear();
|
|
||||||
var spaceBloc = event.context.read<SpaceTreeBloc>();
|
|
||||||
if (spaceBloc.state.selectedCommunities.isEmpty) {
|
|
||||||
devices = await DevicesManagementApi().fetchDevices('', '');
|
|
||||||
} else {
|
|
||||||
for (var community in spaceBloc.state.selectedCommunities) {
|
|
||||||
List<String> spacesList = spaceBloc.state.selectedCommunityAndSpaces[community] ?? [];
|
|
||||||
for (var space in spacesList) {
|
|
||||||
devices.addAll(await DevicesManagementApi().fetchDevices(community, space));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_selectedDevices.clear();
|
_selectedDevices.clear();
|
||||||
_devices = devices;
|
_devices = devices;
|
||||||
_filteredDevices = devices;
|
_filteredDevices = devices;
|
||||||
|
@ -8,13 +8,12 @@ abstract class DeviceManagementEvent extends Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class FetchDevices extends DeviceManagementEvent {
|
class FetchDevices extends DeviceManagementEvent {
|
||||||
// final Map<String, List<String>> selectedCommunitiesSpaces;
|
final String communityId;
|
||||||
// final String spaceId;
|
final String spaceId;
|
||||||
final BuildContext context;
|
|
||||||
|
|
||||||
const FetchDevices(this.context);
|
const FetchDevices(this.communityId, this.spaceId);
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [context];
|
List<Object?> get props => [communityId, spaceId];
|
||||||
}
|
}
|
||||||
|
|
||||||
class FilterDevices extends DeviceManagementEvent {
|
class FilterDevices extends DeviceManagementEvent {
|
||||||
|
@ -19,7 +19,7 @@ class DeviceManagementPage extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
return MultiBlocProvider(
|
return MultiBlocProvider(
|
||||||
providers: [
|
providers: [
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => DeviceManagementBloc()..add(FetchDevices(context)),
|
create: (context) => DeviceManagementBloc()..add(const FetchDevices('', '')),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
child: WebScaffold(
|
child: WebScaffold(
|
||||||
|
@ -8,7 +8,6 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo
|
|||||||
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart';
|
import 'package:syncrow_web/pages/device_managment/all_devices/widgets/device_search_filters.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/device_batch_control_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
|
import 'package:syncrow_web/pages/device_managment/shared/device_control_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
|
||||||
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
|
||||||
import 'package:syncrow_web/utils/format_date_time.dart';
|
import 'package:syncrow_web/utils/format_date_time.dart';
|
||||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||||
@ -63,11 +62,12 @@ class DeviceManagementBody extends StatelessWidget with HelperResponsiveLayout {
|
|||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: SpaceTreeView(
|
const Expanded(
|
||||||
onSelect: () {
|
child: SpaceTreeView(
|
||||||
context.read<DeviceManagementBloc>().add(FetchDevices(context));
|
// onSelectAction: (String communityId, String spaceId) {
|
||||||
},
|
// context.read<DeviceManagementBloc>().add(FetchDevices(communityId, spaceId));
|
||||||
)),
|
// },
|
||||||
|
)),
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: state is DeviceManagementLoading
|
child: state is DeviceManagementLoading
|
||||||
|
@ -85,7 +85,7 @@ class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperRe
|
|||||||
productNameController.clear();
|
productNameController.clear();
|
||||||
context.read<DeviceManagementBloc>()
|
context.read<DeviceManagementBloc>()
|
||||||
..add(ResetFilters())
|
..add(ResetFilters())
|
||||||
..add(FetchDevices(context));
|
..add(const FetchDevices('', ''));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
@ -51,6 +52,8 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||||
user = await HomeApi().fetchUserInfo(uuid);
|
user = await HomeApi().fetchUserInfo(uuid);
|
||||||
add(FetchTermEvent());
|
add(FetchTermEvent());
|
||||||
|
add(FetchPolicyEvent());
|
||||||
|
|
||||||
emit(HomeInitial());
|
emit(HomeInitial());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
@ -61,8 +64,9 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
try {
|
try {
|
||||||
emit(LoadingHome());
|
emit(LoadingHome());
|
||||||
terms = await HomeApi().fetchTerms();
|
terms = await HomeApi().fetchTerms();
|
||||||
add(FetchPolicyEvent());
|
emit(HomeInitial());
|
||||||
emit(PolicyAgreement());
|
|
||||||
|
// emit(PolicyAgreement());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -72,8 +76,11 @@ class HomeBloc extends Bloc<HomeEvent, HomeState> {
|
|||||||
try {
|
try {
|
||||||
emit(LoadingHome());
|
emit(LoadingHome());
|
||||||
policy = await HomeApi().fetchPolicy();
|
policy = await HomeApi().fetchPolicy();
|
||||||
emit(PolicyAgreement());
|
debugPrint("Fetched policy: $policy");
|
||||||
|
// Emit a state to trigger the UI update
|
||||||
|
emit(HomeInitial());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
debugPrint("Error fetching policy: $e");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,103 +9,126 @@ import 'package:syncrow_web/pages/home/view/home_card.dart';
|
|||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
import 'package:syncrow_web/web_layout/web_scaffold.dart';
|
||||||
|
|
||||||
class HomeWebPage extends StatelessWidget {
|
class HomeWebPage extends StatefulWidget {
|
||||||
const HomeWebPage({super.key});
|
const HomeWebPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<HomeWebPage> createState() => _HomeWebPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _HomeWebPageState extends State<HomeWebPage> {
|
||||||
|
// Flag to track whether the dialog is already shown.
|
||||||
|
bool _dialogShown = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
final homeBloc = BlocProvider.of<HomeBloc>(context);
|
||||||
|
homeBloc.add(FetchUserInfo());
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Size size = MediaQuery.of(context).size;
|
Size size = MediaQuery.of(context).size;
|
||||||
final homeBloc = BlocProvider.of<HomeBloc>(context);
|
final homeBloc = BlocProvider.of<HomeBloc>(context);
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: false,
|
canPop: false,
|
||||||
onPopInvoked: (didPop) => false,
|
onPopInvoked: (didPop) => false,
|
||||||
child: BlocConsumer<HomeBloc, HomeState>(
|
child: BlocConsumer<HomeBloc, HomeState>(
|
||||||
listener: (BuildContext context, state) {
|
listener: (BuildContext context, state) {
|
||||||
if (state is HomeInitial) {
|
print('state=$state');
|
||||||
if (homeBloc.user!.hasAcceptedWebAgreement == false) {
|
if (state is HomeInitial) {
|
||||||
Future.delayed(const Duration(seconds: 2), () {
|
if (homeBloc.user!.hasAcceptedWebAgreement == false &&
|
||||||
showDialog(
|
!_dialogShown) {
|
||||||
context: context,
|
_dialogShown =
|
||||||
barrierDismissible: false,
|
true; // Set the flag to true to indicate the dialog is showing.
|
||||||
builder: (BuildContext context) {
|
Future.delayed(const Duration(seconds: 1), () {
|
||||||
return AgreementAndPrivacyDialog(
|
showDialog(
|
||||||
terms: homeBloc.terms,
|
context: context,
|
||||||
policy: homeBloc.policy,
|
barrierDismissible: false,
|
||||||
);
|
builder: (BuildContext context) {
|
||||||
},
|
return AgreementAndPrivacyDialog(
|
||||||
).then((v) {
|
terms: homeBloc.terms,
|
||||||
if (v != null) {
|
policy: homeBloc.policy,
|
||||||
homeBloc.add(ConfirmUserAgreementEvent());
|
);
|
||||||
homeBloc.add(const FetchUserInfo());
|
},
|
||||||
}
|
).then((v) {
|
||||||
});
|
_dialogShown = false;
|
||||||
|
if (v != null) {
|
||||||
|
homeBloc.add(ConfirmUserAgreementEvent());
|
||||||
|
homeBloc.add(const FetchUserInfo());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
builder: (context, state) {
|
},
|
||||||
return WebScaffold(
|
builder: (context, state) {
|
||||||
enableMenuSidebar: false,
|
return WebScaffold(
|
||||||
appBarTitle: Row(
|
enableMenuSidebar: false,
|
||||||
|
appBarTitle: Row(
|
||||||
|
children: [
|
||||||
|
SvgPicture.asset(
|
||||||
|
Assets.loginLogo,
|
||||||
|
width: 150,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
scaffoldBody: SizedBox(
|
||||||
|
height: size.height,
|
||||||
|
width: size.width,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
SvgPicture.asset(
|
Column(
|
||||||
Assets.loginLogo,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
width: 150,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: size.height * 0.1),
|
||||||
|
Text(
|
||||||
|
'ACCESS YOUR APPS',
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineLarge!
|
||||||
|
.copyWith(color: Colors.black, fontSize: 40),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 30),
|
||||||
|
Expanded(
|
||||||
|
flex: 4,
|
||||||
|
child: SizedBox(
|
||||||
|
height: size.height * 0.6,
|
||||||
|
width: size.width * 0.68,
|
||||||
|
child: GridView.builder(
|
||||||
|
itemCount: 3, // Change this count if needed.
|
||||||
|
gridDelegate:
|
||||||
|
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: 3, // Adjust as needed.
|
||||||
|
crossAxisSpacing: 20.0,
|
||||||
|
mainAxisSpacing: 20.0,
|
||||||
|
childAspectRatio: 1.5,
|
||||||
|
),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return HomeCard(
|
||||||
|
index: index,
|
||||||
|
active: homeBloc.homeItems[index].active!,
|
||||||
|
name: homeBloc.homeItems[index].title!,
|
||||||
|
img: homeBloc.homeItems[index].icon!,
|
||||||
|
onTap: () =>
|
||||||
|
homeBloc.homeItems[index].onPress(context),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
scaffoldBody: SizedBox(
|
),
|
||||||
height: size.height,
|
);
|
||||||
width: size.width,
|
},
|
||||||
child: Row(
|
),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
);
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SizedBox(height: size.height * 0.1),
|
|
||||||
Text(
|
|
||||||
'ACCESS YOUR APPS',
|
|
||||||
style: Theme.of(context)
|
|
||||||
.textTheme
|
|
||||||
.headlineLarge!
|
|
||||||
.copyWith(color: Colors.black, fontSize: 40),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 30),
|
|
||||||
Expanded(
|
|
||||||
flex: 4,
|
|
||||||
child: SizedBox(
|
|
||||||
height: size.height * 0.6,
|
|
||||||
width: size.width * 0.68,
|
|
||||||
child: GridView.builder(
|
|
||||||
itemCount: 3, //8
|
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: 3, //4
|
|
||||||
crossAxisSpacing: 20.0,
|
|
||||||
mainAxisSpacing: 20.0,
|
|
||||||
childAspectRatio: 1.5,
|
|
||||||
),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return HomeCard(
|
|
||||||
index: index,
|
|
||||||
active: homeBloc.homeItems[index].active!,
|
|
||||||
name: homeBloc.homeItems[index].title!,
|
|
||||||
img: homeBloc.homeItems[index].icon!,
|
|
||||||
onTap: () => homeBloc.homeItems[index].onPress(context),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
|
|
||||||
List<TreeNode> updatedCommunities = [];
|
List<TreeNode> updatedCommunities = [];
|
||||||
List<TreeNode> spacesNodes = [];
|
List<TreeNode> spacesNodes = [];
|
||||||
List<String> communityIds = [];
|
List<String> communityIds = [];
|
||||||
_onLoadCommunityAndSpaces(
|
_onLoadCommunityAndSpaces(
|
||||||
LoadCommunityAndSpacesEvent event, Emitter<UsersState> emit) async {
|
LoadCommunityAndSpacesEvent event, Emitter<UsersState> emit) async {
|
||||||
try {
|
try {
|
||||||
@ -102,12 +102,19 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
);
|
);
|
||||||
|
originalCommunities = updatedCommunities;
|
||||||
emit(const SpacesLoadedState());
|
emit(const SpacesLoadedState());
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(ErrorState('Error loading communities and spaces: $e'));
|
emit(ErrorState('Error loading communities and spaces: $e'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This variable holds the full original list.
|
||||||
|
List<TreeNode> originalCommunities = [];
|
||||||
|
|
||||||
|
// This variable holds the working list that may be filtered.
|
||||||
|
|
||||||
|
// Build tree nodes from your data model.
|
||||||
List<TreeNode> _buildTreeNodes(List<SpaceModel> spaces) {
|
List<TreeNode> _buildTreeNodes(List<SpaceModel> spaces) {
|
||||||
return spaces.map((space) {
|
return spaces.map((space) {
|
||||||
List<TreeNode> childNodes =
|
List<TreeNode> childNodes =
|
||||||
@ -123,12 +130,39 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Optional helper method to deep clone a TreeNode.
|
||||||
|
TreeNode _cloneNode(TreeNode node) {
|
||||||
|
return TreeNode(
|
||||||
|
uuid: node.uuid,
|
||||||
|
title: node.title,
|
||||||
|
isChecked: node.isChecked,
|
||||||
|
isHighlighted: node.isHighlighted,
|
||||||
|
isExpanded: node.isExpanded,
|
||||||
|
children: node.children.map(_cloneNode).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone an entire list of tree nodes.
|
||||||
|
List<TreeNode> _cloneNodes(List<TreeNode> nodes) {
|
||||||
|
return nodes.map(_cloneNode).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Your search event handler.
|
||||||
void searchTreeNode(SearchAnode event, Emitter<UsersState> emit) {
|
void searchTreeNode(SearchAnode event, Emitter<UsersState> emit) {
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
|
|
||||||
|
// If the search term is empty, restore the original list.
|
||||||
if (event.searchTerm!.isEmpty) {
|
if (event.searchTerm!.isEmpty) {
|
||||||
|
// Clear any highlights on the restored copy.
|
||||||
|
updatedCommunities = _cloneNodes(originalCommunities);
|
||||||
_clearHighlights(updatedCommunities);
|
_clearHighlights(updatedCommunities);
|
||||||
} else {
|
} else {
|
||||||
_searchAndHighlightNodes(updatedCommunities, event.searchTerm!);
|
// Start with a fresh clone of the original tree.
|
||||||
|
List<TreeNode> freshClone = _cloneNodes(originalCommunities);
|
||||||
|
|
||||||
|
_searchAndHighlightNodes(freshClone, event.searchTerm!);
|
||||||
|
|
||||||
|
updatedCommunities = _filterNodes(freshClone, event.searchTerm!);
|
||||||
}
|
}
|
||||||
emit(ChangeStatusSteps());
|
emit(ChangeStatusSteps());
|
||||||
}
|
}
|
||||||
@ -155,6 +189,91 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
return anyMatch;
|
return anyMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<TreeNode> _filterNodes(List<TreeNode> nodes, String searchTerm) {
|
||||||
|
List<TreeNode> filteredNodes = [];
|
||||||
|
for (var node in nodes) {
|
||||||
|
bool isMatch =
|
||||||
|
node.title.toLowerCase().contains(searchTerm.toLowerCase());
|
||||||
|
List<TreeNode> filteredChildren = _filterNodes(node.children, searchTerm);
|
||||||
|
if (isMatch || filteredChildren.isNotEmpty) {
|
||||||
|
node.isHighlighted = isMatch;
|
||||||
|
node.children = filteredChildren;
|
||||||
|
filteredNodes.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List<TreeNode> _buildTreeNodes(List<SpaceModel> spaces) {
|
||||||
|
// return spaces.map((space) {
|
||||||
|
// List<TreeNode> childNodes =
|
||||||
|
// space.children.isNotEmpty ? _buildTreeNodes(space.children) : [];
|
||||||
|
// return TreeNode(
|
||||||
|
// uuid: space.uuid!,
|
||||||
|
// title: space.name,
|
||||||
|
// isChecked: false,
|
||||||
|
// isHighlighted: false,
|
||||||
|
// isExpanded: childNodes.isNotEmpty,
|
||||||
|
// children: childNodes,
|
||||||
|
// );
|
||||||
|
// }).toList();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void searchTreeNode(SearchAnode event, Emitter<UsersState> emit) {
|
||||||
|
// emit(UsersLoadingState());
|
||||||
|
// if (event.searchTerm!.isEmpty) {
|
||||||
|
// _clearHighlights(updatedCommunities);
|
||||||
|
// } else {
|
||||||
|
// _searchAndHighlightNodes(updatedCommunities, event.searchTerm!);
|
||||||
|
// updatedCommunities = _filterNodes(updatedCommunities, event.searchTerm!);
|
||||||
|
// }
|
||||||
|
// emit(ChangeStatusSteps());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void _clearHighlights(List<TreeNode> nodes) {
|
||||||
|
// for (var node in nodes) {
|
||||||
|
// node.isHighlighted = false;
|
||||||
|
// if (node.children.isNotEmpty) {
|
||||||
|
// _clearHighlights(node.children);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// bool _searchAndHighlightNodes(List<TreeNode> nodes, String searchTerm) {
|
||||||
|
// bool anyMatch = false;
|
||||||
|
// for (var node in nodes) {
|
||||||
|
// bool isMatch =
|
||||||
|
// node.title.toLowerCase().contains(searchTerm.toLowerCase());
|
||||||
|
// bool childMatch = _searchAndHighlightNodes(node.children, searchTerm);
|
||||||
|
// node.isHighlighted = isMatch || childMatch;
|
||||||
|
|
||||||
|
// anyMatch = anyMatch || node.isHighlighted;
|
||||||
|
// }
|
||||||
|
// return anyMatch;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// List<TreeNode> _filterNodes(List<TreeNode> nodes, String searchTerm) {
|
||||||
|
// List<TreeNode> filteredNodes = [];
|
||||||
|
// for (var node in nodes) {
|
||||||
|
// // Check if the current node's title contains the search term.
|
||||||
|
// bool isMatch =
|
||||||
|
// node.title.toLowerCase().contains(searchTerm.toLowerCase());
|
||||||
|
|
||||||
|
// // Recursively filter the children.
|
||||||
|
// List<TreeNode> filteredChildren = _filterNodes(node.children, searchTerm);
|
||||||
|
|
||||||
|
// // If the current node is a match or any of its children are, include it.
|
||||||
|
// if (isMatch || filteredChildren.isNotEmpty) {
|
||||||
|
// // Optionally, update any properties (like isHighlighted) if you still need them.
|
||||||
|
// node.isHighlighted = isMatch;
|
||||||
|
// // Replace the children with the filtered ones.
|
||||||
|
// node.children = filteredChildren;
|
||||||
|
// filteredNodes.add(node);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return filteredNodes;
|
||||||
|
// }
|
||||||
|
|
||||||
List<String> selectedIds = [];
|
List<String> selectedIds = [];
|
||||||
|
|
||||||
List<String> getSelectedIds(List<TreeNode> nodes) {
|
List<String> getSelectedIds(List<TreeNode> nodes) {
|
||||||
@ -221,7 +340,7 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
lastName: lastNameController.text,
|
lastName: lastNameController.text,
|
||||||
phoneNumber: phoneController.text,
|
phoneNumber: phoneController.text,
|
||||||
roleUuid: roleSelected,
|
roleUuid: roleSelected,
|
||||||
spaceUuids: selectedIds,
|
spaceUuids: selectedIds,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -251,12 +370,11 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_editInviteUser(EditInviteUsers event, Emitter<UsersState> emit) async {
|
_editInviteUser(EditInviteUsers event, Emitter<UsersState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
List<String> selectedIds = getSelectedIds(updatedCommunities)
|
List<String> selectedIds = getSelectedIds(updatedCommunities)
|
||||||
.where((id) => !communityIds.contains(id))
|
.where((id) => !communityIds.contains(id))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
bool res = await UserPermissionApi().editInviteUser(
|
bool res = await UserPermissionApi().editInviteUser(
|
||||||
|
@ -26,126 +26,126 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
|
|||||||
create: (BuildContext context) => UsersBloc()
|
create: (BuildContext context) => UsersBloc()
|
||||||
..add(const LoadCommunityAndSpacesEvent())
|
..add(const LoadCommunityAndSpacesEvent())
|
||||||
..add(const RoleEvent()),
|
..add(const RoleEvent()),
|
||||||
child: BlocConsumer<UsersBloc, UsersState>(
|
child: BlocConsumer<UsersBloc, UsersState>(listener: (context, state) {
|
||||||
listener: (context, state) {},
|
// print('88888==${state}');
|
||||||
builder: (context, state) {
|
// if (state is SpacesLoadedState) {
|
||||||
final _blocRole = BlocProvider.of<UsersBloc>(context);
|
// print('object');
|
||||||
|
// _blocRole.add(const CheckRoleStepStatus());
|
||||||
|
// }
|
||||||
|
}, builder: (context, state) {
|
||||||
|
final _blocRole = BlocProvider.of<UsersBloc>(context);
|
||||||
|
|
||||||
return Dialog(
|
return Dialog(
|
||||||
child: Container(
|
child: Container(
|
||||||
decoration: const BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(20))),
|
borderRadius: BorderRadius.all(Radius.circular(20))),
|
||||||
width: 900,
|
width: 900,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Title
|
// Title
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.all(8.0),
|
padding: EdgeInsets.all(8.0),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
child: Text(
|
child: Text(
|
||||||
"Add New User",
|
"Add New User",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: ColorsManager.secondaryColor),
|
color: ColorsManager.secondaryColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(20),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildStep1Indicator(1, "Basics", _blocRole),
|
||||||
|
_buildStep2Indicator(2, "Spaces", _blocRole),
|
||||||
|
_buildStep3Indicator(
|
||||||
|
3, "Role & Permissions", _blocRole),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Container(
|
||||||
const Divider(),
|
width: 1,
|
||||||
Expanded(
|
color: ColorsManager.grayBorder,
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.all(20),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
_buildStep1Indicator(1, "Basics", _blocRole),
|
|
||||||
_buildStep2Indicator(2, "Spaces", _blocRole),
|
|
||||||
_buildStep3Indicator(
|
|
||||||
3, "Role & Permissions", _blocRole),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
width: 1,
|
|
||||||
color: ColorsManager.grayBorder,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
flex: 2,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Expanded(
|
|
||||||
child: _getFormContent(),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
const Divider(),
|
flex: 2,
|
||||||
Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(20.0),
|
||||||
child: Row(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
InkWell(
|
const SizedBox(height: 10),
|
||||||
onTap: () {
|
Expanded(
|
||||||
Navigator.of(context).pop();
|
child: _getFormContent(),
|
||||||
},
|
),
|
||||||
child: const Text("Cancel"),
|
const SizedBox(height: 20),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
InkWell(
|
),
|
||||||
onTap: () {
|
|
||||||
_blocRole.add(const CheckEmailEvent());
|
|
||||||
|
|
||||||
setState(() {
|
|
||||||
if (currentStep < 3) {
|
|
||||||
currentStep++;
|
|
||||||
if (currentStep == 2) {
|
|
||||||
_blocRole.add(
|
|
||||||
const CheckStepStatus(isEditUser: false));
|
|
||||||
} else if (currentStep == 3) {
|
|
||||||
_blocRole
|
|
||||||
.add(const CheckSpacesStepStatus());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_blocRole
|
|
||||||
.add(SendInviteUsers(context: context));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Text(
|
|
||||||
currentStep < 3 ? "Next" : "Save",
|
|
||||||
style: TextStyle(
|
|
||||||
color: (_blocRole.isCompleteSpaces == false ||
|
|
||||||
_blocRole.isCompleteBasics ==
|
|
||||||
false ||
|
|
||||||
_blocRole
|
|
||||||
.isCompleteRolePermissions ==
|
|
||||||
false) &&
|
|
||||||
currentStep == 3
|
|
||||||
? ColorsManager.grayColor
|
|
||||||
: ColorsManager.secondaryColor),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
));
|
const Divider(),
|
||||||
}));
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: const Text("Cancel"),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
_blocRole.add(const CheckEmailEvent());
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
if (currentStep < 3) {
|
||||||
|
currentStep++;
|
||||||
|
if (currentStep == 2) {
|
||||||
|
_blocRole.add(
|
||||||
|
const CheckStepStatus(isEditUser: false));
|
||||||
|
} else if (currentStep == 3) {
|
||||||
|
_blocRole.add(const CheckSpacesStepStatus());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_blocRole.add(SendInviteUsers(context: context));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
child: Text(
|
||||||
|
currentStep < 3 ? "Next" : "Save",
|
||||||
|
style: TextStyle(
|
||||||
|
color: (_blocRole.isCompleteSpaces == false ||
|
||||||
|
_blocRole.isCompleteBasics == false ||
|
||||||
|
_blocRole.isCompleteRolePermissions ==
|
||||||
|
false) &&
|
||||||
|
currentStep == 3
|
||||||
|
? ColorsManager.grayColor
|
||||||
|
: ColorsManager.secondaryColor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _getFormContent() {
|
Widget _getFormContent() {
|
||||||
@ -236,12 +236,16 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
currentStep = step;
|
|
||||||
bloc.add(const CheckStepStatus(isEditUser: false));
|
bloc.add(const CheckStepStatus(isEditUser: false));
|
||||||
|
currentStep = step;
|
||||||
|
Future.delayed(const Duration(milliseconds: 500), () {
|
||||||
|
bloc.add(const CheckStepStatus(isEditUser: false));
|
||||||
|
});
|
||||||
if (step3 == 3) {
|
if (step3 == 3) {
|
||||||
bloc.add(const CheckRoleStepStatus());
|
Future.delayed(const Duration(seconds: 1), () {
|
||||||
|
bloc.add(const CheckRoleStepStatus());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -46,117 +46,120 @@ class BasicsView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
Flexible(
|
||||||
width: MediaQuery.of(context).size.width * 0.18,
|
child: SizedBox(
|
||||||
height: MediaQuery.of(context).size.width * 0.08,
|
// width: MediaQuery.of(context).size.width * 0.18,
|
||||||
child: Column(
|
height: MediaQuery.of(context).size.width * 0.08,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
SizedBox(
|
children: [
|
||||||
child: Row(
|
SizedBox(
|
||||||
children: [
|
child: Row(
|
||||||
const Text(
|
children: [
|
||||||
" * ",
|
const Text(
|
||||||
style: TextStyle(
|
" * ",
|
||||||
color: ColorsManager.red,
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.w900,
|
color: ColorsManager.red,
|
||||||
fontSize: 15,
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
Text(
|
'First Name',
|
||||||
'First Name',
|
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
fontSize: 13,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: TextFormField(
|
|
||||||
style:
|
|
||||||
const TextStyle(color: ColorsManager.blackColor),
|
|
||||||
// onChanged: (value) {
|
|
||||||
// Future.delayed(const Duration(milliseconds: 200),
|
|
||||||
// () {
|
|
||||||
// _blocRole.add(const ValidateBasicsStep());
|
|
||||||
// });
|
|
||||||
// },
|
|
||||||
controller: _blocRole.firstNameController,
|
|
||||||
decoration: inputTextFormDeco(
|
|
||||||
hintText: "Enter first name",
|
|
||||||
).copyWith(
|
|
||||||
hintStyle: context.textTheme.bodyMedium?.copyWith(
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
fontSize: 12,
|
|
||||||
color: ColorsManager.textGray),
|
|
||||||
),
|
|
||||||
validator: (value) {
|
|
||||||
if (value == null || value.isEmpty) {
|
|
||||||
return 'Enter first name';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
SizedBox(
|
|
||||||
width: MediaQuery.of(context).size.width * 0.18,
|
|
||||||
height: MediaQuery.of(context).size.width * 0.08,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
SizedBox(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
" * ",
|
|
||||||
style: TextStyle(
|
|
||||||
color: ColorsManager.red,
|
|
||||||
fontWeight: FontWeight.w900,
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text('Last Name',
|
|
||||||
style: context.textTheme.bodyMedium?.copyWith(
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
)),
|
),
|
||||||
],
|
),
|
||||||
)),
|
],
|
||||||
Padding(
|
)),
|
||||||
padding: const EdgeInsets.all(8.0),
|
Padding(
|
||||||
child: TextFormField(
|
padding: const EdgeInsets.all(8.0),
|
||||||
// onChanged: (value) {
|
child: TextFormField(
|
||||||
// Future.delayed(const Duration(milliseconds: 200),
|
style: const TextStyle(
|
||||||
// () {
|
color: ColorsManager.blackColor),
|
||||||
// _blocRole.add(ValidateBasicsStep());
|
// onChanged: (value) {
|
||||||
// });
|
// Future.delayed(const Duration(milliseconds: 200),
|
||||||
// },
|
// () {
|
||||||
controller: _blocRole.lastNameController,
|
// _blocRole.add(const ValidateBasicsStep());
|
||||||
style: const TextStyle(color: Colors.black),
|
// });
|
||||||
decoration:
|
// },
|
||||||
inputTextFormDeco(hintText: "Enter last name")
|
controller: _blocRole.firstNameController,
|
||||||
.copyWith(
|
decoration: inputTextFormDeco(
|
||||||
hintStyle: context
|
hintText: "Enter first name",
|
||||||
.textTheme.bodyMedium
|
).copyWith(
|
||||||
?.copyWith(
|
hintStyle: context.textTheme.bodyMedium?.copyWith(
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: ColorsManager.textGray)),
|
color: ColorsManager.textGray),
|
||||||
validator: (value) {
|
),
|
||||||
if (value == null || value.isEmpty) {
|
validator: (value) {
|
||||||
return 'Enter last name';
|
if (value == null || value.isEmpty) {
|
||||||
}
|
return 'Enter first name';
|
||||||
return null;
|
}
|
||||||
},
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Flexible(
|
||||||
|
child: SizedBox(
|
||||||
|
// width: MediaQuery.of(context).size.width * 0.18,
|
||||||
|
height: MediaQuery.of(context).size.width * 0.08,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
" * ",
|
||||||
|
style: TextStyle(
|
||||||
|
color: ColorsManager.red,
|
||||||
|
fontWeight: FontWeight.w900,
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text('Last Name',
|
||||||
|
style: context.textTheme.bodyMedium?.copyWith(
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 13,
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: TextFormField(
|
||||||
|
// onChanged: (value) {
|
||||||
|
// Future.delayed(const Duration(milliseconds: 200),
|
||||||
|
// () {
|
||||||
|
// _blocRole.add(ValidateBasicsStep());
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
controller: _blocRole.lastNameController,
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
decoration:
|
||||||
|
inputTextFormDeco(hintText: "Enter last name")
|
||||||
|
.copyWith(
|
||||||
|
hintStyle: context.textTheme.bodyMedium
|
||||||
|
?.copyWith(
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
fontSize: 12,
|
||||||
|
color: ColorsManager.textGray)),
|
||||||
|
validator: (value) {
|
||||||
|
if (value == null || value.isEmpty) {
|
||||||
|
return 'Enter last name';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -27,7 +27,16 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
List<RolesUserModel> users = [];
|
List<RolesUserModel> users = [];
|
||||||
List<RolesUserModel> initialUsers = [];
|
List<RolesUserModel> initialUsers = [];
|
||||||
|
|
||||||
|
List<RolesUserModel> totalUsersCount = [];
|
||||||
String currentSortOrder = '';
|
String currentSortOrder = '';
|
||||||
|
|
||||||
|
String currentSortJopTitle = '';
|
||||||
|
String currentSortRole = '';
|
||||||
|
String currentSortCreatedDate = '';
|
||||||
|
String currentSortStatus = '';
|
||||||
|
String currentSortCreatedBy = '';
|
||||||
|
|
||||||
String currentSortOrderDate = '';
|
String currentSortOrderDate = '';
|
||||||
List<String> roleTypes = [];
|
List<String> roleTypes = [];
|
||||||
List<String> jobTitle = [];
|
List<String> jobTitle = [];
|
||||||
@ -60,6 +69,7 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
jobTitle = jobTitle.toSet().toList();
|
jobTitle = jobTitle.toSet().toList();
|
||||||
createdBy = createdBy.toSet().toList();
|
createdBy = createdBy.toSet().toList();
|
||||||
_handlePageChange(ChangePage(1), emit);
|
_handlePageChange(ChangePage(1), emit);
|
||||||
|
totalUsersCount = initialUsers;
|
||||||
add(ChangePage(currentPage));
|
add(ChangePage(currentPage));
|
||||||
emit(UsersLoadedState(users: users));
|
emit(UsersLoadedState(users: users));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -91,26 +101,6 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
event.userId, event.newStatus == "disabled" ? false : true);
|
event.userId, event.newStatus == "disabled" ? false : true);
|
||||||
if (res == true) {
|
if (res == true) {
|
||||||
add(const GetUsers());
|
add(const GetUsers());
|
||||||
// users = users.map((user) {
|
|
||||||
// if (user.uuid == event.userId) {
|
|
||||||
// return RolesUserModel(
|
|
||||||
// uuid: user.uuid,
|
|
||||||
// createdAt: user.createdAt,
|
|
||||||
// email: user.email,
|
|
||||||
// firstName: user.firstName,
|
|
||||||
// lastName: user.lastName,
|
|
||||||
// roleType: user.roleType,
|
|
||||||
// status: event.newStatus,
|
|
||||||
// isEnabled: event.newStatus == "disabled" ? false : true,
|
|
||||||
// invitedBy: user.invitedBy,
|
|
||||||
// phoneNumber: user.phoneNumber,
|
|
||||||
// jobTitle: user.jobTitle,
|
|
||||||
// createdDate: user.createdDate,
|
|
||||||
// createdTime: user.createdTime,
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// return user;
|
|
||||||
// }).toList();
|
|
||||||
}
|
}
|
||||||
emit(UsersLoadedState(users: users));
|
emit(UsersLoadedState(users: users));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -128,7 +118,6 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
currentSortOrder = "";
|
currentSortOrder = "";
|
||||||
users = List.from(users);
|
users = List.from(users);
|
||||||
emit(UsersLoadedState(users: users));
|
|
||||||
} else {
|
} else {
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
currentSortOrder = "Asc";
|
currentSortOrder = "Asc";
|
||||||
@ -136,8 +125,12 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
.toString()
|
.toString()
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.compareTo(b.firstName.toString().toLowerCase()));
|
.compareTo(b.firstName.toString().toLowerCase()));
|
||||||
emit(UsersLoadedState(users: users));
|
|
||||||
}
|
}
|
||||||
|
currentSortJopTitle = '';
|
||||||
|
currentSortCreatedDate = '';
|
||||||
|
currentSortStatus = '';
|
||||||
|
currentSortCreatedBy = '';
|
||||||
|
emit(UsersLoadedState(users: users));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleSortUsersByNameDesc(
|
void _toggleSortUsersByNameDesc(
|
||||||
@ -150,13 +143,16 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
currentSortOrder = "";
|
currentSortOrder = "";
|
||||||
users = List.from(initialUsers);
|
users = List.from(initialUsers);
|
||||||
emit(UsersLoadedState(users: users));
|
|
||||||
} else {
|
} else {
|
||||||
emit(UsersLoadingState());
|
emit(UsersLoadingState());
|
||||||
currentSortOrder = "Desc";
|
currentSortOrder = "Desc";
|
||||||
users.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
users.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
||||||
emit(UsersLoadedState(users: users));
|
|
||||||
}
|
}
|
||||||
|
currentSortJopTitle = '';
|
||||||
|
currentSortCreatedDate = '';
|
||||||
|
currentSortStatus = '';
|
||||||
|
currentSortCreatedBy = '';
|
||||||
|
emit(UsersLoadedState(users: users));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _toggleSortUsersByDateNewestToOldest(
|
void _toggleSortUsersByDateNewestToOldest(
|
||||||
@ -222,6 +218,7 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
Future<void> _searchUsers(
|
Future<void> _searchUsers(
|
||||||
SearchUsers event, Emitter<UserTableState> emit) async {
|
SearchUsers event, Emitter<UserTableState> emit) async {
|
||||||
try {
|
try {
|
||||||
|
emit(TableSearch());
|
||||||
final query = event.query.toLowerCase();
|
final query = event.query.toLowerCase();
|
||||||
final filteredUsers = initialUsers.where((user) {
|
final filteredUsers = initialUsers.where((user) {
|
||||||
final fullName = "${user.firstName} ${user.lastName}".toLowerCase();
|
final fullName = "${user.firstName} ${user.lastName}".toLowerCase();
|
||||||
@ -250,7 +247,8 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handlePageChange(ChangePage event, Emitter<UserTableState> emit) {
|
void _handlePageChange(ChangePage event, Emitter<UserTableState> emit) {
|
||||||
const itemsPerPage = 10;
|
currentPage = event.pageNumber;
|
||||||
|
const itemsPerPage = 20;
|
||||||
final startIndex = (event.pageNumber - 1) * itemsPerPage;
|
final startIndex = (event.pageNumber - 1) * itemsPerPage;
|
||||||
final endIndex = startIndex + itemsPerPage;
|
final endIndex = startIndex + itemsPerPage;
|
||||||
if (startIndex >= users.length) {
|
if (startIndex >= users.length) {
|
||||||
@ -287,9 +285,15 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
} else if (event.sortOrder == "Desc") {
|
} else if (event.sortOrder == "Desc") {
|
||||||
currentSortOrder = "Desc";
|
currentSortOrder = "Desc";
|
||||||
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
||||||
} else {
|
} else {}
|
||||||
currentSortOrder = "";
|
currentSortOrder = "";
|
||||||
}
|
currentSortCreatedDate = '';
|
||||||
|
currentSortStatus = '';
|
||||||
|
currentSortCreatedBy = '';
|
||||||
|
currentSortJopTitle = '';
|
||||||
|
currentSortOrderDate = "";
|
||||||
|
|
||||||
|
totalUsersCount = filteredUsers;
|
||||||
|
|
||||||
emit(UsersLoadedState(users: filteredUsers));
|
emit(UsersLoadedState(users: filteredUsers));
|
||||||
}
|
}
|
||||||
@ -311,9 +315,16 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
} else if (event.sortOrder == "Desc") {
|
} else if (event.sortOrder == "Desc") {
|
||||||
currentSortOrder = "Desc";
|
currentSortOrder = "Desc";
|
||||||
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
||||||
} else {
|
} else {}
|
||||||
currentSortOrder = "";
|
currentSortOrder = "";
|
||||||
}
|
currentSortCreatedDate = '';
|
||||||
|
currentSortStatus = '';
|
||||||
|
currentSortCreatedBy = '';
|
||||||
|
currentSortRole = '';
|
||||||
|
currentSortOrderDate = "";
|
||||||
|
|
||||||
|
totalUsersCount = filteredUsers;
|
||||||
|
|
||||||
emit(UsersLoadedState(users: filteredUsers));
|
emit(UsersLoadedState(users: filteredUsers));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,9 +346,15 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
} else if (event.sortOrder == "Desc") {
|
} else if (event.sortOrder == "Desc") {
|
||||||
currentSortOrder = "Desc";
|
currentSortOrder = "Desc";
|
||||||
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
||||||
} else {
|
} else {}
|
||||||
currentSortOrder = "";
|
currentSortOrder = '';
|
||||||
}
|
currentSortRole = '';
|
||||||
|
currentSortCreatedDate = '';
|
||||||
|
currentSortStatus = '';
|
||||||
|
currentSortOrderDate = "";
|
||||||
|
|
||||||
|
totalUsersCount = filteredUsers;
|
||||||
|
|
||||||
emit(UsersLoadedState(users: filteredUsers));
|
emit(UsersLoadedState(users: filteredUsers));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,14 +388,17 @@ class UserTableBloc extends Bloc<UserTableEvent, UserTableState> {
|
|||||||
} else if (event.sortOrder == "Desc") {
|
} else if (event.sortOrder == "Desc") {
|
||||||
currentSortOrder = "Desc";
|
currentSortOrder = "Desc";
|
||||||
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
filteredUsers.sort((a, b) => b.firstName!.compareTo(a.firstName!));
|
||||||
} else {
|
totalUsersCount = filteredUsers;
|
||||||
currentSortOrder = "";
|
} else {}
|
||||||
}
|
currentSortOrder = '';
|
||||||
|
currentSortRole = '';
|
||||||
|
currentSortCreatedDate = '';
|
||||||
|
currentSortCreatedBy = '';
|
||||||
|
currentSortOrderDate = "";
|
||||||
|
|
||||||
emit(UsersLoadedState(users: filteredUsers));
|
emit(UsersLoadedState(users: filteredUsers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _resetAllFilters(Emitter<UserTableState> emit) {
|
void _resetAllFilters(Emitter<UserTableState> emit) {
|
||||||
selectedRoles.clear();
|
selectedRoles.clear();
|
||||||
selectedJobTitles.clear();
|
selectedJobTitles.clear();
|
||||||
|
@ -9,7 +9,10 @@ final class TableInitial extends UserTableState {
|
|||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
final class TableSearch extends UserTableState {
|
||||||
|
@override
|
||||||
|
List<Object> get props => [];
|
||||||
|
}
|
||||||
final class RolesLoadingState extends UserTableState {
|
final class RolesLoadingState extends UserTableState {
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [];
|
List<Object> get props => [];
|
||||||
|
@ -129,9 +129,12 @@ class UsersPage extends StatelessWidget {
|
|||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: searchController,
|
controller: searchController,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context
|
final bloc = context.read<UserTableBloc>();
|
||||||
.read<UserTableBloc>()
|
bloc.add(FilterClearEvent());
|
||||||
.add(SearchUsers(value));
|
bloc.add(SearchUsers(value));
|
||||||
|
if (value == '') {
|
||||||
|
bloc.add(ChangePage(1));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
decoration: textBoxDecoration(radios: 15)!.copyWith(
|
decoration: textBoxDecoration(radios: 15)!.copyWith(
|
||||||
@ -222,7 +225,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
list: _blocRole.jobTitle,
|
list: _blocRole.jobTitle,
|
||||||
context: context,
|
context: context,
|
||||||
checkboxStates: checkboxStates,
|
checkboxStates: checkboxStates,
|
||||||
isSelected: _blocRole.currentSortOrder,
|
isSelected: _blocRole.currentSortJopTitle,
|
||||||
onOkPressed: () {
|
onOkPressed: () {
|
||||||
searchController.clear();
|
searchController.clear();
|
||||||
_blocRole.add(FilterClearEvent());
|
_blocRole.add(FilterClearEvent());
|
||||||
@ -233,14 +236,14 @@ class UsersPage extends StatelessWidget {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
_blocRole.add(FilterUsersByJobEvent(
|
_blocRole.add(FilterUsersByJobEvent(
|
||||||
selectedJob: selectedItems,
|
selectedJob: selectedItems,
|
||||||
sortOrder: _blocRole.currentSortOrder,
|
sortOrder: _blocRole.currentSortJopTitle,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
onSortAtoZ: (v) {
|
onSortAtoZ: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortJopTitle = v;
|
||||||
},
|
},
|
||||||
onSortZtoA: (v) {
|
onSortZtoA: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortJopTitle = v;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -263,7 +266,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
list: _blocRole.roleTypes,
|
list: _blocRole.roleTypes,
|
||||||
context: context,
|
context: context,
|
||||||
checkboxStates: checkboxStates,
|
checkboxStates: checkboxStates,
|
||||||
isSelected: _blocRole.currentSortOrder,
|
isSelected: _blocRole.currentSortRole,
|
||||||
onOkPressed: () {
|
onOkPressed: () {
|
||||||
searchController.clear();
|
searchController.clear();
|
||||||
_blocRole.add(FilterClearEvent());
|
_blocRole.add(FilterClearEvent());
|
||||||
@ -275,13 +278,13 @@ class UsersPage extends StatelessWidget {
|
|||||||
context.read<UserTableBloc>().add(
|
context.read<UserTableBloc>().add(
|
||||||
FilterUsersByRoleEvent(
|
FilterUsersByRoleEvent(
|
||||||
selectedRoles: selectedItems,
|
selectedRoles: selectedItems,
|
||||||
sortOrder: _blocRole.currentSortOrder));
|
sortOrder: _blocRole.currentSortRole));
|
||||||
},
|
},
|
||||||
onSortAtoZ: (v) {
|
onSortAtoZ: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortRole = v;
|
||||||
},
|
},
|
||||||
onSortZtoA: (v) {
|
onSortZtoA: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortRole = v;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -319,7 +322,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
list: _blocRole.createdBy,
|
list: _blocRole.createdBy,
|
||||||
context: context,
|
context: context,
|
||||||
checkboxStates: checkboxStates,
|
checkboxStates: checkboxStates,
|
||||||
isSelected: _blocRole.currentSortOrder,
|
isSelected: _blocRole.currentSortCreatedBy,
|
||||||
onOkPressed: () {
|
onOkPressed: () {
|
||||||
searchController.clear();
|
searchController.clear();
|
||||||
_blocRole.add(FilterClearEvent());
|
_blocRole.add(FilterClearEvent());
|
||||||
@ -330,13 +333,13 @@ class UsersPage extends StatelessWidget {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
_blocRole.add(FilterUsersByCreatedEvent(
|
_blocRole.add(FilterUsersByCreatedEvent(
|
||||||
selectedCreatedBy: selectedItems,
|
selectedCreatedBy: selectedItems,
|
||||||
sortOrder: _blocRole.currentSortOrder));
|
sortOrder: _blocRole.currentSortCreatedBy));
|
||||||
},
|
},
|
||||||
onSortAtoZ: (v) {
|
onSortAtoZ: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortCreatedBy = v;
|
||||||
},
|
},
|
||||||
onSortZtoA: (v) {
|
onSortZtoA: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortCreatedBy = v;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -359,7 +362,7 @@ class UsersPage extends StatelessWidget {
|
|||||||
list: _blocRole.status,
|
list: _blocRole.status,
|
||||||
context: context,
|
context: context,
|
||||||
checkboxStates: checkboxStates,
|
checkboxStates: checkboxStates,
|
||||||
isSelected: _blocRole.currentSortOrder,
|
isSelected: _blocRole.currentSortStatus,
|
||||||
onOkPressed: () {
|
onOkPressed: () {
|
||||||
searchController.clear();
|
searchController.clear();
|
||||||
_blocRole.add(FilterClearEvent());
|
_blocRole.add(FilterClearEvent());
|
||||||
@ -370,13 +373,13 @@ class UsersPage extends StatelessWidget {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
_blocRole.add(FilterUsersByDeActevateEvent(
|
_blocRole.add(FilterUsersByDeActevateEvent(
|
||||||
selectedActivate: selectedItems,
|
selectedActivate: selectedItems,
|
||||||
sortOrder: _blocRole.currentSortOrder));
|
sortOrder: _blocRole.currentSortStatus));
|
||||||
},
|
},
|
||||||
onSortAtoZ: (v) {
|
onSortAtoZ: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortStatus = v;
|
||||||
},
|
},
|
||||||
onSortZtoA: (v) {
|
onSortZtoA: (v) {
|
||||||
_blocRole.currentSortOrder = v;
|
_blocRole.currentSortStatus = v;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -508,12 +511,11 @@ class UsersPage extends StatelessWidget {
|
|||||||
const Icon(Icons.keyboard_double_arrow_right),
|
const Icon(Icons.keyboard_double_arrow_right),
|
||||||
firstPageIcon:
|
firstPageIcon:
|
||||||
const Icon(Icons.keyboard_double_arrow_left),
|
const Icon(Icons.keyboard_double_arrow_left),
|
||||||
totalPages: (_blocRole.users.length /
|
totalPages: (_blocRole.totalUsersCount.length /
|
||||||
_blocRole.itemsPerPage)
|
_blocRole.itemsPerPage)
|
||||||
.ceil(),
|
.ceil(),
|
||||||
currentPage: _blocRole.currentPage,
|
currentPage: _blocRole.currentPage,
|
||||||
onPageChanged: (int pageNumber) {
|
onPageChanged: (int pageNumber) {
|
||||||
_blocRole.currentPage = pageNumber;
|
|
||||||
context
|
context
|
||||||
.read<UserTableBloc>()
|
.read<UserTableBloc>()
|
||||||
.add(ChangePage(pageNumber));
|
.add(ChangePage(pageNumber));
|
||||||
|
@ -816,7 +816,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
|
|||||||
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
|
FutureOr<void> _fetchDevices(FetchDevicesInRoutine event, Emitter<RoutineState> emit) async {
|
||||||
emit(state.copyWith(isLoading: true));
|
emit(state.copyWith(isLoading: true));
|
||||||
try {
|
try {
|
||||||
final devices = await DevicesManagementApi().fetchDevices('', '');
|
final devices = await DevicesManagementApi().fetchDevices(communityId, spaceId);
|
||||||
|
|
||||||
emit(state.copyWith(isLoading: false, devices: devices));
|
emit(state.copyWith(isLoading: false, devices: devices));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -32,7 +32,7 @@ class _RoutinesViewState extends State<RoutinesView> {
|
|||||||
}
|
}
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
const Expanded(
|
||||||
child:
|
child:
|
||||||
// SideSpacesView(
|
// SideSpacesView(
|
||||||
// onSelectAction: (String communityId, String spaceId) {
|
// onSelectAction: (String communityId, String spaceId) {
|
||||||
@ -41,9 +41,7 @@ class _RoutinesViewState extends State<RoutinesView> {
|
|||||||
// // ..add(LoadAutomation(spaceId));
|
// // ..add(LoadAutomation(spaceId));
|
||||||
// },
|
// },
|
||||||
// )
|
// )
|
||||||
SpaceTreeView(
|
SpaceTreeView()),
|
||||||
onSelect: () {},
|
|
||||||
)),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
|
@ -6,8 +6,8 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model
|
|||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
|
|
||||||
class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
||||||
String selectedCommunityId = 'aff21a57-2f91-4e5c-b99b-0182c3ab65a9';
|
String selectedCommunityId = '';
|
||||||
String selectedSpaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
|
String selectedSpaceId = '';
|
||||||
|
|
||||||
SpaceTreeBloc() : super(const SpaceTreeState()) {
|
SpaceTreeBloc() : super(const SpaceTreeState()) {
|
||||||
on<InitialEvent>(_fetchSpaces);
|
on<InitialEvent>(_fetchSpaces);
|
||||||
@ -87,7 +87,6 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
List.from(state.selectedCommunities.toSet().toList());
|
List.from(state.selectedCommunities.toSet().toList());
|
||||||
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
||||||
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
||||||
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
|
|
||||||
|
|
||||||
List<String> childrenIds = _getAllChildIds(event.children);
|
List<String> childrenIds = _getAllChildIds(event.children);
|
||||||
|
|
||||||
@ -102,13 +101,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
updatedSoldChecks.removeWhere(childrenIds.contains);
|
updatedSoldChecks.removeWhere(childrenIds.contains);
|
||||||
}
|
}
|
||||||
|
|
||||||
communityAndSpaces[event.communityId] = updatedSelectedSpaces;
|
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
selectedCommunities: updatedSelectedCommunities,
|
selectedCommunities: updatedSelectedCommunities,
|
||||||
selectedSpaces: updatedSelectedSpaces,
|
selectedSpaces: updatedSelectedSpaces,
|
||||||
soldCheck: updatedSoldChecks,
|
soldCheck: updatedSoldChecks));
|
||||||
selectedCommunityAndSpaces: communityAndSpaces));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||||
}
|
}
|
||||||
@ -120,7 +116,6 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
List.from(state.selectedCommunities.toSet().toList());
|
List.from(state.selectedCommunities.toSet().toList());
|
||||||
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
||||||
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
||||||
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
|
|
||||||
|
|
||||||
List<String> childrenIds = _getAllChildIds(event.children);
|
List<String> childrenIds = _getAllChildIds(event.children);
|
||||||
bool isChildSelected = false;
|
bool isChildSelected = false;
|
||||||
@ -171,13 +166,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
communityAndSpaces[event.communityId] = updatedSelectedSpaces;
|
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
selectedCommunities: updatedSelectedCommunities,
|
selectedCommunities: updatedSelectedCommunities,
|
||||||
selectedSpaces: updatedSelectedSpaces,
|
selectedSpaces: updatedSelectedSpaces,
|
||||||
soldCheck: updatedSoldChecks,
|
soldCheck: updatedSoldChecks));
|
||||||
selectedCommunityAndSpaces: communityAndSpaces));
|
|
||||||
emit(state.copyWith(selectedSpaces: updatedSelectedSpaces));
|
emit(state.copyWith(selectedSpaces: updatedSelectedSpaces));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||||
|
@ -2,7 +2,6 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
|
|
||||||
class SpaceTreeState extends Equatable {
|
class SpaceTreeState extends Equatable {
|
||||||
final Map<String, List<String>> selectedCommunityAndSpaces;
|
|
||||||
final List<CommunityModel> communityList;
|
final List<CommunityModel> communityList;
|
||||||
final List<CommunityModel> filteredCommunity;
|
final List<CommunityModel> filteredCommunity;
|
||||||
final List<String> expandedCommunities;
|
final List<String> expandedCommunities;
|
||||||
@ -20,8 +19,7 @@ class SpaceTreeState extends Equatable {
|
|||||||
this.selectedCommunities = const [],
|
this.selectedCommunities = const [],
|
||||||
this.selectedSpaces = const [],
|
this.selectedSpaces = const [],
|
||||||
this.soldCheck = const [],
|
this.soldCheck = const [],
|
||||||
this.isSearching = false,
|
this.isSearching = false});
|
||||||
this.selectedCommunityAndSpaces = const {}});
|
|
||||||
|
|
||||||
SpaceTreeState copyWith(
|
SpaceTreeState copyWith(
|
||||||
{List<CommunityModel>? communitiesList,
|
{List<CommunityModel>? communitiesList,
|
||||||
@ -31,8 +29,7 @@ class SpaceTreeState extends Equatable {
|
|||||||
List<String>? selectedCommunities,
|
List<String>? selectedCommunities,
|
||||||
List<String>? selectedSpaces,
|
List<String>? selectedSpaces,
|
||||||
List<String>? soldCheck,
|
List<String>? soldCheck,
|
||||||
bool? isSearching,
|
bool? isSearching}) {
|
||||||
Map<String, List<String>>? selectedCommunityAndSpaces}) {
|
|
||||||
return SpaceTreeState(
|
return SpaceTreeState(
|
||||||
communityList: communitiesList ?? this.communityList,
|
communityList: communitiesList ?? this.communityList,
|
||||||
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
||||||
@ -41,8 +38,7 @@ class SpaceTreeState extends Equatable {
|
|||||||
selectedCommunities: selectedCommunities ?? this.selectedCommunities,
|
selectedCommunities: selectedCommunities ?? this.selectedCommunities,
|
||||||
selectedSpaces: selectedSpaces ?? this.selectedSpaces,
|
selectedSpaces: selectedSpaces ?? this.selectedSpaces,
|
||||||
soldCheck: soldCheck ?? this.soldCheck,
|
soldCheck: soldCheck ?? this.soldCheck,
|
||||||
isSearching: isSearching ?? this.isSearching,
|
isSearching: isSearching ?? this.isSearching);
|
||||||
selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -54,8 +50,7 @@ class SpaceTreeState extends Equatable {
|
|||||||
selectedCommunities,
|
selectedCommunities,
|
||||||
selectedSpaces,
|
selectedSpaces,
|
||||||
soldCheck,
|
soldCheck,
|
||||||
isSearching,
|
isSearching
|
||||||
selectedCommunityAndSpaces
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,7 @@ import 'package:syncrow_web/utils/color_manager.dart';
|
|||||||
import 'package:syncrow_web/utils/style.dart';
|
import 'package:syncrow_web/utils/style.dart';
|
||||||
|
|
||||||
class SpaceTreeView extends StatelessWidget {
|
class SpaceTreeView extends StatelessWidget {
|
||||||
final Function onSelect;
|
const SpaceTreeView({super.key});
|
||||||
const SpaceTreeView({required this.onSelect, super.key});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -65,8 +64,6 @@ class SpaceTreeView extends StatelessWidget {
|
|||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
context.read<SpaceTreeBloc>().add(
|
context.read<SpaceTreeBloc>().add(
|
||||||
OnCommunitySelected(community.uuid, community.spaces));
|
OnCommunitySelected(community.uuid, community.spaces));
|
||||||
|
|
||||||
onSelect();
|
|
||||||
},
|
},
|
||||||
children: community.spaces.map((space) {
|
children: community.spaces.map((space) {
|
||||||
return CustomExpansionTileSpaceTree(
|
return CustomExpansionTileSpaceTree(
|
||||||
@ -75,7 +72,6 @@ class SpaceTreeView extends StatelessWidget {
|
|||||||
onItemSelected: () {
|
onItemSelected: () {
|
||||||
context.read<SpaceTreeBloc>().add(OnSpaceSelected(
|
context.read<SpaceTreeBloc>().add(OnSpaceSelected(
|
||||||
community.uuid, space.uuid ?? '', space.children));
|
community.uuid, space.uuid ?? '', space.children));
|
||||||
onSelect();
|
|
||||||
},
|
},
|
||||||
onExpansionChanged: () {
|
onExpansionChanged: () {
|
||||||
context.read<SpaceTreeBloc>().add(
|
context.read<SpaceTreeBloc>().add(
|
||||||
@ -113,7 +109,6 @@ class SpaceTreeView extends StatelessWidget {
|
|||||||
context
|
context
|
||||||
.read<SpaceTreeBloc>()
|
.read<SpaceTreeBloc>()
|
||||||
.add(OnSpaceSelected(communityId, child.uuid ?? '', child.children));
|
.add(OnSpaceSelected(communityId, child.uuid ?? '', child.children));
|
||||||
onSelect();
|
|
||||||
},
|
},
|
||||||
onExpansionChanged: () {
|
onExpansionChanged: () {
|
||||||
context.read<SpaceTreeBloc>().add(OnSpaceExpanded(communityId, child.uuid ?? ''));
|
context.read<SpaceTreeBloc>().add(OnSpaceExpanded(communityId, child.uuid ?? ''));
|
||||||
|
@ -87,7 +87,6 @@ class SpaceManagementBloc
|
|||||||
prevSpaceModels = List<SpaceTemplateModel>.from(
|
prevSpaceModels = List<SpaceTemplateModel>.from(
|
||||||
(previousState as dynamic).spaceModels ?? [],
|
(previousState as dynamic).spaceModels ?? [],
|
||||||
);
|
);
|
||||||
allSpaces.addAll(prevSpaceModels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevSpaceModels.isEmpty) {
|
if (prevSpaceModels.isEmpty) {
|
||||||
@ -315,6 +314,7 @@ class SpaceManagementBloc
|
|||||||
SelectSpaceEvent event,
|
SelectSpaceEvent event,
|
||||||
Emitter<SpaceManagementState> emit,
|
Emitter<SpaceManagementState> emit,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
_handleCommunitySpaceStateUpdate(
|
_handleCommunitySpaceStateUpdate(
|
||||||
emit: emit,
|
emit: emit,
|
||||||
selectedCommunity: event.selectedCommunity,
|
selectedCommunity: event.selectedCommunity,
|
||||||
|
@ -64,11 +64,11 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
|||||||
);
|
);
|
||||||
} else if (state is SpaceModelLoaded) {
|
} else if (state is SpaceModelLoaded) {
|
||||||
return LoadedSpaceView(
|
return LoadedSpaceView(
|
||||||
communities: state.communities,
|
communities: state.communities,
|
||||||
products: state.products,
|
products: state.products,
|
||||||
spaceModels: state.spaceModels,
|
spaceModels: state.spaceModels,
|
||||||
shouldNavigateToSpaceModelPage: true,
|
shouldNavigateToSpaceModelPage: true,
|
||||||
);
|
);
|
||||||
} else if (state is SpaceManagementError) {
|
} else if (state is SpaceManagementError) {
|
||||||
return Center(child: Text('Error: ${state.errorMessage}'));
|
return Center(child: Text('Error: ${state.errorMessage}'));
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/curved_li
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/duplicate_process_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_card_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_card_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_container_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_container_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/helper/connection_helper.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/helper/space_helper.dart';
|
import 'package:syncrow_web/pages/spaces_management/helper/space_helper.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.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/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
@ -133,7 +131,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
communities: widget.communities,
|
communities: widget.communities,
|
||||||
communityName: widget.selectedCommunity?.name,
|
communityName: widget.selectedCommunity?.name,
|
||||||
community: widget.selectedCommunity,
|
community: widget.selectedCommunity,
|
||||||
isSave: SpaceHelper.isSave(spaces),
|
isSave: isSave(spaces),
|
||||||
isEditingName: isEditingName,
|
isEditingName: isEditingName,
|
||||||
nameController: _nameController,
|
nameController: _nameController,
|
||||||
onSave: _saveSpaces,
|
onSave: _saveSpaces,
|
||||||
@ -178,8 +176,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
children: [
|
children: [
|
||||||
for (var connection in connections)
|
for (var connection in connections)
|
||||||
Opacity(
|
Opacity(
|
||||||
opacity: ConnectionHelper.isHighlightedConnection(
|
opacity: _isHighlightedConnection(connection)
|
||||||
connection, widget.selectedSpace)
|
|
||||||
? 1.0
|
? 1.0
|
||||||
: 0.3, // Adjust opacity
|
: 0.3, // Adjust opacity
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
@ -212,8 +209,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
},
|
},
|
||||||
buildSpaceContainer: (int index) {
|
buildSpaceContainer: (int index) {
|
||||||
final bool isHighlighted =
|
final bool isHighlighted =
|
||||||
SpaceHelper.isHighlightedSpace(
|
_isHighlightedSpace(spaces[index]);
|
||||||
spaces[index], widget.selectedSpace);
|
|
||||||
|
|
||||||
return Opacity(
|
return Opacity(
|
||||||
opacity: isHighlighted ? 1.0 : 0.3,
|
opacity: isHighlighted ? 1.0 : 0.3,
|
||||||
@ -299,8 +295,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
return CreateSpaceDialog(
|
return CreateSpaceDialog(
|
||||||
products: widget.products,
|
products: widget.products,
|
||||||
spaceModels: widget.spaceModels,
|
spaceModels: widget.spaceModels,
|
||||||
allTags:
|
allTags: _getAllTagValues(spaces),
|
||||||
TagHelper.getAllTagValues(widget.communities, widget.spaceModels),
|
|
||||||
parentSpace: parentIndex != null ? spaces[parentIndex] : null,
|
parentSpace: parentIndex != null ? spaces[parentIndex] : null,
|
||||||
onCreateSpace: (String name,
|
onCreateSpace: (String name,
|
||||||
String icon,
|
String icon,
|
||||||
@ -311,7 +306,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
// Set the first space in the center or use passed position
|
// Set the first space in the center or use passed position
|
||||||
Offset centerPosition =
|
Offset centerPosition =
|
||||||
position ?? ConnectionHelper.getCenterPosition(screenSize);
|
position ?? _getCenterPosition(screenSize);
|
||||||
SpaceModel newSpace = SpaceModel(
|
SpaceModel newSpace = SpaceModel(
|
||||||
name: name,
|
name: name,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
@ -363,8 +358,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
tags: widget.selectedSpace?.tags,
|
tags: widget.selectedSpace?.tags,
|
||||||
subspaces: widget.selectedSpace?.subspaces,
|
subspaces: widget.selectedSpace?.subspaces,
|
||||||
isEdit: true,
|
isEdit: true,
|
||||||
allTags: TagHelper.getAllTagValues(
|
allTags: _getAllTagValues(spaces),
|
||||||
widget.communities, widget.spaceModels),
|
|
||||||
onCreateSpace: (String name,
|
onCreateSpace: (String name,
|
||||||
String icon,
|
String icon,
|
||||||
List<SelectedProduct> selectedProducts,
|
List<SelectedProduct> selectedProducts,
|
||||||
@ -533,6 +527,17 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _isHighlightedSpace(SpaceModel space) {
|
||||||
|
final selectedSpace = widget.selectedSpace;
|
||||||
|
if (selectedSpace == null) return true;
|
||||||
|
|
||||||
|
return space == selectedSpace ||
|
||||||
|
selectedSpace.parent?.internalId == space.internalId ||
|
||||||
|
selectedSpace.children
|
||||||
|
?.any((child) => child.internalId == space.internalId) ==
|
||||||
|
true;
|
||||||
|
}
|
||||||
|
|
||||||
void _deselectSpace(BuildContext context) {
|
void _deselectSpace(BuildContext context) {
|
||||||
context.read<SpaceManagementBloc>().add(
|
context.read<SpaceManagementBloc>().add(
|
||||||
SelectSpaceEvent(
|
SelectSpaceEvent(
|
||||||
@ -540,6 +545,28 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _isHighlightedConnection(Connection connection) {
|
||||||
|
if (widget.selectedSpace == null) return true;
|
||||||
|
|
||||||
|
return connection.startSpace == widget.selectedSpace ||
|
||||||
|
connection.endSpace == widget.selectedSpace;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset _getCenterPosition(Size screenSize) {
|
||||||
|
return Offset(
|
||||||
|
screenSize.width / 2 - 260,
|
||||||
|
screenSize.height / 2 - 200,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSave(List<SpaceModel> spaces) {
|
||||||
|
return spaces.isNotEmpty &&
|
||||||
|
spaces.any((space) =>
|
||||||
|
space.status == SpaceStatus.newSpace ||
|
||||||
|
space.status == SpaceStatus.modified ||
|
||||||
|
space.status == SpaceStatus.deleted);
|
||||||
|
}
|
||||||
|
|
||||||
void _onDuplicate(BuildContext parentContext) {
|
void _onDuplicate(BuildContext parentContext) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
@ -625,10 +652,11 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
const double horizontalGap = 200.0;
|
const double horizontalGap = 200.0;
|
||||||
const double verticalGap = 100.0;
|
const double verticalGap = 100.0;
|
||||||
|
|
||||||
|
final Map<String, int> nameCounters = {};
|
||||||
|
|
||||||
SpaceModel duplicateRecursive(SpaceModel original, Offset parentPosition,
|
SpaceModel duplicateRecursive(SpaceModel original, Offset parentPosition,
|
||||||
SpaceModel? duplicatedParent) {
|
SpaceModel? duplicatedParent) {
|
||||||
Offset newPosition =
|
Offset newPosition = parentPosition + Offset(horizontalGap, 0);
|
||||||
Offset(parentPosition.dx + horizontalGap, original.position.dy);
|
|
||||||
|
|
||||||
while (spaces.any((s) =>
|
while (spaces.any((s) =>
|
||||||
(s.position - newPosition).distance < horizontalGap &&
|
(s.position - newPosition).distance < horizontalGap &&
|
||||||
@ -639,16 +667,6 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
final duplicatedName =
|
final duplicatedName =
|
||||||
SpaceHelper.generateUniqueSpaceName(original.name, spaces);
|
SpaceHelper.generateUniqueSpaceName(original.name, spaces);
|
||||||
|
|
||||||
final List<SubspaceModel>? duplicatedSubspaces;
|
|
||||||
final List<Tag>? duplicatedTags;
|
|
||||||
if (original.spaceModel != null) {
|
|
||||||
duplicatedTags = [];
|
|
||||||
duplicatedSubspaces = [];
|
|
||||||
} else {
|
|
||||||
duplicatedTags = original.tags;
|
|
||||||
duplicatedSubspaces = original.subspaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
final duplicated = SpaceModel(
|
final duplicated = SpaceModel(
|
||||||
name: duplicatedName,
|
name: duplicatedName,
|
||||||
icon: original.icon,
|
icon: original.icon,
|
||||||
@ -658,8 +676,8 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
status: SpaceStatus.newSpace,
|
status: SpaceStatus.newSpace,
|
||||||
parent: duplicatedParent,
|
parent: duplicatedParent,
|
||||||
spaceModel: original.spaceModel,
|
spaceModel: original.spaceModel,
|
||||||
subspaces: duplicatedSubspaces,
|
subspaces: original.subspaces,
|
||||||
tags: duplicatedTags,
|
tags: original.tags,
|
||||||
);
|
);
|
||||||
|
|
||||||
originalToDuplicate[original] = duplicated;
|
originalToDuplicate[original] = duplicated;
|
||||||
@ -672,7 +690,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
final newConnection = Connection(
|
final newConnection = Connection(
|
||||||
startSpace: duplicatedParent,
|
startSpace: duplicatedParent,
|
||||||
endSpace: duplicated,
|
endSpace: duplicated,
|
||||||
direction: original.incomingConnection?.direction ?? 'down',
|
direction: "down",
|
||||||
);
|
);
|
||||||
connections.add(newConnection);
|
connections.add(newConnection);
|
||||||
duplicated.incomingConnection = newConnection;
|
duplicated.incomingConnection = newConnection;
|
||||||
@ -711,8 +729,10 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
child.incomingConnection?.direction == "down" ?? false;
|
child.incomingConnection?.direction == "down" ?? false;
|
||||||
|
|
||||||
if (isDownDirection && childrenWithDownDirection.length == 1) {
|
if (isDownDirection && childrenWithDownDirection.length == 1) {
|
||||||
|
// Place the only "down" child vertically aligned with the parent
|
||||||
childStartPosition = duplicated.position + Offset(0, verticalGap);
|
childStartPosition = duplicated.position + Offset(0, verticalGap);
|
||||||
} else if (!isDownDirection) {
|
} else if (!isDownDirection) {
|
||||||
|
// Position children with other directions horizontally
|
||||||
childStartPosition = duplicated.position + Offset(horizontalGap, 0);
|
childStartPosition = duplicated.position + Offset(horizontalGap, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -733,4 +753,14 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
duplicateRecursive(space, space.position, duplicatedParent);
|
duplicateRecursive(space, space.position, duplicatedParent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _getAllTagValues(List<SpaceModel> spaces) {
|
||||||
|
final List<String> allTags = [];
|
||||||
|
for (final space in spaces) {
|
||||||
|
if (space.tags != null) {
|
||||||
|
allTags.addAll(space.listAllTagValues());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allTags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart';
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/dialogs/icon_selection_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag/views/assign_tag_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace/views/create_subspace_model_dialog.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/helper/space_helper.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart';
|
import 'package:syncrow_web/pages/spaces_management/helper/tag_helper.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/link_space_model/view/link_space_model_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/link_space_model/view/link_space_model_dialog.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';
|
||||||
@ -84,22 +83,13 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
widget.selectedProducts.isNotEmpty ? widget.selectedProducts : [];
|
widget.selectedProducts.isNotEmpty ? widget.selectedProducts : [];
|
||||||
isOkButtonEnabled =
|
isOkButtonEnabled =
|
||||||
enteredName.isNotEmpty || nameController.text.isNotEmpty;
|
enteredName.isNotEmpty || nameController.text.isNotEmpty;
|
||||||
if (widget.currentSpaceModel != null) {
|
tags = widget.tags ?? [];
|
||||||
subspaces = [];
|
subspaces = widget.subspaces ?? [];
|
||||||
tags = [];
|
|
||||||
} else {
|
|
||||||
tags = widget.tags ?? [];
|
|
||||||
subspaces = widget.subspaces ?? [];
|
|
||||||
}
|
|
||||||
selectedSpaceModel = widget.currentSpaceModel;
|
selectedSpaceModel = widget.currentSpaceModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool isSpaceModelDisabled = (tags != null && tags!.isNotEmpty ||
|
|
||||||
subspaces != null && subspaces!.isNotEmpty);
|
|
||||||
bool isTagsAndSubspaceModelDisabled = (selectedSpaceModel != null);
|
|
||||||
|
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
title: widget.isEdit
|
title: widget.isEdit
|
||||||
@ -178,7 +168,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
isNameFieldInvalid = value.isEmpty;
|
isNameFieldInvalid = value.isEmpty;
|
||||||
|
|
||||||
if (!isNameFieldInvalid) {
|
if (!isNameFieldInvalid) {
|
||||||
if (SpaceHelper.isNameConflict(value, widget.parentSpace, widget.editSpace)) {
|
if (_isNameConflict(value)) {
|
||||||
isNameFieldExist = true;
|
isNameFieldExist = true;
|
||||||
isOkButtonEnabled = false;
|
isOkButtonEnabled = false;
|
||||||
} else {
|
} else {
|
||||||
@ -245,14 +235,11 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
isSpaceModelDisabled
|
_showLinkSpaceModelDialog(context);
|
||||||
? null
|
|
||||||
: _showLinkSpaceModelDialog(context);
|
|
||||||
},
|
},
|
||||||
child: ButtonContentWidget(
|
child: const ButtonContentWidget(
|
||||||
svgAssets: Assets.link,
|
svgAssets: Assets.link,
|
||||||
label: 'Link a space model',
|
label: 'Link a space model',
|
||||||
disabled: isSpaceModelDisabled,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
@ -341,15 +328,12 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
overlayColor: ColorsManager.transparentColor,
|
overlayColor: ColorsManager.transparentColor,
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
isTagsAndSubspaceModelDisabled
|
_showSubSpaceDialog(context, enteredName, [],
|
||||||
? null
|
false, widget.products, subspaces);
|
||||||
: _showSubSpaceDialog(context, enteredName,
|
|
||||||
[], false, widget.products, subspaces);
|
|
||||||
},
|
},
|
||||||
child: ButtonContentWidget(
|
child: const ButtonContentWidget(
|
||||||
icon: Icons.add,
|
icon: Icons.add,
|
||||||
label: 'Create Sub Space',
|
label: 'Create Sub Space',
|
||||||
disabled: isTagsAndSubspaceModelDisabled,
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: SizedBox(
|
: SizedBox(
|
||||||
@ -477,7 +461,6 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
builder: (context) => AssignTagDialog(
|
builder: (context) => AssignTagDialog(
|
||||||
products: widget.products,
|
products: widget.products,
|
||||||
subspaces: subspaces,
|
subspaces: subspaces,
|
||||||
allTags: widget.allTags,
|
|
||||||
addedProducts: TagHelper
|
addedProducts: TagHelper
|
||||||
.createInitialSelectedProductsForTags(
|
.createInitialSelectedProductsForTags(
|
||||||
tags ?? [], subspaces),
|
tags ?? [], subspaces),
|
||||||
@ -503,22 +486,19 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
)
|
)
|
||||||
: TextButton(
|
: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
isTagsAndSubspaceModelDisabled
|
_showTagCreateDialog(
|
||||||
? null
|
context,
|
||||||
: _showTagCreateDialog(
|
enteredName,
|
||||||
context,
|
widget.isEdit,
|
||||||
enteredName,
|
widget.products,
|
||||||
widget.isEdit,
|
);
|
||||||
widget.products,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
child: ButtonContentWidget(
|
child: const ButtonContentWidget(
|
||||||
icon: Icons.add,
|
icon: Icons.add,
|
||||||
label: 'Add Devices',
|
label: 'Add Devices',
|
||||||
disabled: isTagsAndSubspaceModelDisabled,
|
|
||||||
))
|
))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -592,7 +572,26 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _isNameConflict(String value) {
|
||||||
|
final parentSpace = widget.parentSpace;
|
||||||
|
final editSpace = widget.editSpace;
|
||||||
|
final siblings = parentSpace?.children
|
||||||
|
.where((child) => child.uuid != editSpace?.uuid)
|
||||||
|
.toList() ??
|
||||||
|
[];
|
||||||
|
final siblingConflict = siblings.any((child) => child.name == value);
|
||||||
|
final parentConflict =
|
||||||
|
parentSpace?.name == value && parentSpace?.uuid != editSpace?.uuid;
|
||||||
|
final parentOfEditSpaceConflict = editSpace?.parent?.name == value &&
|
||||||
|
editSpace?.parent?.uuid != editSpace?.uuid;
|
||||||
|
final childConflict =
|
||||||
|
editSpace?.children.any((child) => child.name == value) ?? false;
|
||||||
|
return siblingConflict ||
|
||||||
|
parentConflict ||
|
||||||
|
parentOfEditSpaceConflict ||
|
||||||
|
childConflict;
|
||||||
|
}
|
||||||
|
|
||||||
void _showLinkSpaceModelDialog(BuildContext context) {
|
void _showLinkSpaceModelDialog(BuildContext context) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -57,7 +57,6 @@ class AssignTagBloc extends Bloc<AssignTagEvent, AssignTagState> {
|
|||||||
if (currentState is AssignTagLoaded && currentState.tags.isNotEmpty) {
|
if (currentState is AssignTagLoaded && currentState.tags.isNotEmpty) {
|
||||||
final tags = List<Tag>.from(currentState.tags);
|
final tags = List<Tag>.from(currentState.tags);
|
||||||
tags[event.index].tag = event.tag;
|
tags[event.index].tag = event.tag;
|
||||||
|
|
||||||
emit(AssignTagLoaded(
|
emit(AssignTagLoaded(
|
||||||
tags: tags,
|
tags: tags,
|
||||||
isSaveEnabled: _validateTags(tags),
|
isSaveEnabled: _validateTags(tags),
|
||||||
@ -79,7 +78,6 @@ class AssignTagBloc extends Bloc<AssignTagEvent, AssignTagState> {
|
|||||||
emit(AssignTagLoaded(
|
emit(AssignTagLoaded(
|
||||||
tags: tags,
|
tags: tags,
|
||||||
isSaveEnabled: _validateTags(tags),
|
isSaveEnabled: _validateTags(tags),
|
||||||
errorMessage: _getValidationError(tags),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -108,13 +106,12 @@ class AssignTagBloc extends Bloc<AssignTagEvent, AssignTagState> {
|
|||||||
emit(AssignTagLoaded(
|
emit(AssignTagLoaded(
|
||||||
tags: updatedTags,
|
tags: updatedTags,
|
||||||
isSaveEnabled: _validateTags(updatedTags),
|
isSaveEnabled: _validateTags(updatedTags),
|
||||||
errorMessage: _getValidationError(updatedTags),
|
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
emit(const AssignTagLoaded(
|
emit(const AssignTagLoaded(
|
||||||
tags: [],
|
tags: [],
|
||||||
isSaveEnabled: false,
|
isSaveEnabled: false,
|
||||||
errorMessage: 'Failed to delete tag'));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -128,10 +125,7 @@ class AssignTagBloc extends Bloc<AssignTagEvent, AssignTagState> {
|
|||||||
|
|
||||||
String? _getValidationError(List<Tag> tags) {
|
String? _getValidationError(List<Tag> tags) {
|
||||||
final hasEmptyTag = tags.any((tag) => (tag.tag?.trim() ?? '').isEmpty);
|
final hasEmptyTag = tags.any((tag) => (tag.tag?.trim() ?? '').isEmpty);
|
||||||
if (hasEmptyTag) {
|
if (hasEmptyTag) return 'Tags cannot be empty.';
|
||||||
return 'Tags cannot be empty.';
|
|
||||||
}
|
|
||||||
|
|
||||||
final duplicateTags = tags
|
final duplicateTags = tags
|
||||||
.map((tag) => tag.tag?.trim() ?? '')
|
.map((tag) => tag.tag?.trim() ?? '')
|
||||||
.fold<Map<String, int>>({}, (map, tag) {
|
.fold<Map<String, int>>({}, (map, tag) {
|
||||||
|
@ -21,11 +21,11 @@ class AssignTagLoaded extends AssignTagState {
|
|||||||
const AssignTagLoaded({
|
const AssignTagLoaded({
|
||||||
required this.tags,
|
required this.tags,
|
||||||
required this.isSaveEnabled,
|
required this.isSaveEnabled,
|
||||||
required this.errorMessage,
|
this.errorMessage,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [tags, isSaveEnabled, errorMessage ?? ''];
|
List<Object> get props => [tags, isSaveEnabled];
|
||||||
}
|
}
|
||||||
|
|
||||||
class AssignTagError extends AssignTagState {
|
class AssignTagError extends AssignTagState {
|
||||||
|
@ -71,7 +71,6 @@ class AssignTagDialog extends StatelessWidget {
|
|||||||
child: DataTable(
|
child: DataTable(
|
||||||
headingRowColor: WidgetStateProperty.all(
|
headingRowColor: WidgetStateProperty.all(
|
||||||
ColorsManager.dataHeaderGrey),
|
ColorsManager.dataHeaderGrey),
|
||||||
key: ValueKey(state.tags.length),
|
|
||||||
border: TableBorder.all(
|
border: TableBorder.all(
|
||||||
color: ColorsManager.dataHeaderGrey,
|
color: ColorsManager.dataHeaderGrey,
|
||||||
width: 1,
|
width: 1,
|
||||||
@ -121,7 +120,6 @@ class AssignTagDialog extends StatelessWidget {
|
|||||||
final controller = controllers[index];
|
final controller = controllers[index];
|
||||||
final availableTags = getAvailableTags(
|
final availableTags = getAvailableTags(
|
||||||
allTags ?? [], state.tags, tag);
|
allTags ?? [], state.tags, tag);
|
||||||
|
|
||||||
return DataRow(
|
return DataRow(
|
||||||
cells: [
|
cells: [
|
||||||
DataCell(Text((index + 1).toString())),
|
DataCell(Text((index + 1).toString())),
|
||||||
@ -160,8 +158,6 @@ class AssignTagDialog extends StatelessWidget {
|
|||||||
.add(DeleteTag(
|
.add(DeleteTag(
|
||||||
tagToDelete: tag,
|
tagToDelete: tag,
|
||||||
tags: state.tags));
|
tags: state.tags));
|
||||||
|
|
||||||
controllers.removeAt(index);
|
|
||||||
},
|
},
|
||||||
tooltip: 'Delete Tag',
|
tooltip: 'Delete Tag',
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
@ -259,7 +255,6 @@ class AssignTagDialog extends StatelessWidget {
|
|||||||
spaceTags: processedTags,
|
spaceTags: processedTags,
|
||||||
isCreate: false,
|
isCreate: false,
|
||||||
onSave: onSave,
|
onSave: onSave,
|
||||||
allTags: allTags,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -270,10 +265,10 @@ class AssignTagDialog extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
backgroundColor: ColorsManager.secondaryColor,
|
backgroundColor: state.isSaveEnabled
|
||||||
foregroundColor: state.isSaveEnabled
|
? ColorsManager.secondaryColor
|
||||||
? ColorsManager.whiteColors
|
: ColorsManager.grayColor,
|
||||||
: ColorsManager.whiteColorsWithOpacity,
|
foregroundColor: ColorsManager.whiteColors,
|
||||||
onPressed: state.isSaveEnabled
|
onPressed: state.isSaveEnabled
|
||||||
? () async {
|
? () async {
|
||||||
final updatedTags = List<Tag>.from(state.tags);
|
final updatedTags = List<Tag>.from(state.tags);
|
||||||
|
@ -82,7 +82,6 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
child: DataTable(
|
child: DataTable(
|
||||||
headingRowColor: WidgetStateProperty.all(
|
headingRowColor: WidgetStateProperty.all(
|
||||||
ColorsManager.dataHeaderGrey),
|
ColorsManager.dataHeaderGrey),
|
||||||
key: ValueKey(state.tags.length),
|
|
||||||
border: TableBorder.all(
|
border: TableBorder.all(
|
||||||
color: ColorsManager.dataHeaderGrey,
|
color: ColorsManager.dataHeaderGrey,
|
||||||
width: 1,
|
width: 1,
|
||||||
@ -177,7 +176,6 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
.add(DeleteTagModel(
|
.add(DeleteTagModel(
|
||||||
tagToDelete: tag,
|
tagToDelete: tag,
|
||||||
tags: state.tags));
|
tags: state.tags));
|
||||||
controllers.removeAt(index);
|
|
||||||
},
|
},
|
||||||
tooltip: 'Delete Tag',
|
tooltip: 'Delete Tag',
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
@ -304,10 +302,10 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultButton(
|
child: DefaultButton(
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
backgroundColor: ColorsManager.secondaryColor,
|
backgroundColor: state.isSaveEnabled
|
||||||
foregroundColor: state.isSaveEnabled
|
? ColorsManager.secondaryColor
|
||||||
? ColorsManager.whiteColors
|
: ColorsManager.grayColor,
|
||||||
: ColorsManager.whiteColorsWithOpacity,
|
foregroundColor: ColorsManager.whiteColors,
|
||||||
onPressed: state.isSaveEnabled
|
onPressed: state.isSaveEnabled
|
||||||
? () async {
|
? () async {
|
||||||
final updatedTags =
|
final updatedTags =
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
|
||||||
|
|
||||||
class ConnectionHelper {
|
|
||||||
static Offset getCenterPosition(Size screenSize) {
|
|
||||||
return Offset(
|
|
||||||
screenSize.width / 2 - 260,
|
|
||||||
screenSize.height / 2 - 200,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isHighlightedConnection(
|
|
||||||
Connection connection, SpaceModel? selectedSpace) {
|
|
||||||
if (selectedSpace == null) return true;
|
|
||||||
|
|
||||||
return connection.startSpace == selectedSpace ||
|
|
||||||
connection.endSpace == selectedSpace;
|
|
||||||
}
|
|
||||||
}
|
|
@ -40,55 +40,4 @@ class SpaceHelper {
|
|||||||
|
|
||||||
return "$baseName(${maxNumber + 1})";
|
return "$baseName(${maxNumber + 1})";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isSave(List<SpaceModel> spaces) {
|
|
||||||
return spaces.isNotEmpty &&
|
|
||||||
spaces.any((space) =>
|
|
||||||
space.status == SpaceStatus.newSpace ||
|
|
||||||
space.status == SpaceStatus.modified ||
|
|
||||||
space.status == SpaceStatus.deleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isHighlightedSpace(SpaceModel space, SpaceModel? selectedSpace) {
|
|
||||||
if (selectedSpace == null) return true;
|
|
||||||
|
|
||||||
return space == selectedSpace ||
|
|
||||||
selectedSpace.parent?.internalId == space.internalId ||
|
|
||||||
selectedSpace.children
|
|
||||||
?.any((child) => child.internalId == space.internalId) ==
|
|
||||||
true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isNameConflict(
|
|
||||||
String value, SpaceModel? parentSpace, SpaceModel? editSpace) {
|
|
||||||
final siblings = parentSpace?.children
|
|
||||||
.where((child) => child.internalId != editSpace?.internalId)
|
|
||||||
.toList() ??
|
|
||||||
[];
|
|
||||||
|
|
||||||
final editSiblings = editSpace?.parent?.children
|
|
||||||
.where((child) => child.internalId != editSpace.internalId)
|
|
||||||
.toList() ??
|
|
||||||
[];
|
|
||||||
|
|
||||||
final editSiblingConflict =
|
|
||||||
editSiblings.any((child) => child.name == value);
|
|
||||||
|
|
||||||
final siblingConflict = siblings.any((child) => child.name == value);
|
|
||||||
|
|
||||||
final parentConflict = parentSpace?.name == value &&
|
|
||||||
parentSpace?.internalId != editSpace?.internalId;
|
|
||||||
|
|
||||||
final parentOfEditSpaceConflict = editSpace?.parent?.name == value &&
|
|
||||||
editSpace?.parent?.internalId != editSpace?.internalId;
|
|
||||||
|
|
||||||
final childConflict =
|
|
||||||
editSpace?.children.any((child) => child.name == value) ?? false;
|
|
||||||
|
|
||||||
return siblingConflict ||
|
|
||||||
parentConflict ||
|
|
||||||
editSiblingConflict ||
|
|
||||||
parentOfEditSpaceConflict ||
|
|
||||||
childConflict;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/base_tag.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/base_tag.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.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/selected_product_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.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/models/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||||
|
|
||||||
@ -340,25 +337,4 @@ class TagHelper {
|
|||||||
checkTagExistInSubspace: checkTagExistInSubspace,
|
checkTagExistInSubspace: checkTagExistInSubspace,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<String> getAllTagValues(
|
|
||||||
List<CommunityModel> communities, List<SpaceTemplateModel>? spaceModels) {
|
|
||||||
final Set<String> allTags = {};
|
|
||||||
|
|
||||||
if (spaceModels != null) {
|
|
||||||
for (var model in spaceModels) {
|
|
||||||
allTags.addAll(model.listAllTagValues());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (final community in communities) {
|
|
||||||
for (final space in community.spaces) {
|
|
||||||
if (space.tags != null) {
|
|
||||||
allTags.addAll(space.listAllTagValues());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return allTags.toList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,64 +6,55 @@ class ButtonContentWidget extends StatelessWidget {
|
|||||||
final IconData? icon;
|
final IconData? icon;
|
||||||
final String label;
|
final String label;
|
||||||
final String? svgAssets;
|
final String? svgAssets;
|
||||||
final bool disabled;
|
|
||||||
|
|
||||||
const ButtonContentWidget({
|
const ButtonContentWidget(
|
||||||
Key? key,
|
{Key? key, this.icon, required this.label, this.svgAssets})
|
||||||
this.icon,
|
: super(key: key);
|
||||||
required this.label,
|
|
||||||
this.svgAssets,
|
|
||||||
this.disabled = false,
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
return Opacity(
|
return SizedBox(
|
||||||
opacity: disabled ? 0.5 : 1.0,
|
width: screenWidth * 0.25,
|
||||||
child: SizedBox(
|
child: Container(
|
||||||
width: screenWidth * 0.25,
|
decoration: BoxDecoration(
|
||||||
child: Container(
|
color: ColorsManager.textFieldGreyColor,
|
||||||
decoration: BoxDecoration(
|
border: Border.all(
|
||||||
color: ColorsManager.textFieldGreyColor,
|
color: ColorsManager.neutralGray,
|
||||||
border: Border.all(
|
width: 3.0,
|
||||||
color: ColorsManager.neutralGray,
|
|
||||||
width: 3.0,
|
|
||||||
),
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
),
|
),
|
||||||
child: Padding(
|
borderRadius: BorderRadius.circular(20),
|
||||||
padding:
|
),
|
||||||
const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
child: Padding(
|
||||||
child: Row(
|
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
||||||
children: [
|
child: Row(
|
||||||
if (icon != null)
|
children: [
|
||||||
Icon(
|
if (icon != null)
|
||||||
icon,
|
Icon(
|
||||||
color: ColorsManager.spaceColor,
|
icon,
|
||||||
),
|
color: ColorsManager.spaceColor,
|
||||||
if (svgAssets != null)
|
),
|
||||||
Padding(
|
if (svgAssets != null)
|
||||||
padding: const EdgeInsets.only(left: 6.0),
|
Padding(
|
||||||
child: SvgPicture.asset(
|
padding: const EdgeInsets.only(left: 6.0),
|
||||||
svgAssets!,
|
child: SvgPicture.asset(
|
||||||
width: screenWidth * 0.015, // Adjust icon size
|
svgAssets!,
|
||||||
height: screenWidth * 0.015,
|
width: screenWidth * 0.015, // Adjust icon size
|
||||||
),
|
height: screenWidth * 0.015,
|
||||||
),
|
|
||||||
const SizedBox(width: 10),
|
|
||||||
Expanded(
|
|
||||||
child: Text(
|
|
||||||
label,
|
|
||||||
style: const TextStyle(
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
fontSize: 16,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(width: 10),
|
||||||
),
|
Expanded(
|
||||||
|
child: Text(
|
||||||
|
label,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -23,8 +23,7 @@ class DevicesManagementApi {
|
|||||||
: ApiEndpoints.getAllDevices,
|
: ApiEndpoints.getAllDevices,
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
List<dynamic> jsonData =
|
List<dynamic> jsonData = json;
|
||||||
communityId.isNotEmpty && spaceId.isNotEmpty ? json['data'] : json;
|
|
||||||
List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
|
List<AllDevicesModel> devicesList = jsonData.map((jsonItem) {
|
||||||
return AllDevicesModel.fromJson(jsonItem);
|
return AllDevicesModel.fromJson(jsonItem);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
Reference in New Issue
Block a user