mirror of
https://github.com/SyncrowIOT/web.git
synced 2026-10-26 08:57:57 +00:00
Compare commits
26
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37440f288c | ||
|
|
973ae82bec | ||
|
|
8c4dec4483 | ||
|
|
ad922577da | ||
|
|
64f61a6c3d | ||
|
|
ab3f268f29 | ||
|
|
b345822366 | ||
|
|
76793a3c0b | ||
|
|
c330f11206 | ||
|
|
9cb62795a6 | ||
|
|
a034202d76 | ||
|
|
869799f08e | ||
|
|
573e7b42ed | ||
|
|
22935f7007 | ||
|
|
5bf5120883 | ||
|
|
f307aaff9d | ||
|
|
aea18fb293 | ||
|
|
835dfe8785 | ||
|
|
f670ae78aa | ||
|
|
d3128a9c9c | ||
|
|
b65f172f9d | ||
|
|
dad18b77de | ||
|
|
77a9aa2f19 | ||
|
|
de5030d9f0 | ||
|
|
8c15fffd42 | ||
|
|
3750fa8329 |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,17 +0,0 @@
|
|||||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g filter="url(#filter0_d_6675_32326)">
|
|
||||||
<path d="M18 3C9.71584 3 3 9.71572 3 18C3 26.2843 9.71584 33 18 33C26.2842 33 33 26.2843 33 18C33 9.71572 26.2842 3 18 3ZM23.1844 18.7951L15.6844 23.4826C15.5326 23.5774 15.3601 23.625 15.1875 23.625C15.0312 23.625 14.8746 23.5861 14.7329 23.5073C14.4349 23.3421 14.25 23.0285 14.25 22.6875V13.3125C14.25 12.9715 14.4349 12.6579 14.7329 12.4927C15.0309 12.3265 15.3953 12.3366 15.6844 12.5174L23.1844 17.2049C23.4584 17.3766 23.625 17.6769 23.625 18C23.625 18.3231 23.4584 18.6235 23.1844 18.7951Z" fill="#F4F4F4"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_d_6675_32326" x="0" y="0" width="36" height="36" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset/>
|
|
||||||
<feGaussianBlur stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
|
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_6675_32326"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_6675_32326" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,30 +0,0 @@
|
|||||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g filter="url(#filter0_d_7280_5211)">
|
|
||||||
<circle cx="18" cy="18" r="15" fill="#F4F4F4"/>
|
|
||||||
</g>
|
|
||||||
<g filter="url(#filter1_i_7280_5211)">
|
|
||||||
<path d="M25.1663 13.187C24.8231 12.8439 24.2666 12.8439 23.9234 13.1871L16.1621 20.9484L12.0766 16.8628C11.7334 16.5196 11.1768 16.5196 10.8336 16.8628C10.4904 17.206 10.4904 17.7625 10.8336 18.1057L15.5406 22.8127C15.7122 22.9844 15.9372 23.0701 16.1621 23.0701C16.3869 23.0701 16.6119 22.9843 16.7835 22.8127L25.1663 14.43C25.5095 14.0868 25.5095 13.5303 25.1663 13.187Z" fill="white"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<filter id="filter0_d_7280_5211" x="0" y="0" width="36" height="36" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset/>
|
|
||||||
<feGaussianBlur stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="out"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
|
|
||||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_7280_5211"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_7280_5211" result="shape"/>
|
|
||||||
</filter>
|
|
||||||
<filter id="filter1_i_7280_5211" x="10.5762" y="12.9297" width="14.8475" height="10.1406" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
||||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
||||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
||||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
|
||||||
<feOffset/>
|
|
||||||
<feGaussianBlur stdDeviation="1.5"/>
|
|
||||||
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
|
||||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0"/>
|
|
||||||
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_7280_5211"/>
|
|
||||||
</filter>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -2,14 +2,17 @@ import 'package:flutter/foundation.dart';
|
|||||||
|
|
||||||
class FactoryResetModel {
|
class FactoryResetModel {
|
||||||
final List<String> devicesUuid;
|
final List<String> devicesUuid;
|
||||||
|
final String operationType;
|
||||||
|
|
||||||
FactoryResetModel({
|
FactoryResetModel({
|
||||||
required this.devicesUuid,
|
required this.devicesUuid,
|
||||||
|
this.operationType = "RESET",
|
||||||
});
|
});
|
||||||
|
|
||||||
factory FactoryResetModel.fromJson(Map<String, dynamic> json) {
|
factory FactoryResetModel.fromJson(Map<String, dynamic> json) {
|
||||||
return FactoryResetModel(
|
return FactoryResetModel(
|
||||||
devicesUuid: List<String>.from(json['devicesUuid']),
|
devicesUuid: List<String>.from(json['devicesUuid']),
|
||||||
|
operationType: "RESET",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,77 +12,68 @@ class DeviceSearchFilters extends StatefulWidget {
|
|||||||
State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState();
|
State<DeviceSearchFilters> createState() => _DeviceSearchFiltersState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DeviceSearchFiltersState extends State<DeviceSearchFilters> with HelperResponsiveLayout {
|
class _DeviceSearchFiltersState extends State<DeviceSearchFilters>
|
||||||
final TextEditingController communityController = TextEditingController();
|
with HelperResponsiveLayout {
|
||||||
final TextEditingController unitNameController = TextEditingController();
|
final _unitNameController = TextEditingController();
|
||||||
final TextEditingController productNameController = TextEditingController();
|
final _productNameController = TextEditingController();
|
||||||
|
|
||||||
|
List<Widget> get _widgets => [
|
||||||
|
_buildSearchField("Space Name", _unitNameController, 200),
|
||||||
|
_buildSearchField("Device Name / Product Name", _productNameController, 300),
|
||||||
|
_buildSearchResetButtons(),
|
||||||
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return isExtraLargeScreenSize(context)
|
if (isExtraLargeScreenSize(context)) {
|
||||||
? Row(
|
return Row(
|
||||||
children: [
|
children: _widgets
|
||||||
_buildSearchField("Community", communityController, 200),
|
.map((e) => Padding(padding: const EdgeInsets.all(10), child: e))
|
||||||
const SizedBox(width: 20),
|
.toList(),
|
||||||
_buildSearchField("Space Name", unitNameController, 200),
|
);
|
||||||
const SizedBox(width: 20),
|
}
|
||||||
_buildSearchField("Device Name / Product Name", productNameController, 300),
|
|
||||||
const SizedBox(width: 20),
|
return Wrap(
|
||||||
_buildSearchResetButtons(),
|
spacing: 20,
|
||||||
],
|
runSpacing: 10,
|
||||||
)
|
children: _widgets,
|
||||||
: Wrap(
|
);
|
||||||
spacing: 20,
|
|
||||||
runSpacing: 10,
|
|
||||||
children: [
|
|
||||||
_buildSearchField(
|
|
||||||
"Community",
|
|
||||||
communityController,
|
|
||||||
200,
|
|
||||||
),
|
|
||||||
_buildSearchField("Space Name", unitNameController, 200),
|
|
||||||
_buildSearchField(
|
|
||||||
"Device Name / Product Name",
|
|
||||||
productNameController,
|
|
||||||
300,
|
|
||||||
),
|
|
||||||
_buildSearchResetButtons(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSearchField(String title, TextEditingController controller, double width) {
|
Widget _buildSearchField(
|
||||||
return Container(
|
String title,
|
||||||
child: StatefulTextField(
|
TextEditingController controller,
|
||||||
title: title,
|
double width,
|
||||||
width: width,
|
) {
|
||||||
elevation: 2,
|
return StatefulTextField(
|
||||||
controller: controller,
|
title: title,
|
||||||
onSubmitted: () {
|
width: width,
|
||||||
context.read<DeviceManagementBloc>().add(SearchDevices(
|
elevation: 2,
|
||||||
productName: productNameController.text,
|
controller: controller,
|
||||||
unitName: unitNameController.text,
|
onSubmitted: () {
|
||||||
community: communityController.text,
|
final searchDevicesEvent = SearchDevices(
|
||||||
searchField: true));
|
productName: _productNameController.text,
|
||||||
},
|
unitName: _unitNameController.text,
|
||||||
onChanged: (p0) {},
|
searchField: true,
|
||||||
),
|
);
|
||||||
|
context.read<DeviceManagementBloc>().add(searchDevicesEvent);
|
||||||
|
},
|
||||||
|
onChanged: (p0) {},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSearchResetButtons() {
|
Widget _buildSearchResetButtons() {
|
||||||
return SearchResetButtons(
|
return SearchResetButtons(
|
||||||
onSearch: () {
|
onSearch: () => context.read<DeviceManagementBloc>().add(
|
||||||
context.read<DeviceManagementBloc>().add(SearchDevices(
|
SearchDevices(
|
||||||
community: communityController.text,
|
unitName: _unitNameController.text,
|
||||||
unitName: unitNameController.text,
|
productName: _productNameController.text,
|
||||||
productName: productNameController.text,
|
searchField: true,
|
||||||
searchField: true));
|
),
|
||||||
},
|
),
|
||||||
onReset: () {
|
onReset: () {
|
||||||
communityController.clear();
|
_unitNameController.clear();
|
||||||
unitNameController.clear();
|
_productNameController.clear();
|
||||||
productNameController.clear();
|
|
||||||
context.read<DeviceManagementBloc>()
|
context.read<DeviceManagementBloc>()
|
||||||
..add(ResetFilters())
|
..add(ResetFilters())
|
||||||
..add(FetchDevices(context));
|
..add(FetchDevices(context));
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.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/space_tree/bloc/space_tree_bloc.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
|
||||||
|
|
||||||
class CommunityDropdown extends StatelessWidget {
|
class CommunityDropdown extends StatelessWidget {
|
||||||
final String? selectedValue;
|
final String? selectedValue;
|
||||||
final Function(String?) onChanged;
|
final Function(String?) onChanged;
|
||||||
|
final TextEditingController _searchController = TextEditingController();
|
||||||
|
|
||||||
const CommunityDropdown({
|
CommunityDropdown({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.selectedValue,
|
required this.selectedValue,
|
||||||
required this.onChanged,
|
required this.onChanged,
|
||||||
@@ -34,59 +34,119 @@ class CommunityDropdown extends StatelessWidget {
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
|
BlocBuilder<SpaceTreeBloc, SpaceTreeState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
List<CommunityModel> communities = state.isSearching
|
|
||||||
? state.filteredCommunity
|
|
||||||
: state.communityList;
|
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
child: DropdownButtonFormField<String>(
|
child: Container(
|
||||||
dropdownColor: ColorsManager.whiteColors,
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: DropdownButton2<String>(
|
||||||
|
underline: SizedBox(),
|
||||||
value: selectedValue,
|
value: selectedValue,
|
||||||
items: communities.map((community) {
|
items: state.communityList.map((community) {
|
||||||
return DropdownMenuItem<String>(
|
return DropdownMenuItem<String>(
|
||||||
value: community.uuid,
|
value: community.uuid,
|
||||||
child: Text(' ${community.name}'),
|
child: Text(
|
||||||
|
' ${community.name}',
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
onChanged: onChanged,
|
onChanged: onChanged,
|
||||||
icon: const SizedBox.shrink(),
|
style: TextStyle(color: Colors.black),
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
|
||||||
hint: Padding(
|
hint: Padding(
|
||||||
padding: EdgeInsets.only(left: 10),
|
padding: EdgeInsets.only(left: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
"Please Select",
|
" Please Select",
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
color: ColorsManager.textGray,
|
color: ColorsManager.textGray,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
decoration: inputTextFormDeco().copyWith(
|
customButton: Container(
|
||||||
contentPadding: EdgeInsets.zero,
|
height: 45,
|
||||||
suffixIcon: Container(
|
decoration: BoxDecoration(
|
||||||
padding: EdgeInsets.zero,
|
border: Border.all(color: ColorsManager.textGray, width: 1.0),
|
||||||
width: 70,
|
borderRadius: BorderRadius.circular(10),
|
||||||
height: 45,
|
),
|
||||||
decoration: BoxDecoration(
|
child: Row(
|
||||||
color: Colors.grey[100],
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
borderRadius: const BorderRadius.only(
|
children: [
|
||||||
bottomRight: Radius.circular(10),
|
Expanded(
|
||||||
topRight: Radius.circular(10),
|
flex: 5,
|
||||||
|
child: Text(
|
||||||
|
selectedValue != null
|
||||||
|
? " ${state.communityList.firstWhere((element) => element.uuid == selectedValue).name}"
|
||||||
|
: ' Please Select',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color:
|
||||||
|
selectedValue != null ? Colors.black : ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
border: Border.all(
|
Expanded(
|
||||||
color: ColorsManager.textGray,
|
child: Container(
|
||||||
width: 1.0,
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[100],
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: 45,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
child: const Center(
|
),
|
||||||
child: Icon(
|
),
|
||||||
Icons.keyboard_arrow_down,
|
dropdownStyleData: DropdownStyleData(
|
||||||
color: ColorsManager.textGray,
|
maxHeight: MediaQuery.of(context).size.height * 0.4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownSearchData: DropdownSearchData(
|
||||||
|
searchController: _searchController,
|
||||||
|
searchInnerWidgetHeight: 50,
|
||||||
|
searchInnerWidget: Container(
|
||||||
|
height: 50,
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
child: TextFormField(
|
||||||
|
style: const TextStyle(color: Colors.black),
|
||||||
|
controller: _searchController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: 10,
|
||||||
|
vertical: 12,
|
||||||
|
),
|
||||||
|
hintText: 'Search for community...',
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
searchMatchFn: (item, searchValue) {
|
||||||
|
final communityName = (item.child as Text).data?.toLowerCase() ?? '';
|
||||||
|
return communityName.contains(searchValue.toLowerCase().trim());
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onMenuStateChange: (isOpen) {
|
||||||
|
if (!isOpen) {
|
||||||
|
_searchController.clear();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
menuItemStyleData: const MenuItemStyleData(
|
||||||
|
height: 40,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -62,28 +62,34 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Divider(),
|
const Divider(),
|
||||||
CommunityDropdown(
|
Padding(
|
||||||
selectedValue: _selectedCommunity,
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
onChanged: (String? newValue) {
|
child: CommunityDropdown(
|
||||||
setState(() {
|
selectedValue: _selectedCommunity,
|
||||||
_selectedCommunity = newValue;
|
onChanged: (String? newValue) {
|
||||||
_selectedSpace = null;
|
setState(() {
|
||||||
});
|
_selectedCommunity = newValue;
|
||||||
if (newValue != null) {
|
_selectedSpace = null;
|
||||||
_fetchSpaces(newValue);
|
});
|
||||||
}
|
if (newValue != null) {
|
||||||
},
|
_fetchSpaces(newValue);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 5),
|
||||||
SpaceDropdown(
|
Padding(
|
||||||
hintMessage: spaceHint,
|
padding: const EdgeInsets.only(left: 15, right: 15),
|
||||||
spaces: spaces,
|
child: SpaceDropdown(
|
||||||
selectedValue: _selectedSpace,
|
hintMessage: spaceHint,
|
||||||
onChanged: (String? newValue) {
|
spaces: spaces,
|
||||||
setState(() {
|
selectedValue: _selectedSpace,
|
||||||
_selectedSpace = newValue;
|
onChanged: (String? newValue) {
|
||||||
});
|
setState(() {
|
||||||
},
|
_selectedSpace = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
Row(
|
Row(
|
||||||
@@ -96,7 +102,6 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
),
|
),
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -139,6 +144,7 @@ class _CreateNewRoutinesDialogState extends State<CreateNewRoutinesDialog> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 10),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/utils/style.dart';
|
|
||||||
|
|
||||||
class SpaceDropdown extends StatelessWidget {
|
class SpaceDropdown extends StatelessWidget {
|
||||||
final List<SpaceModel> spaces;
|
final List<SpaceModel> spaces;
|
||||||
@@ -33,62 +34,108 @@ class SpaceDropdown extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
DropdownButtonFormField<String>(
|
SizedBox(
|
||||||
value: selectedValue,
|
child: Container(
|
||||||
items: spaces.map((space) {
|
decoration: BoxDecoration(
|
||||||
return DropdownMenuItem<String>(
|
borderRadius: BorderRadius.circular(10),
|
||||||
value: space.uuid,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
' ${space.name}',
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
|
||||||
fontSize: 12,
|
|
||||||
color: ColorsManager.blackColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
' ${space.lastThreeParents}',
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
|
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
}).toList(),
|
|
||||||
onChanged: onChanged,
|
|
||||||
icon: const SizedBox.shrink(),
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(10)),
|
|
||||||
hint: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 10),
|
|
||||||
child: Text(
|
|
||||||
hintMessage,
|
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
|
||||||
color: ColorsManager.textGray,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
child: DropdownButton2<String>(
|
||||||
decoration: inputTextFormDeco().copyWith(
|
underline: const SizedBox(),
|
||||||
contentPadding: EdgeInsets.zero,
|
value: selectedValue,
|
||||||
suffixIcon: Container(
|
items: spaces.map((space) {
|
||||||
width: 70,
|
return DropdownMenuItem<String>(
|
||||||
height: 45,
|
value: space.uuid,
|
||||||
decoration: BoxDecoration(
|
child: Column(
|
||||||
color: Colors.grey[200],
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
borderRadius: const BorderRadius.only(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
bottomRight: Radius.circular(10),
|
children: [
|
||||||
topRight: Radius.circular(10),
|
Text(
|
||||||
),
|
' ${space.name}',
|
||||||
border: Border.all(
|
style:
|
||||||
color: ColorsManager.textGray,
|
Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
width: 1.0,
|
fontSize: 12,
|
||||||
|
color: ColorsManager.blackColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
' ${space.lastThreeParents}',
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||||
|
fontSize: 12,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
onChanged: onChanged,
|
||||||
|
style: TextStyle(color: Colors.black),
|
||||||
|
hint: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Text(
|
||||||
|
hintMessage,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: const Icon(
|
customButton: Container(
|
||||||
Icons.keyboard_arrow_down,
|
height: 45,
|
||||||
color: ColorsManager.textGray,
|
decoration: BoxDecoration(
|
||||||
|
border:
|
||||||
|
Border.all(color: ColorsManager.textGray, width: 1.0),
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
flex: 5,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Text(
|
||||||
|
selectedValue != null
|
||||||
|
? spaces
|
||||||
|
.firstWhere((e) => e.uuid == selectedValue)
|
||||||
|
.name
|
||||||
|
: hintMessage,
|
||||||
|
style:
|
||||||
|
Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: selectedValue != null
|
||||||
|
? Colors.black
|
||||||
|
: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey[200],
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topRight: Radius.circular(10),
|
||||||
|
bottomRight: Radius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
height: 45,
|
||||||
|
child: const Icon(
|
||||||
|
Icons.keyboard_arrow_down,
|
||||||
|
color: ColorsManager.textGray,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
dropdownStyleData: DropdownStyleData(
|
||||||
|
maxHeight: MediaQuery.of(context).size.height * 0.4,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
menuItemStyleData: const MenuItemStyleData(
|
||||||
|
height: 60,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -33,8 +33,6 @@ class _RoutinesViewState extends State<RoutinesView> {
|
|||||||
communityID: communityId, spaceID: spaceId));
|
communityID: communityId, spaceID: spaceId));
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
routineBloc.add(const CreateNewRoutineViewEvent(createRoutineView: true));
|
routineBloc.add(const CreateNewRoutineViewEvent(createRoutineView: true));
|
||||||
await Future.delayed(const Duration(milliseconds:500));
|
|
||||||
_bloc.add(const ResetSelectedEvent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -92,6 +90,7 @@ class _RoutinesViewState extends State<RoutinesView> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 50),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 5),
|
const SizedBox(height: 3),
|
||||||
if (state.automations.isEmpty)
|
if (state.automations.isEmpty)
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -130,8 +130,8 @@ class _FetchRoutineScenesState extends State<FetchRoutineScenesAutomation>
|
|||||||
if (state.automations.isNotEmpty)
|
if (state.automations.isNotEmpty)
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: BoxConstraints(
|
constraints: BoxConstraints(
|
||||||
maxHeight: isSmallScreenSize(context) ? 185 : 192,
|
maxHeight: isSmallScreenSize(context) ? 190 : 195,
|
||||||
maxWidth: MediaQuery.sizeOf(context).width * 0.7),
|
),
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: state.automations.length,
|
itemCount: state.automations.length,
|
||||||
|
|||||||
@@ -106,10 +106,10 @@ class _RoutineViewCardState extends State<RoutineViewCard> {
|
|||||||
if (widget.isFromScenes ?? false)
|
if (widget.isFromScenes ?? false)
|
||||||
InkWell(
|
InkWell(
|
||||||
onTap: _handleSceneTap,
|
onTap: _handleSceneTap,
|
||||||
child: SvgPicture.asset(
|
child: Image.asset(
|
||||||
_showTemporaryCheck
|
_showTemporaryCheck
|
||||||
? Assets.scenesPlayIconCheck
|
? Assets.scenesPlayIcon
|
||||||
: Assets.scenesPlayIcon,
|
: Assets.scenesPlayIconCheck,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
import 'package:syncrow_web/pages/common/bloc/project_manager.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart';
|
||||||
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
import 'package:syncrow_web/pages/space_tree/bloc/space_tree_state.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.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';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
import 'package:syncrow_web/services/space_mana_api.dart';
|
import 'package:syncrow_web/services/space_mana_api.dart';
|
||||||
@@ -18,7 +21,10 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
on<ClearCachedData>(_clearCachedData);
|
on<ClearCachedData>(_clearCachedData);
|
||||||
on<OnCommunityAdded>(_onCommunityAdded);
|
on<OnCommunityAdded>(_onCommunityAdded);
|
||||||
on<OnCommunityUpdated>(_onCommunityUpdate);
|
on<OnCommunityUpdated>(_onCommunityUpdate);
|
||||||
|
on<PaginationEvent>(_fetchPaginationSpaces);
|
||||||
|
on<DebouncedSearchEvent>(_onDebouncedSearch);
|
||||||
}
|
}
|
||||||
|
Timer _timer = Timer(const Duration(microseconds: 0), () {});
|
||||||
|
|
||||||
void _onCommunityUpdate(
|
void _onCommunityUpdate(
|
||||||
OnCommunityUpdated event,
|
OnCommunityUpdated event,
|
||||||
@@ -28,17 +34,16 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final updatedCommunity = event.updatedCommunity;
|
final updatedCommunity = event.updatedCommunity;
|
||||||
final updatedCommunities =
|
final updatedCommunities = List<CommunityModel>.from(state.communityList);
|
||||||
List<CommunityModel>.from(state.communityList);
|
|
||||||
|
|
||||||
final index = updatedCommunities
|
final index =
|
||||||
.indexWhere((community) => community.uuid == updatedCommunity.uuid);
|
updatedCommunities.indexWhere((community) => community.uuid == updatedCommunity.uuid);
|
||||||
|
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
updatedCommunities[index] = updatedCommunity;
|
updatedCommunities[index] = updatedCommunity;
|
||||||
emit(state.copyWith(communitiesList: updatedCommunities));
|
emit(state.copyWith(communitiesList: updatedCommunities));
|
||||||
} else {
|
} else {
|
||||||
emit(SpaceTreeErrorState('Community not found in the list.'));
|
emit(const SpaceTreeErrorState('Community not found in the list.'));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SpaceTreeErrorState('Error updating community: $e'));
|
emit(SpaceTreeErrorState('Error updating community: $e'));
|
||||||
@@ -50,48 +55,68 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
try {
|
try {
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
List<CommunityModel> communities =
|
PaginationModel paginationModel = await CommunitySpaceManagementApi()
|
||||||
await CommunitySpaceManagementApi().fetchCommunities(projectUuid);
|
.fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1);
|
||||||
|
|
||||||
List<CommunityModel> updatedCommunities = await Future.wait(
|
// List<CommunityModel> updatedCommunities = await Future.wait(
|
||||||
communities.map((community) async {
|
// communities.map((community) async {
|
||||||
List<SpaceModel> spaces = await CommunitySpaceManagementApi()
|
// List<SpaceModel> spaces =
|
||||||
.getSpaceHierarchy(community.uuid, projectUuid);
|
// await CommunitySpaceManagementApi().getSpaceHierarchy(community.uuid, projectUuid);
|
||||||
|
|
||||||
return CommunityModel(
|
// return CommunityModel(
|
||||||
uuid: community.uuid,
|
// uuid: community.uuid,
|
||||||
createdAt: community.createdAt,
|
// createdAt: community.createdAt,
|
||||||
updatedAt: community.updatedAt,
|
// updatedAt: community.updatedAt,
|
||||||
name: community.name,
|
// name: community.name,
|
||||||
description: community.description,
|
// description: community.description,
|
||||||
spaces: spaces,
|
// spaces: spaces,
|
||||||
region: community.region,
|
// region: community.region,
|
||||||
);
|
// );
|
||||||
}).toList(),
|
// }).toList(),
|
||||||
);
|
// );
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
communitiesList: updatedCommunities,
|
communitiesList: paginationModel.communities,
|
||||||
expandedCommunity: [],
|
expandedCommunity: [],
|
||||||
expandedSpaces: []));
|
expandedSpaces: [],
|
||||||
|
paginationModel: paginationModel));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onCommunityAdded(
|
_fetchPaginationSpaces(PaginationEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
OnCommunityAdded event, Emitter<SpaceTreeState> emit) async {
|
emit(state.copyWith(paginationIsLoading: true));
|
||||||
|
PaginationModel paginationModel = event.paginationModel;
|
||||||
|
List<CommunityModel> communities = List<CommunityModel>.from(event.communities);
|
||||||
|
try {
|
||||||
|
if (paginationModel.hasNext && state.searchQuery.isEmpty) {
|
||||||
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
|
paginationModel = await CommunitySpaceManagementApi().fetchCommunitiesAndSpaces(
|
||||||
|
projectId: projectUuid, page: paginationModel.pageNum, search: state.searchQuery);
|
||||||
|
|
||||||
|
communities.addAll(paginationModel.communities);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
emit(SpaceTreeErrorState('Error loading communities and spaces: $e'));
|
||||||
|
}
|
||||||
|
emit(state.copyWith(
|
||||||
|
communitiesList: communities,
|
||||||
|
paginationModel: paginationModel,
|
||||||
|
paginationIsLoading: false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onCommunityAdded(OnCommunityAdded event, Emitter<SpaceTreeState> emit) async {
|
||||||
final updatedCommunities = List<CommunityModel>.from(state.communityList);
|
final updatedCommunities = List<CommunityModel>.from(state.communityList);
|
||||||
updatedCommunities.add(event.newCommunity);
|
updatedCommunities.add(event.newCommunity);
|
||||||
|
|
||||||
emit(state.copyWith(communitiesList: updatedCommunities));
|
emit(state.copyWith(communitiesList: updatedCommunities));
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCommunityExpanded(
|
_onCommunityExpanded(OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
|
||||||
OnCommunityExpanded event, Emitter<SpaceTreeState> emit) async {
|
|
||||||
try {
|
try {
|
||||||
List<String> updatedExpandedCommunityList =
|
List<String> updatedExpandedCommunityList = List.from(state.expandedCommunities);
|
||||||
List.from(state.expandedCommunities);
|
|
||||||
|
|
||||||
if (updatedExpandedCommunityList.contains(event.communityId)) {
|
if (updatedExpandedCommunityList.contains(event.communityId)) {
|
||||||
updatedExpandedCommunityList.remove(event.communityId);
|
updatedExpandedCommunityList.remove(event.communityId);
|
||||||
@@ -123,19 +148,14 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCommunitySelected(
|
_onCommunitySelected(OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
|
||||||
OnCommunitySelected event, Emitter<SpaceTreeState> emit) async {
|
|
||||||
try {
|
try {
|
||||||
List<String> updatedSelectedCommunities =
|
List<String> updatedSelectedCommunities =
|
||||||
List.from(state.selectedCommunities.toSet().toList());
|
List.from(state.selectedCommunities.toSet().toList());
|
||||||
List<String> updatedSelectedSpaces =
|
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
||||||
List.from(state.selectedSpaces.toSet().toList());
|
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
||||||
List<String> updatedSoldChecks =
|
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
|
||||||
List.from(state.soldCheck.toSet().toList());
|
List<String> selectedSpacesInCommunity = communityAndSpaces[event.communityId] ?? [];
|
||||||
Map<String, List<String>> communityAndSpaces =
|
|
||||||
Map.from(state.selectedCommunityAndSpaces);
|
|
||||||
List<String> selectedSpacesInCommunity =
|
|
||||||
communityAndSpaces[event.communityId] ?? [];
|
|
||||||
|
|
||||||
List<String> childrenIds = _getAllChildIds(event.children);
|
List<String> childrenIds = _getAllChildIds(event.children);
|
||||||
|
|
||||||
@@ -168,15 +188,11 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
try {
|
try {
|
||||||
List<String> updatedSelectedCommunities =
|
List<String> updatedSelectedCommunities =
|
||||||
List.from(state.selectedCommunities.toSet().toList());
|
List.from(state.selectedCommunities.toSet().toList());
|
||||||
List<String> updatedSelectedSpaces =
|
List<String> updatedSelectedSpaces = List.from(state.selectedSpaces.toSet().toList());
|
||||||
List.from(state.selectedSpaces.toSet().toList());
|
List<String> updatedSoldChecks = List.from(state.soldCheck.toSet().toList());
|
||||||
List<String> updatedSoldChecks =
|
Map<String, List<String>> communityAndSpaces = Map.from(state.selectedCommunityAndSpaces);
|
||||||
List.from(state.soldCheck.toSet().toList());
|
|
||||||
Map<String, List<String>> communityAndSpaces =
|
|
||||||
Map.from(state.selectedCommunityAndSpaces);
|
|
||||||
|
|
||||||
List<String> selectedSpacesInCommunity =
|
List<String> selectedSpacesInCommunity = communityAndSpaces[event.communityModel.uuid] ?? [];
|
||||||
communityAndSpaces[event.communityModel.uuid] ?? [];
|
|
||||||
|
|
||||||
List<String> childrenIds = _getAllChildIds(event.children);
|
List<String> childrenIds = _getAllChildIds(event.children);
|
||||||
bool isChildSelected = false;
|
bool isChildSelected = false;
|
||||||
@@ -199,11 +215,9 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
selectedSpacesInCommunity.addAll(childrenIds);
|
selectedSpacesInCommunity.addAll(childrenIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> spaces =
|
List<String> spaces = _getThePathToChild(event.communityModel.uuid, event.spaceId);
|
||||||
_getThePathToChild(event.communityModel.uuid, event.spaceId);
|
|
||||||
for (String space in spaces) {
|
for (String space in spaces) {
|
||||||
if (!updatedSelectedSpaces.contains(space) &&
|
if (!updatedSelectedSpaces.contains(space) && !updatedSoldChecks.contains(space)) {
|
||||||
!updatedSoldChecks.contains(space)) {
|
|
||||||
updatedSoldChecks.add(space);
|
updatedSoldChecks.add(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,9 +240,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
updatedSoldChecks.remove(event.spaceId);
|
updatedSoldChecks.remove(event.spaceId);
|
||||||
|
|
||||||
List<String> parents =
|
List<String> parents =
|
||||||
_getThePathToChild(event.communityModel.uuid, event.spaceId)
|
_getThePathToChild(event.communityModel.uuid, event.spaceId).toSet().toList();
|
||||||
.toSet()
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
if (updatedSelectedSpaces.isEmpty) {
|
if (updatedSelectedSpaces.isEmpty) {
|
||||||
updatedSoldChecks.removeWhere(parents.contains);
|
updatedSoldChecks.removeWhere(parents.contains);
|
||||||
@@ -236,8 +248,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
} else {
|
} else {
|
||||||
// Check if any parent has selected children
|
// Check if any parent has selected children
|
||||||
for (String space in parents) {
|
for (String space in parents) {
|
||||||
if (!_noChildrenSelected(
|
if (!_noChildrenSelected(event.communityModel, space, updatedSelectedSpaces, parents)) {
|
||||||
event.communityModel, space, updatedSelectedSpaces, parents)) {
|
|
||||||
updatedSoldChecks.remove(space);
|
updatedSoldChecks.remove(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,8 +273,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_noChildrenSelected(CommunityModel community, String spaceId,
|
_noChildrenSelected(
|
||||||
List<String> selectedSpaces, List<String> parents) {
|
CommunityModel community, String spaceId, List<String> selectedSpaces, List<String> parents) {
|
||||||
if (selectedSpaces.contains(spaceId)) {
|
if (selectedSpaces.contains(spaceId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -285,29 +296,52 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
_onSearch(SearchQueryEvent event, Emitter<SpaceTreeState> emit) async {
|
_onSearch(SearchQueryEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
try {
|
try {
|
||||||
List<CommunityModel> communities = List.from(state.communityList);
|
const duration = Duration(seconds: 1);
|
||||||
List<CommunityModel> filteredCommunity = [];
|
if (_timer.isActive) {
|
||||||
|
_timer.cancel(); // clear timer
|
||||||
|
}
|
||||||
|
_timer = Timer(duration, () async => add(DebouncedSearchEvent(event.searchQuery)));
|
||||||
|
|
||||||
|
// List<CommunityModel> communities = List.from(state.communityList);
|
||||||
|
// List<CommunityModel> filteredCommunity = [];
|
||||||
|
|
||||||
// Filter communities and expand only those that match the query
|
// Filter communities and expand only those that match the query
|
||||||
filteredCommunity = communities.where((community) {
|
// filteredCommunity = communities.where((community) {
|
||||||
final containsQueryInCommunity = community.name
|
// final containsQueryInCommunity =
|
||||||
.toLowerCase()
|
// community.name.toLowerCase().contains(event.searchQuery.toLowerCase());
|
||||||
.contains(event.searchQuery.toLowerCase());
|
// final containsQueryInSpaces =
|
||||||
final containsQueryInSpaces = community.spaces.any(
|
// community.spaces.any((space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
||||||
(space) => _containsQuery(space, event.searchQuery.toLowerCase()));
|
|
||||||
|
|
||||||
return containsQueryInCommunity || containsQueryInSpaces;
|
// return containsQueryInCommunity || containsQueryInSpaces;
|
||||||
}).toList();
|
// }).toList();
|
||||||
|
|
||||||
emit(state.copyWith(
|
// emit(state.copyWith(
|
||||||
filteredCommunity: filteredCommunity,
|
// filteredCommunity: filteredCommunity,
|
||||||
isSearching: event.searchQuery.isNotEmpty,
|
// isSearching: event.searchQuery.isNotEmpty,
|
||||||
searchQuery: event.searchQuery));
|
// searchQuery: event.searchQuery));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(const SpaceTreeErrorState('Something went wrong'));
|
emit(const SpaceTreeErrorState('Something went wrong'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onDebouncedSearch(DebouncedSearchEvent event, Emitter<SpaceTreeState> emit) async {
|
||||||
|
emit(state.copyWith(
|
||||||
|
isSearching: true,
|
||||||
|
));
|
||||||
|
PaginationModel paginationModel = const PaginationModel.emptyConstructor();
|
||||||
|
try {
|
||||||
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
|
paginationModel = await CommunitySpaceManagementApi()
|
||||||
|
.fetchCommunitiesAndSpaces(projectId: projectUuid, page: 1, search: event.searchQuery);
|
||||||
|
} catch (_) {}
|
||||||
|
|
||||||
|
emit(state.copyWith(
|
||||||
|
filteredCommunity: paginationModel.communities,
|
||||||
|
isSearching: false,
|
||||||
|
searchQuery: event.searchQuery));
|
||||||
|
}
|
||||||
|
|
||||||
_clearAllData(ClearAllData event, Emitter<SpaceTreeState> emit) async {
|
_clearAllData(ClearAllData event, Emitter<SpaceTreeState> emit) async {
|
||||||
try {
|
try {
|
||||||
emit(state.copyWith(
|
emit(state.copyWith(
|
||||||
@@ -345,13 +379,13 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to determine if any space or its children match the search query
|
// Helper function to determine if any space or its children match the search query
|
||||||
bool _containsQuery(SpaceModel space, String query) {
|
// bool _containsQuery(SpaceModel space, String query) {
|
||||||
final matchesSpace = space.name.toLowerCase().contains(query);
|
// final matchesSpace = space.name.toLowerCase().contains(query);
|
||||||
final matchesChildren = space.children.any((child) =>
|
// final matchesChildren =
|
||||||
_containsQuery(child, query)); // Recursive check for children
|
// space.children.any((child) => _containsQuery(child, query)); // Recursive check for children
|
||||||
|
|
||||||
return matchesSpace || matchesChildren;
|
// return matchesSpace || matchesChildren;
|
||||||
}
|
// }
|
||||||
|
|
||||||
List<String> _getAllChildIds(List<SpaceModel> spaces) {
|
List<String> _getAllChildIds(List<SpaceModel> spaces) {
|
||||||
List<String> ids = [];
|
List<String> ids = [];
|
||||||
@@ -371,8 +405,8 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _anySpacesSelectedInCommunity(CommunityModel community,
|
bool _anySpacesSelectedInCommunity(
|
||||||
List<String> selectedSpaces, List<String> partialCheckedList) {
|
CommunityModel community, List<String> selectedSpaces, List<String> partialCheckedList) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
List<String> ids = _getAllChildIds(community.spaces);
|
List<String> ids = _getAllChildIds(community.spaces);
|
||||||
for (var id in ids) {
|
for (var id in ids) {
|
||||||
@@ -401,8 +435,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> _getAllParentsIds(
|
List<String> _getAllParentsIds(SpaceModel child, String spaceId, List<String> listIds) {
|
||||||
SpaceModel child, String spaceId, List<String> listIds) {
|
|
||||||
List<String> ids = listIds;
|
List<String> ids = listIds;
|
||||||
|
|
||||||
ids.add(child.uuid ?? '');
|
ids.add(child.uuid ?? '');
|
||||||
@@ -426,6 +459,7 @@ class SpaceTreeBloc extends Bloc<SpaceTreeEvent, SpaceTreeState> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
_timer.cancel();
|
||||||
super.close();
|
super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.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';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
|
|
||||||
@@ -11,6 +12,16 @@ class SpaceTreeEvent extends Equatable {
|
|||||||
|
|
||||||
class InitialEvent extends SpaceTreeEvent {}
|
class InitialEvent extends SpaceTreeEvent {}
|
||||||
|
|
||||||
|
class PaginationEvent extends SpaceTreeEvent {
|
||||||
|
final PaginationModel paginationModel;
|
||||||
|
final List<CommunityModel> communities;
|
||||||
|
|
||||||
|
const PaginationEvent(this.paginationModel, this.communities);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [paginationModel, communities];
|
||||||
|
}
|
||||||
|
|
||||||
class SearchForSpace extends SpaceTreeEvent {
|
class SearchForSpace extends SpaceTreeEvent {
|
||||||
final String searchQuery;
|
final String searchQuery;
|
||||||
|
|
||||||
@@ -69,6 +80,15 @@ class SearchQueryEvent extends SpaceTreeEvent {
|
|||||||
List<Object> get props => [searchQuery];
|
List<Object> get props => [searchQuery];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DebouncedSearchEvent extends SpaceTreeEvent {
|
||||||
|
final String searchQuery;
|
||||||
|
|
||||||
|
const DebouncedSearchEvent(this.searchQuery);
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [searchQuery];
|
||||||
|
}
|
||||||
|
|
||||||
class OnCommunityAdded extends SpaceTreeEvent {
|
class OnCommunityAdded extends SpaceTreeEvent {
|
||||||
final CommunityModel newCommunity;
|
final CommunityModel newCommunity;
|
||||||
const OnCommunityAdded(this.newCommunity);
|
const OnCommunityAdded(this.newCommunity);
|
||||||
@@ -85,7 +105,6 @@ class OnCommunityUpdated extends SpaceTreeEvent {
|
|||||||
List<Object> get props => [updatedCommunity];
|
List<Object> get props => [updatedCommunity];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ClearAllData extends SpaceTreeEvent {}
|
class ClearAllData extends SpaceTreeEvent {}
|
||||||
|
|
||||||
class ClearCachedData extends SpaceTreeEvent {}
|
class ClearCachedData extends SpaceTreeEvent {}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.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 {
|
||||||
@@ -12,6 +13,8 @@ class SpaceTreeState extends Equatable {
|
|||||||
final List<String> soldCheck;
|
final List<String> soldCheck;
|
||||||
final bool isSearching;
|
final bool isSearching;
|
||||||
final String searchQuery;
|
final String searchQuery;
|
||||||
|
final PaginationModel paginationModel;
|
||||||
|
final bool paginationIsLoading;
|
||||||
|
|
||||||
const SpaceTreeState(
|
const SpaceTreeState(
|
||||||
{this.communityList = const [],
|
{this.communityList = const [],
|
||||||
@@ -23,7 +26,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
this.soldCheck = const [],
|
this.soldCheck = const [],
|
||||||
this.isSearching = false,
|
this.isSearching = false,
|
||||||
this.selectedCommunityAndSpaces = const {},
|
this.selectedCommunityAndSpaces = const {},
|
||||||
this.searchQuery = ''});
|
this.searchQuery = '',
|
||||||
|
this.paginationModel = const PaginationModel.emptyConstructor(),
|
||||||
|
this.paginationIsLoading = false});
|
||||||
|
|
||||||
SpaceTreeState copyWith(
|
SpaceTreeState copyWith(
|
||||||
{List<CommunityModel>? communitiesList,
|
{List<CommunityModel>? communitiesList,
|
||||||
@@ -35,7 +40,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
List<String>? soldCheck,
|
List<String>? soldCheck,
|
||||||
bool? isSearching,
|
bool? isSearching,
|
||||||
Map<String, List<String>>? selectedCommunityAndSpaces,
|
Map<String, List<String>>? selectedCommunityAndSpaces,
|
||||||
String? searchQuery}) {
|
String? searchQuery,
|
||||||
|
PaginationModel? paginationModel,
|
||||||
|
bool? paginationIsLoading}) {
|
||||||
return SpaceTreeState(
|
return SpaceTreeState(
|
||||||
communityList: communitiesList ?? this.communityList,
|
communityList: communitiesList ?? this.communityList,
|
||||||
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
filteredCommunity: filteredCommunity ?? this.filteredCommunity,
|
||||||
@@ -46,7 +53,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
soldCheck: soldCheck ?? this.soldCheck,
|
soldCheck: soldCheck ?? this.soldCheck,
|
||||||
isSearching: isSearching ?? this.isSearching,
|
isSearching: isSearching ?? this.isSearching,
|
||||||
selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces,
|
selectedCommunityAndSpaces: selectedCommunityAndSpaces ?? this.selectedCommunityAndSpaces,
|
||||||
searchQuery: searchQuery ?? this.searchQuery);
|
searchQuery: searchQuery ?? this.searchQuery,
|
||||||
|
paginationModel: paginationModel ?? this.paginationModel,
|
||||||
|
paginationIsLoading: paginationIsLoading ?? this.paginationIsLoading);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -60,7 +69,9 @@ class SpaceTreeState extends Equatable {
|
|||||||
soldCheck,
|
soldCheck,
|
||||||
isSearching,
|
isSearching,
|
||||||
selectedCommunityAndSpaces,
|
selectedCommunityAndSpaces,
|
||||||
searchQuery
|
searchQuery,
|
||||||
|
paginationModel,
|
||||||
|
paginationIsLoading
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart';
|
||||||
|
|
||||||
|
class PaginationModel {
|
||||||
|
final int pageNum;
|
||||||
|
final bool hasNext;
|
||||||
|
final int size;
|
||||||
|
final List<CommunityModel> communities;
|
||||||
|
|
||||||
|
const PaginationModel(
|
||||||
|
{required this.pageNum,
|
||||||
|
required this.hasNext,
|
||||||
|
required this.size,
|
||||||
|
required this.communities});
|
||||||
|
|
||||||
|
const PaginationModel.emptyConstructor()
|
||||||
|
: pageNum = 1,
|
||||||
|
hasNext = true,
|
||||||
|
size = 10,
|
||||||
|
communities = const [];
|
||||||
|
}
|
||||||
@@ -34,7 +34,8 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(builder: (context, state) {
|
return BlocBuilder<SpaceTreeBloc, SpaceTreeState>(builder: (context, state) {
|
||||||
List<CommunityModel> list = state.isSearching ? state.filteredCommunity : state.communityList;
|
List<CommunityModel> list =
|
||||||
|
state.searchQuery.isNotEmpty ? state.filteredCommunity : state.communityList;
|
||||||
return Container(
|
return Container(
|
||||||
height: MediaQuery.sizeOf(context).height,
|
height: MediaQuery.sizeOf(context).height,
|
||||||
decoration: widget.isSide == true
|
decoration: widget.isSide == true
|
||||||
@@ -61,7 +62,8 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
border: Border.all(color: ColorsManager.grayBorder)),
|
border: Border.all(color: ColorsManager.grayBorder)),
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
style: const TextStyle(color: Colors.black),
|
style: context.textTheme.bodyMedium
|
||||||
|
?.copyWith(color: ColorsManager.blackColor),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context.read<SpaceTreeBloc>().add(SearchQueryEvent(value));
|
context.read<SpaceTreeBloc>().add(SearchQueryEvent(value));
|
||||||
},
|
},
|
||||||
@@ -94,88 +96,101 @@ class _SpaceTreeViewState extends State<SpaceTreeView> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(
|
child: state.isSearching
|
||||||
shrinkWrap: true,
|
? const Center(child: CircularProgressIndicator())
|
||||||
scrollDirection: Axis.horizontal,
|
: ListView(
|
||||||
children: [
|
shrinkWrap: true,
|
||||||
Container(
|
scrollDirection: Axis.horizontal,
|
||||||
width: MediaQuery.sizeOf(context).width * 0.5,
|
children: [
|
||||||
padding: const EdgeInsets.all(8.0),
|
Container(
|
||||||
child: list.isEmpty
|
width: MediaQuery.sizeOf(context).width * 0.5,
|
||||||
? Center(
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Text(
|
child: list.isEmpty
|
||||||
'No results found',
|
? Center(
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
child: Text(
|
||||||
color: ColorsManager.lightGrayColor,
|
'No results found',
|
||||||
fontWeight: FontWeight.w400,
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
|
color: ColorsManager.lightGrayColor,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
: Scrollbar(
|
||||||
: Scrollbar(
|
scrollbarOrientation: ScrollbarOrientation.left,
|
||||||
scrollbarOrientation: ScrollbarOrientation.left,
|
thumbVisibility: true,
|
||||||
thumbVisibility: true,
|
controller: _scrollController,
|
||||||
controller: _scrollController,
|
child: NotificationListener(
|
||||||
child: Padding(
|
onNotification: (notification) {
|
||||||
padding: const EdgeInsets.only(left: 16),
|
if (notification is ScrollEndNotification &&
|
||||||
child: ListView(
|
notification.metrics.extentAfter == 0) {
|
||||||
controller: _scrollController,
|
// If the user has reached the end of the list Load more data
|
||||||
shrinkWrap: true,
|
context.read<SpaceTreeBloc>().add(PaginationEvent(
|
||||||
children: list
|
state.paginationModel, state.communityList));
|
||||||
.map(
|
}
|
||||||
(community) => CustomExpansionTileSpaceTree(
|
return false;
|
||||||
title: community.name,
|
},
|
||||||
isSelected: state.selectedCommunities
|
child: Padding(
|
||||||
.contains(community.uuid),
|
padding: const EdgeInsets.only(left: 16),
|
||||||
isSoldCheck: state.selectedCommunities
|
child: ListView.builder(
|
||||||
.contains(community.uuid),
|
shrinkWrap: true,
|
||||||
onExpansionChanged: () {
|
itemCount: list.length,
|
||||||
context
|
controller: _scrollController,
|
||||||
.read<SpaceTreeBloc>()
|
itemBuilder: (context, index) {
|
||||||
.add(OnCommunityExpanded(community.uuid));
|
return CustomExpansionTileSpaceTree(
|
||||||
},
|
title: list[index].name,
|
||||||
isExpanded: state.expandedCommunities
|
isSelected: state.selectedCommunities
|
||||||
.contains(community.uuid),
|
.contains(list[index].uuid),
|
||||||
onItemSelected: () {
|
isSoldCheck: state.selectedCommunities
|
||||||
context.read<SpaceTreeBloc>().add(
|
.contains(list[index].uuid),
|
||||||
OnCommunitySelected(
|
onExpansionChanged: () {
|
||||||
community.uuid, community.spaces));
|
context.read<SpaceTreeBloc>().add(
|
||||||
widget.onSelect();
|
OnCommunityExpanded(list[index].uuid));
|
||||||
},
|
},
|
||||||
children: community.spaces.map((space) {
|
isExpanded: state.expandedCommunities
|
||||||
return CustomExpansionTileSpaceTree(
|
.contains(list[index].uuid),
|
||||||
title: space.name,
|
onItemSelected: () {
|
||||||
isExpanded:
|
context.read<SpaceTreeBloc>().add(
|
||||||
state.expandedSpaces.contains(space.uuid),
|
OnCommunitySelected(list[index].uuid,
|
||||||
onItemSelected: () {
|
list[index].spaces));
|
||||||
context.read<SpaceTreeBloc>().add(
|
widget.onSelect();
|
||||||
OnSpaceSelected(community, space.uuid ?? '',
|
},
|
||||||
space.children));
|
children: list[index].spaces.map((space) {
|
||||||
widget.onSelect();
|
return CustomExpansionTileSpaceTree(
|
||||||
},
|
title: space.name,
|
||||||
onExpansionChanged: () {
|
isExpanded: state.expandedSpaces
|
||||||
context.read<SpaceTreeBloc>().add(
|
.contains(space.uuid),
|
||||||
OnSpaceExpanded(
|
onItemSelected: () {
|
||||||
community.uuid, space.uuid ?? ''));
|
context.read<SpaceTreeBloc>().add(
|
||||||
},
|
OnSpaceSelected(
|
||||||
isSelected:
|
list[index],
|
||||||
state.selectedSpaces.contains(space.uuid) ||
|
space.uuid ?? '',
|
||||||
state.soldCheck.contains(space.uuid),
|
space.children));
|
||||||
isSoldCheck: state.soldCheck.contains(space.uuid),
|
widget.onSelect();
|
||||||
children: _buildNestedSpaces(
|
},
|
||||||
context, state, space, community),
|
onExpansionChanged: () {
|
||||||
);
|
context.read<SpaceTreeBloc>().add(
|
||||||
}).toList(),
|
OnSpaceExpanded(list[index].uuid,
|
||||||
),
|
space.uuid ?? ''));
|
||||||
)
|
},
|
||||||
.toList(),
|
isSelected: state.selectedSpaces
|
||||||
),
|
.contains(space.uuid) ||
|
||||||
),
|
state.soldCheck.contains(space.uuid),
|
||||||
),
|
isSoldCheck:
|
||||||
),
|
state.soldCheck.contains(space.uuid),
|
||||||
],
|
children: _buildNestedSpaces(
|
||||||
),
|
context, state, space, list[index]),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
if (state.paginationIsLoading) const CircularProgressIndicator(),
|
||||||
// Expanded(
|
// Expanded(
|
||||||
// child: Padding(
|
// child: Padding(
|
||||||
// padding: const EdgeInsets.all(8.0),
|
// padding: const EdgeInsets.all(8.0),
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ class CommunityModel {
|
|||||||
|
|
||||||
factory CommunityModel.fromJson(Map<String, dynamic> json) {
|
factory CommunityModel.fromJson(Map<String, dynamic> json) {
|
||||||
return CommunityModel(
|
return CommunityModel(
|
||||||
uuid: json['uuid'],
|
uuid: json['uuid'] ?? '',
|
||||||
createdAt: DateTime.parse(json['createdAt']),
|
createdAt: DateTime.parse(json['createdAt'] ?? ''),
|
||||||
updatedAt: DateTime.parse(json['updatedAt']),
|
updatedAt: DateTime.parse(json['updatedAt'] ?? ''),
|
||||||
name: json['name'],
|
name: json['name'] ?? '',
|
||||||
description: json['description'],
|
description: json['description'] ?? '',
|
||||||
region: json['region'] != null ? RegionModel.fromJson(json['region']) : null,
|
region: json['region'] != null ? RegionModel.fromJson(json['region']) : null,
|
||||||
spaces: json['spaces'] != null
|
spaces: json['spaces'] != null
|
||||||
? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList()
|
? (json['spaces'] as List).map((space) => SpaceModel.fromJson(space)).toList()
|
||||||
|
|||||||
@@ -301,11 +301,18 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
SpaceTemplateModel? spaceModel, List<SubspaceModel>? subspaces, List<Tag>? tags) {
|
SpaceTemplateModel? spaceModel, List<SubspaceModel>? subspaces, List<Tag>? tags) {
|
||||||
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 = position ?? ConnectionHelper.getCenterPosition(screenSize);
|
Offset newPosition;
|
||||||
|
if (parentIndex != null) {
|
||||||
|
newPosition =
|
||||||
|
getBalancedChildPosition(spaces[parentIndex]); // Ensure balanced position
|
||||||
|
} else {
|
||||||
|
newPosition = position ?? ConnectionHelper.getCenterPosition(screenSize);
|
||||||
|
}
|
||||||
|
|
||||||
SpaceModel newSpace = SpaceModel(
|
SpaceModel newSpace = SpaceModel(
|
||||||
name: name,
|
name: name,
|
||||||
icon: icon,
|
icon: icon,
|
||||||
position: centerPosition,
|
position: newPosition,
|
||||||
isPrivate: false,
|
isPrivate: false,
|
||||||
children: [],
|
children: [],
|
||||||
status: SpaceStatus.newSpace,
|
status: SpaceStatus.newSpace,
|
||||||
@@ -425,7 +432,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
Connection(
|
Connection(
|
||||||
startSpace: parent,
|
startSpace: parent,
|
||||||
endSpace: child,
|
endSpace: child,
|
||||||
direction: child.incomingConnection?.direction ?? "down",
|
direction: "down",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -522,6 +529,38 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Offset getBalancedChildPosition(SpaceModel parent) {
|
||||||
|
int totalSiblings = parent.children.length + 1;
|
||||||
|
double totalWidth = (totalSiblings - 1) * 250; // Horizontal spacing
|
||||||
|
double startX = parent.position.dx - (totalWidth / 2);
|
||||||
|
|
||||||
|
Offset position = Offset(startX + (parent.children.length * 250), parent.position.dy + 180);
|
||||||
|
|
||||||
|
// Check for overlaps & adjust
|
||||||
|
while (spaces.any((s) => (s.position - position).distance < 250)) {
|
||||||
|
position = Offset(position.dx + 250, position.dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
void realignTree() {
|
||||||
|
void updatePositions(SpaceModel node, double x, double y) {
|
||||||
|
node.position = Offset(x, y);
|
||||||
|
|
||||||
|
int numChildren = node.children.length;
|
||||||
|
double childStartX = x - ((numChildren - 1) * 250) / 2;
|
||||||
|
|
||||||
|
for (int i = 0; i < numChildren; i++) {
|
||||||
|
updatePositions(node.children[i], childStartX + (i * 250), y + 180);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spaces.isNotEmpty) {
|
||||||
|
updatePositions(spaces.first, spaces.first.position.dx, spaces.first.position.dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _onDuplicate(BuildContext parentContext) {
|
void _onDuplicate(BuildContext parentContext) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
@@ -604,29 +643,57 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
|
|||||||
|
|
||||||
void _duplicateSpace(SpaceModel space) {
|
void _duplicateSpace(SpaceModel space) {
|
||||||
final Map<SpaceModel, SpaceModel> originalToDuplicate = {};
|
final Map<SpaceModel, SpaceModel> originalToDuplicate = {};
|
||||||
const double horizontalGap = 200.0;
|
double horizontalGap = 250.0; // Increased spacing
|
||||||
const double verticalGap = 100.0;
|
double verticalGap = 180.0; // Adjusted for better visualization
|
||||||
|
|
||||||
SpaceModel duplicateRecursive(
|
print("🟢 Duplicating: ${space.name}");
|
||||||
SpaceModel original, Offset parentPosition, SpaceModel? duplicatedParent) {
|
|
||||||
Offset newPosition = Offset(parentPosition.dx + horizontalGap, original.position.dy);
|
|
||||||
|
|
||||||
while (spaces.any((s) =>
|
/// **Find a new position ensuring no overlap**
|
||||||
(s.position - newPosition).distance < horizontalGap && s.status != SpaceStatus.deleted)) {
|
Offset getBalancedChildPosition(SpaceModel parent) {
|
||||||
newPosition += Offset(horizontalGap, 0);
|
int totalSiblings = parent.children.length + 1;
|
||||||
|
double totalWidth = (totalSiblings - 1) * horizontalGap;
|
||||||
|
double startX = parent.position.dx - (totalWidth / 2);
|
||||||
|
Offset position = Offset(
|
||||||
|
startX + (parent.children.length * horizontalGap), parent.position.dy + verticalGap);
|
||||||
|
|
||||||
|
// **Check for overlaps & adjust**
|
||||||
|
while (spaces.any((s) => (s.position - position).distance < horizontalGap)) {
|
||||||
|
position = Offset(position.dx + horizontalGap, position.dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("🔹 New position for ${parent.name}: (${position.dx}, ${position.dy})");
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// **Realign the entire tree after duplication**
|
||||||
|
void realignTree() {
|
||||||
|
void updatePositions(SpaceModel node, double x, double y) {
|
||||||
|
node.position = Offset(x, y);
|
||||||
|
print("✅ Adjusted ${node.name} to (${x}, ${y})");
|
||||||
|
|
||||||
|
int numChildren = node.children.length;
|
||||||
|
double childStartX = x - ((numChildren - 1) * horizontalGap) / 2;
|
||||||
|
|
||||||
|
for (int i = 0; i < numChildren; i++) {
|
||||||
|
updatePositions(node.children[i], childStartX + (i * horizontalGap), y + verticalGap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spaces.isNotEmpty) {
|
||||||
|
print("🔄 Realigning tree...");
|
||||||
|
updatePositions(spaces.first, spaces.first.position.dx, spaces.first.position.dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// **Recursive duplication logic**
|
||||||
|
SpaceModel duplicateRecursive(SpaceModel original, SpaceModel? duplicatedParent) {
|
||||||
|
Offset newPosition = duplicatedParent == null
|
||||||
|
? Offset(original.position.dx + horizontalGap, original.position.dy)
|
||||||
|
: getBalancedChildPosition(duplicatedParent);
|
||||||
|
|
||||||
final duplicatedName = SpaceHelper.generateUniqueSpaceName(original.name, spaces);
|
final duplicatedName = SpaceHelper.generateUniqueSpaceName(original.name, spaces);
|
||||||
|
print(
|
||||||
final List<SubspaceModel>? duplicatedSubspaces;
|
"🟡 Duplicating ${original.name} → ${duplicatedName} at (${newPosition.dx}, ${newPosition.dy})");
|
||||||
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,
|
||||||
@@ -637,12 +704,10 @@ 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;
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
spaces.add(duplicated);
|
spaces.add(duplicated);
|
||||||
_updateNodePosition(duplicated, duplicated.position);
|
_updateNodePosition(duplicated, duplicated.position);
|
||||||
@@ -651,60 +716,42 @@ 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;
|
||||||
duplicatedParent.addOutgoingConnection(newConnection);
|
duplicatedParent.addOutgoingConnection(newConnection);
|
||||||
|
duplicatedParent.children.add(duplicated);
|
||||||
|
print("🔗 Created connection: ${duplicatedParent.name} → ${duplicated.name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (original.parent != null && duplicatedParent == null) {
|
// **Recalculate the whole tree to avoid overlaps**
|
||||||
final originalParent = original.parent!;
|
realignTree();
|
||||||
final duplicatedParent = originalToDuplicate[originalParent] ?? originalParent;
|
|
||||||
|
|
||||||
final parentConnection = Connection(
|
|
||||||
startSpace: duplicatedParent,
|
|
||||||
endSpace: duplicated,
|
|
||||||
direction: original.incomingConnection?.direction ?? "down",
|
|
||||||
);
|
|
||||||
|
|
||||||
connections.add(parentConnection);
|
|
||||||
duplicated.incomingConnection = parentConnection;
|
|
||||||
duplicatedParent.addOutgoingConnection(parentConnection);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final childrenWithDownDirection = original.children
|
// Recursively duplicate children
|
||||||
.where((child) =>
|
for (var child in original.children) {
|
||||||
child.incomingConnection?.direction == "down" && child.status != SpaceStatus.deleted)
|
duplicateRecursive(child, duplicated);
|
||||||
.toList();
|
|
||||||
|
|
||||||
Offset childStartPosition = childrenWithDownDirection.length == 1
|
|
||||||
? duplicated.position
|
|
||||||
: newPosition + Offset(0, verticalGap);
|
|
||||||
|
|
||||||
for (final child in original.children) {
|
|
||||||
final isDownDirection = child.incomingConnection?.direction == "down" ?? false;
|
|
||||||
|
|
||||||
if (isDownDirection && childrenWithDownDirection.length == 1) {
|
|
||||||
childStartPosition = duplicated.position + Offset(0, verticalGap);
|
|
||||||
} else if (!isDownDirection) {
|
|
||||||
childStartPosition = duplicated.position + Offset(horizontalGap, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final duplicatedChild = duplicateRecursive(child, childStartPosition, duplicated);
|
|
||||||
duplicated.children.add(duplicatedChild);
|
|
||||||
childStartPosition += Offset(0, verticalGap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return duplicated;
|
return duplicated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **Handle root duplication**
|
||||||
if (space.parent == null) {
|
if (space.parent == null) {
|
||||||
duplicateRecursive(space, space.position, null);
|
print("🟠 Duplicating root node: ${space.name}");
|
||||||
|
SpaceModel duplicatedRoot = duplicateRecursive(space, null);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
spaces.add(duplicatedRoot);
|
||||||
|
realignTree();
|
||||||
|
});
|
||||||
|
|
||||||
|
print("✅ Root duplication successful: ${duplicatedRoot.name}");
|
||||||
} else {
|
} else {
|
||||||
final duplicatedParent = originalToDuplicate[space.parent!] ?? space.parent!;
|
duplicateRecursive(space, space.parent);
|
||||||
duplicateRecursive(space, space.position, duplicatedParent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("🟢 Finished duplication process for: ${space.name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,18 +47,6 @@ class SpaceCardWidget extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
buildSpaceContainer(index), // Build the space container
|
buildSpaceContainer(index), // Build the space container
|
||||||
if (isHovered) ...[
|
if (isHovered) ...[
|
||||||
PlusButtonWidget(
|
|
||||||
index: index,
|
|
||||||
direction: 'left',
|
|
||||||
offset: const Offset(-21, 20),
|
|
||||||
onButtonTap: onButtonTap,
|
|
||||||
),
|
|
||||||
PlusButtonWidget(
|
|
||||||
index: index,
|
|
||||||
direction: 'right',
|
|
||||||
offset: const Offset(140, 20),
|
|
||||||
onButtonTap: onButtonTap,
|
|
||||||
),
|
|
||||||
PlusButtonWidget(
|
PlusButtonWidget(
|
||||||
index: index,
|
index: index,
|
||||||
direction: 'down',
|
direction: 'down',
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_m
|
|||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart';
|
||||||
|
|
||||||
class SpaceHelper {
|
class SpaceHelper {
|
||||||
static SpaceModel? findSpaceByUuid(
|
static SpaceModel? findSpaceByUuid(String? uuid, List<CommunityModel> communities) {
|
||||||
String? uuid, List<CommunityModel> communities) {
|
|
||||||
for (var community in communities) {
|
for (var community in communities) {
|
||||||
for (var space in community.spaces) {
|
for (var space in community.spaces) {
|
||||||
if (space.uuid == uuid) return space;
|
if (space.uuid == uuid) return space;
|
||||||
@@ -12,8 +11,7 @@ class SpaceHelper {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpaceModel? findSpaceByInternalId(
|
static SpaceModel? findSpaceByInternalId(String? internalId, List<SpaceModel> spaces) {
|
||||||
String? internalId, List<SpaceModel> spaces) {
|
|
||||||
if (internalId != null) {
|
if (internalId != null) {
|
||||||
for (var space in spaces) {
|
for (var space in spaces) {
|
||||||
if (space.internalId == internalId) return space;
|
if (space.internalId == internalId) return space;
|
||||||
@@ -23,8 +21,7 @@ class SpaceHelper {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String generateUniqueSpaceName(
|
static String generateUniqueSpaceName(String originalName, List<SpaceModel> spaces) {
|
||||||
String originalName, List<SpaceModel> spaces) {
|
|
||||||
final baseName = originalName.replaceAll(RegExp(r'\(\d+\)$'), '').trim();
|
final baseName = originalName.replaceAll(RegExp(r'\(\d+\)$'), '').trim();
|
||||||
int maxNumber = 0;
|
int maxNumber = 0;
|
||||||
|
|
||||||
@@ -54,13 +51,10 @@ class SpaceHelper {
|
|||||||
|
|
||||||
return space == selectedSpace ||
|
return space == selectedSpace ||
|
||||||
selectedSpace.parent?.internalId == space.internalId ||
|
selectedSpace.parent?.internalId == space.internalId ||
|
||||||
selectedSpace.children
|
selectedSpace.children?.any((child) => child.internalId == space.internalId) == true;
|
||||||
?.any((child) => child.internalId == space.internalId) ==
|
|
||||||
true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isNameConflict(
|
static bool isNameConflict(String value, SpaceModel? parentSpace, SpaceModel? editSpace) {
|
||||||
String value, SpaceModel? parentSpace, SpaceModel? editSpace) {
|
|
||||||
final siblings = parentSpace?.children
|
final siblings = parentSpace?.children
|
||||||
.where((child) => child.internalId != editSpace?.internalId)
|
.where((child) => child.internalId != editSpace?.internalId)
|
||||||
.toList() ??
|
.toList() ??
|
||||||
@@ -71,19 +65,17 @@ class SpaceHelper {
|
|||||||
.toList() ??
|
.toList() ??
|
||||||
[];
|
[];
|
||||||
|
|
||||||
final editSiblingConflict =
|
final editSiblingConflict = editSiblings.any((child) => child.name == value);
|
||||||
editSiblings.any((child) => child.name == value);
|
|
||||||
|
|
||||||
final siblingConflict = siblings.any((child) => child.name == value);
|
final siblingConflict = siblings.any((child) => child.name == value);
|
||||||
|
|
||||||
final parentConflict = parentSpace?.name == value &&
|
final parentConflict =
|
||||||
parentSpace?.internalId != editSpace?.internalId;
|
parentSpace?.name == value && parentSpace?.internalId != editSpace?.internalId;
|
||||||
|
|
||||||
final parentOfEditSpaceConflict = editSpace?.parent?.name == value &&
|
final parentOfEditSpaceConflict =
|
||||||
editSpace?.parent?.internalId != editSpace?.internalId;
|
editSpace?.parent?.name == value && editSpace?.parent?.internalId != editSpace?.internalId;
|
||||||
|
|
||||||
final childConflict =
|
final childConflict = editSpace?.children.any((child) => child.name == value) ?? false;
|
||||||
editSpace?.children.any((child) => child.name == value) ?? false;
|
|
||||||
|
|
||||||
return siblingConflict ||
|
return siblingConflict ||
|
||||||
parentConflict ||
|
parentConflict ||
|
||||||
|
|||||||
@@ -194,9 +194,10 @@ class VisitorPasswordBloc
|
|||||||
emit(DeviceLoaded());
|
emit(DeviceLoaded());
|
||||||
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
final projectUuid = await ProjectManager.getProjectUUID() ?? '';
|
||||||
|
|
||||||
data = await AccessMangApi().fetchDevices(projectUuid);
|
data = await AccessMangApi().fetchDoorLockDeviceList(projectUuid);
|
||||||
emit(TableLoaded(data));
|
emit(TableLoaded(data));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
print("error: $e");
|
||||||
emit(FailedState(e.toString()));
|
emit(FailedState(e.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,23 @@ import 'package:syncrow_web/services/api/http_service.dart';
|
|||||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||||
|
|
||||||
class AccessMangApi {
|
class AccessMangApi {
|
||||||
|
AccessMangApi() {
|
||||||
|
_validateEndpoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _validateEndpoints() {
|
||||||
|
if (!ApiEndpoints.getDevices.contains('{projectId}')) {
|
||||||
|
throw Exception("Endpoint 'getDevices' must contain '{projectId}' placeholder.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<PasswordModel>> fetchVisitorPassword(String projectId) async {
|
Future<List<PasswordModel>> fetchVisitorPassword(String projectId) async {
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.visitorPassword.replaceAll('{projectId}', projectId),
|
path: ApiEndpoints.visitorPassword,
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
List<dynamic> jsonData = json;
|
List<dynamic> jsonData = json['data'] ?? [];
|
||||||
List<PasswordModel> passwordList = jsonData.map((jsonItem) {
|
List<PasswordModel> passwordList = jsonData.map((jsonItem) {
|
||||||
return PasswordModel.fromJson(jsonItem);
|
return PasswordModel.fromJson(jsonItem);
|
||||||
}).toList();
|
}).toList();
|
||||||
@@ -25,17 +35,22 @@ class AccessMangApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future fetchDevices(String projectId) async {
|
Future fetchDoorLockDeviceList(String projectId) async {
|
||||||
try {
|
try {
|
||||||
|
// The endpoint structure is already validated during initialization.
|
||||||
|
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getDevices.replaceAll('{projectId}', projectId),
|
path: ApiEndpoints.getDevices.replaceAll('{projectId}', projectId),
|
||||||
|
queryParameters: {
|
||||||
|
'deviceType': 'DOOR_LOCK',
|
||||||
|
},
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
List<dynamic> jsonData = json;
|
List<dynamic> jsonData = json['data'] ?? [];
|
||||||
List<DeviceModel> passwordList = jsonData.map((jsonItem) {
|
List<DeviceModel> deviceList = jsonData.map((jsonItem) {
|
||||||
return DeviceModel.fromJson(jsonItem);
|
return DeviceModel.fromJson(jsonItem);
|
||||||
}).toList();
|
}).toList();
|
||||||
return passwordList;
|
return deviceList;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
@@ -52,14 +67,15 @@ class AccessMangApi {
|
|||||||
String? invalidTime,
|
String? invalidTime,
|
||||||
List<String>? devicesUuid}) async {
|
List<String>? devicesUuid}) async {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.sendOnlineOneTime,
|
path: ApiEndpoints.visitorPassword,
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
"email": email,
|
"email": email,
|
||||||
"passwordName": passwordName,
|
"passwordName": passwordName,
|
||||||
"password": password,
|
"password": password,
|
||||||
"devicesUuid": devicesUuid,
|
"devicesUuid": devicesUuid,
|
||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime
|
"invalidTime": invalidTime,
|
||||||
|
"operationType": "ONLINE_ONE_TIME",
|
||||||
}),
|
}),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@@ -84,13 +100,13 @@ class AccessMangApi {
|
|||||||
"password": password,
|
"password": password,
|
||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
|
"operationType": "ONLINE_MULTIPLE_TIME",
|
||||||
};
|
};
|
||||||
if (scheduleList != null) {
|
if (scheduleList != null) {
|
||||||
body["scheduleList"] =
|
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
|
||||||
scheduleList.map((schedule) => schedule.toJson()).toList();
|
|
||||||
}
|
}
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.sendOnlineMultipleTime,
|
path: ApiEndpoints.visitorPassword,
|
||||||
body: jsonEncode(body),
|
body: jsonEncode(body),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
@@ -105,8 +121,9 @@ class AccessMangApi {
|
|||||||
Future postOffLineOneTime(
|
Future postOffLineOneTime(
|
||||||
{String? email, String? passwordName, List<String>? devicesUuid}) async {
|
{String? email, String? passwordName, List<String>? devicesUuid}) async {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.sendOffLineOneTime,
|
path: ApiEndpoints.visitorPassword,
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
|
"operationType": "OFFLINE_ONE_TIME",
|
||||||
"email": email,
|
"email": email,
|
||||||
"passwordName": passwordName,
|
"passwordName": passwordName,
|
||||||
"devicesUuid": devicesUuid
|
"devicesUuid": devicesUuid
|
||||||
@@ -126,13 +143,14 @@ class AccessMangApi {
|
|||||||
String? invalidTime,
|
String? invalidTime,
|
||||||
List<String>? devicesUuid}) async {
|
List<String>? devicesUuid}) async {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.sendOffLineMultipleTime,
|
path: ApiEndpoints.visitorPassword,
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
"email": email,
|
"email": email,
|
||||||
"devicesUuid": devicesUuid,
|
"devicesUuid": devicesUuid,
|
||||||
"passwordName": passwordName,
|
"passwordName": passwordName,
|
||||||
"effectiveTime": effectiveTime,
|
"effectiveTime": effectiveTime,
|
||||||
"invalidTime": invalidTime,
|
"invalidTime": invalidTime,
|
||||||
|
"operationType": "OFFLINE_MULTIPLE_TIME",
|
||||||
}),
|
}),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ class DevicesManagementApi {
|
|||||||
: ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
|
: ApiEndpoints.getAllDevices.replaceAll('{projectId}', projectId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
List<dynamic> jsonData = communityId.isNotEmpty && spaceId.isNotEmpty
|
List<dynamic> jsonData = json['data'];
|
||||||
? 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();
|
||||||
@@ -34,7 +32,7 @@ class DevicesManagementApi {
|
|||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('fetchDevices Error fetching $e');
|
debugPrint('Error fetching device $e');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +43,7 @@ class DevicesManagementApi {
|
|||||||
path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid),
|
path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return DeviceStatus.fromJson(json);
|
return DeviceStatus.fromJson(json['data']);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
@@ -62,7 +60,7 @@ class DevicesManagementApi {
|
|||||||
Future getPowerClampInfo(String deviceId) async {
|
Future getPowerClampInfo(String deviceId) async {
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId),
|
path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', deviceId),
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return json;
|
return json;
|
||||||
@@ -93,13 +91,13 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deviceBatchControl(
|
Future<bool> deviceBatchControl(List<String> uuids, String code, dynamic value) async {
|
||||||
List<String> uuids, String code, dynamic value) async {
|
|
||||||
try {
|
try {
|
||||||
final body = {
|
final body = {
|
||||||
'devicesUuid': uuids,
|
'devicesUuid': uuids,
|
||||||
'code': code,
|
'code': code,
|
||||||
'value': value,
|
'value': value,
|
||||||
|
'operationType': 'COMMAND',
|
||||||
};
|
};
|
||||||
|
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
@@ -107,7 +105,7 @@ class DevicesManagementApi {
|
|||||||
body: body,
|
body: body,
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return (json['successResults'] as List).isNotEmpty;
|
return json['success'] ?? false;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -118,8 +116,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<DeviceModel>> getDevicesByGatewayId(
|
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
|
||||||
String gatewayId) async {
|
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
@@ -128,7 +125,7 @@ class DevicesManagementApi {
|
|||||||
if (json == null || json.isEmpty || json == []) {
|
if (json == null || json.isEmpty || json == []) {
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
for (var device in json['devices']) {
|
for (var device in json['data']['devices']) {
|
||||||
devices.add(DeviceModel.fromJson(device));
|
devices.add(DeviceModel.fromJson(device));
|
||||||
}
|
}
|
||||||
return devices;
|
return devices;
|
||||||
@@ -153,12 +150,10 @@ class DevicesManagementApi {
|
|||||||
String code,
|
String code,
|
||||||
) async {
|
) async {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getDeviceLogs
|
path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code),
|
||||||
.replaceAll('{uuid}', uuid)
|
|
||||||
.replaceAll('{code}', code),
|
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return DeviceReport.fromJson(json);
|
return DeviceReport.fromJson(json['data']);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
@@ -174,7 +169,7 @@ class DevicesManagementApi {
|
|||||||
.replaceAll('{endTime}', to ?? ''),
|
.replaceAll('{endTime}', to ?? ''),
|
||||||
showServerMessage: false,
|
showServerMessage: false,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return DeviceReport.fromJson(json);
|
return DeviceReport.fromJson(json['data']);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
@@ -190,7 +185,7 @@ class DevicesManagementApi {
|
|||||||
queryParameters: queryParameters,
|
queryParameters: queryParameters,
|
||||||
showServerMessage: true,
|
showServerMessage: true,
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return DeviceStatus.fromJson(json['status']);
|
return DeviceStatus.fromJson(json['data']['status']);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
return response;
|
return response;
|
||||||
@@ -228,8 +223,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> addScheduleRecord(
|
Future<bool> addScheduleRecord(ScheduleEntry sendSchedule, String uuid) async {
|
||||||
ScheduleEntry sendSchedule, String uuid) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||||
@@ -246,8 +240,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ScheduleModel>> getDeviceSchedules(
|
Future<List<ScheduleModel>> getDeviceSchedules(String uuid, String category) async {
|
||||||
String uuid, String category) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getScheduleByDeviceId
|
path: ApiEndpoints.getScheduleByDeviceId
|
||||||
@@ -270,9 +263,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> updateScheduleRecord(
|
Future<bool> updateScheduleRecord(
|
||||||
{required bool enable,
|
{required bool enable, required String uuid, required String scheduleId}) async {
|
||||||
required String uuid,
|
|
||||||
required String scheduleId}) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().put(
|
final response = await HTTPService().put(
|
||||||
path: ApiEndpoints.updateScheduleByDeviceId
|
path: ApiEndpoints.updateScheduleByDeviceId
|
||||||
@@ -293,8 +284,7 @@ class DevicesManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> editScheduleRecord(
|
Future<bool> editScheduleRecord(String uuid, ScheduleEntry newSchedule) async {
|
||||||
String uuid, ScheduleEntry newSchedule) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().put(
|
final response = await HTTPService().put(
|
||||||
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
path: ApiEndpoints.scheduleByDeviceId.replaceAll('{deviceUuid}', uuid),
|
||||||
|
|||||||
@@ -1,29 +1,28 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:syncrow_web/pages/space_tree/model/pagination_model.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';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/create_subspace_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/space_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_response_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/create_space_template_body_model.dart';
|
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_body_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_update_model.dart';
|
||||||
import 'package:syncrow_web/services/api/http_service.dart';
|
import 'package:syncrow_web/services/api/http_service.dart';
|
||||||
import 'package:syncrow_web/utils/constants/api_const.dart';
|
import 'package:syncrow_web/utils/constants/api_const.dart';
|
||||||
import 'package:syncrow_web/utils/constants/temp_const.dart';
|
|
||||||
|
|
||||||
class CommunitySpaceManagementApi {
|
class CommunitySpaceManagementApi {
|
||||||
// Community Management APIs
|
// Community Management APIs
|
||||||
Future<List<CommunityModel>> fetchCommunities(String projectId,
|
Future<List<CommunityModel>> fetchCommunities(String projectId, {int page = 1}) async {
|
||||||
{int page = 1}) async {
|
|
||||||
try {
|
try {
|
||||||
List<CommunityModel> allCommunities = [];
|
List<CommunityModel> allCommunities = [];
|
||||||
bool hasNext = true;
|
bool hasNext = true;
|
||||||
|
|
||||||
while (hasNext) {
|
while (hasNext) {
|
||||||
await HTTPService().get(
|
await HTTPService().get(
|
||||||
path: ApiEndpoints.getCommunityList
|
path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId),
|
||||||
.replaceAll('{projectId}', projectId),
|
queryParameters: {
|
||||||
queryParameters: {'page': page},
|
'page': page,
|
||||||
|
},
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
try {
|
try {
|
||||||
List<dynamic> jsonData = json['data'] ?? [];
|
List<dynamic> jsonData = json['data'] ?? [];
|
||||||
@@ -49,11 +48,42 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<PaginationModel> fetchCommunitiesAndSpaces(
|
||||||
|
{required String projectId, int page = 1, String search = ''}) async {
|
||||||
|
PaginationModel paginationModel = const PaginationModel.emptyConstructor();
|
||||||
|
|
||||||
|
try {
|
||||||
|
bool hasNext = false;
|
||||||
|
await HTTPService().get(
|
||||||
|
path: ApiEndpoints.getCommunityList.replaceAll('{projectId}', projectId),
|
||||||
|
queryParameters: {'page': page, 'includeSpaces': true, 'size': 25, 'search': search},
|
||||||
|
expectedResponseModel: (json) {
|
||||||
|
try {
|
||||||
|
List<dynamic> jsonData = json['data'] ?? [];
|
||||||
|
hasNext = json['hasNext'] ?? false;
|
||||||
|
int currentPage = json['page'] ?? 1;
|
||||||
|
List<CommunityModel> communityList = jsonData.map((jsonItem) {
|
||||||
|
return CommunityModel.fromJson(jsonItem);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
page = currentPage + 1;
|
||||||
|
paginationModel = PaginationModel(
|
||||||
|
pageNum: page, hasNext: hasNext, size: 25, communities: communityList);
|
||||||
|
return paginationModel;
|
||||||
|
} catch (_) {
|
||||||
|
hasNext = false;
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (_) {}
|
||||||
|
return paginationModel;
|
||||||
|
}
|
||||||
|
|
||||||
Future<CommunityModel?> getCommunityById(String communityId) async {
|
Future<CommunityModel?> getCommunityById(String communityId) async {
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getCommunityById
|
path: ApiEndpoints.getCommunityById.replaceAll('{communityId}', communityId),
|
||||||
.replaceAll('{communityId}', communityId),
|
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
return CommunityModel.fromJson(json['data']);
|
return CommunityModel.fromJson(json['data']);
|
||||||
},
|
},
|
||||||
@@ -65,8 +95,7 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<CommunityModel?> createCommunity(
|
Future<CommunityModel?> createCommunity(String name, String description, String projectId) async {
|
||||||
String name, String description, String projectId) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().post(
|
final response = await HTTPService().post(
|
||||||
path: ApiEndpoints.createCommunity.replaceAll('{projectId}', projectId),
|
path: ApiEndpoints.createCommunity.replaceAll('{projectId}', projectId),
|
||||||
@@ -85,8 +114,7 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> updateCommunity(
|
Future<bool> updateCommunity(String communityId, String name, String projectId) async {
|
||||||
String communityId, String name, String projectId) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().put(
|
final response = await HTTPService().put(
|
||||||
path: ApiEndpoints.updateCommunity
|
path: ApiEndpoints.updateCommunity
|
||||||
@@ -123,8 +151,7 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SpacesResponse> fetchSpaces(
|
Future<SpacesResponse> fetchSpaces(String communityId, String projectId) async {
|
||||||
String communityId, String projectId) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.listSpaces
|
path: ApiEndpoints.listSpaces
|
||||||
@@ -150,8 +177,7 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SpaceModel?> getSpace(
|
Future<SpaceModel?> getSpace(String communityId, String spaceId, String projectId) async {
|
||||||
String communityId, String spaceId, String projectId) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getSpace
|
path: ApiEndpoints.getSpace
|
||||||
@@ -262,8 +288,7 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> deleteSpace(
|
Future<bool> deleteSpace(String communityId, String spaceId, String projectId) async {
|
||||||
String communityId, String spaceId, String projectId) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().delete(
|
final response = await HTTPService().delete(
|
||||||
path: ApiEndpoints.deleteSpace
|
path: ApiEndpoints.deleteSpace
|
||||||
@@ -281,17 +306,15 @@ class CommunitySpaceManagementApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<SpaceModel>> getSpaceHierarchy(
|
Future<List<SpaceModel>> getSpaceHierarchy(String communityId, String projectId) async {
|
||||||
String communityId, String projectId) async {
|
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.getSpaceHierarchy
|
path: ApiEndpoints.getSpaceHierarchy
|
||||||
.replaceAll('{communityId}', communityId)
|
.replaceAll('{communityId}', communityId)
|
||||||
.replaceAll('{projectId}', projectId),
|
.replaceAll('{projectId}', projectId),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
final spaceModels = (json['data'] as List)
|
final spaceModels =
|
||||||
.map((spaceJson) => SpaceModel.fromJson(spaceJson))
|
(json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList();
|
||||||
.toList();
|
|
||||||
|
|
||||||
return spaceModels;
|
return spaceModels;
|
||||||
},
|
},
|
||||||
@@ -302,17 +325,16 @@ class CommunitySpaceManagementApi {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Future<List<SpaceModel>> getSpaceOnlyWithDevices(
|
|
||||||
{String? communityId, String? projectId}) async {
|
Future<List<SpaceModel>> getSpaceOnlyWithDevices({String? communityId, String? projectId}) async {
|
||||||
try {
|
try {
|
||||||
final response = await HTTPService().get(
|
final response = await HTTPService().get(
|
||||||
path: ApiEndpoints.spaceOnlyWithDevices
|
path: ApiEndpoints.spaceOnlyWithDevices
|
||||||
.replaceAll('{communityId}', communityId!)
|
.replaceAll('{communityId}', communityId!)
|
||||||
.replaceAll('{projectId}', projectId!),
|
.replaceAll('{projectId}', projectId!),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
final spaceModels = (json['data'] as List)
|
final spaceModels =
|
||||||
.map((spaceJson) => SpaceModel.fromJson(spaceJson))
|
(json['data'] as List).map((spaceJson) => SpaceModel.fromJson(spaceJson)).toList();
|
||||||
.toList();
|
|
||||||
return spaceModels;
|
return spaceModels;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,21 +9,8 @@ abstract class ApiEndpoints {
|
|||||||
static const String sendOtp = '/authentication/user/send-otp';
|
static const String sendOtp = '/authentication/user/send-otp';
|
||||||
static const String verifyOtp = '/authentication/user/verify-otp';
|
static const String verifyOtp = '/authentication/user/verify-otp';
|
||||||
static const String getRegion = '/region';
|
static const String getRegion = '/region';
|
||||||
static const String visitorPassword =
|
static const String visitorPassword = '/visitor-passwords';
|
||||||
'/projects/{projectId}/visitor-password';
|
static const String getDevices = '/projects/{projectId}/devices';
|
||||||
static const String getDevices =
|
|
||||||
'/projects/{projectId}/visitor-password/devices';
|
|
||||||
|
|
||||||
static const String sendOnlineOneTime =
|
|
||||||
'/visitor-password/temporary-password/online/one-time';
|
|
||||||
static const String sendOnlineMultipleTime =
|
|
||||||
'/visitor-password/temporary-password/online/multiple-time';
|
|
||||||
|
|
||||||
//offline Password
|
|
||||||
static const String sendOffLineOneTime =
|
|
||||||
'/visitor-password/temporary-password/offline/one-time';
|
|
||||||
static const String sendOffLineMultipleTime =
|
|
||||||
'/visitor-password/temporary-password/offline/multiple-time';
|
|
||||||
|
|
||||||
static const String getUser = '/user/{userUuid}';
|
static const String getUser = '/user/{userUuid}';
|
||||||
|
|
||||||
@@ -32,15 +19,15 @@ abstract class ApiEndpoints {
|
|||||||
static const String getAllDevices = '/projects/{projectId}/devices';
|
static const String getAllDevices = '/projects/{projectId}/devices';
|
||||||
static const String getSpaceDevices =
|
static const String getSpaceDevices =
|
||||||
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
'/projects/{projectId}/communities/{communityUuid}/spaces/{spaceUuid}/devices';
|
||||||
static const String getDeviceStatus = '/device/{uuid}/functions/status';
|
static const String getDeviceStatus = '/devices/{uuid}/functions/status';
|
||||||
static const String getBatchStatus = '/device/status/batch';
|
static const String getBatchStatus = '/devices/batch';
|
||||||
|
|
||||||
static const String deviceControl = '/device/{uuid}/control';
|
static const String deviceControl = '/devices/{uuid}/command';
|
||||||
static const String deviceBatchControl = '/device/control/batch';
|
static const String deviceBatchControl = '/devices/batch';
|
||||||
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
|
static const String gatewayApi = '/devices/gateway/{gatewayUuid}/devices';
|
||||||
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
|
||||||
|
|
||||||
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
|
static const String getDeviceLogs = '/devices/{uuid}/report-logs?code={code}';
|
||||||
|
|
||||||
// Space Module
|
// Space Module
|
||||||
static const String createSpace =
|
static const String createSpace =
|
||||||
@@ -70,18 +57,13 @@ abstract class ApiEndpoints {
|
|||||||
static const String createUserCommunity =
|
static const String createUserCommunity =
|
||||||
'/projects/{projectId}/communities/user';
|
'/projects/{projectId}/communities/user';
|
||||||
static const String getDeviceLogsByDate =
|
static const String getDeviceLogsByDate =
|
||||||
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
|
'/devices/{uuid}/report-logs?code={code}&startTime={startTime}&endTime={endTime}';
|
||||||
|
|
||||||
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
|
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
|
||||||
static const String getScheduleByDeviceId =
|
static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
|
||||||
'/schedule/{deviceUuid}?category={category}';
|
static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
|
||||||
static const String deleteScheduleByDeviceId =
|
static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
|
||||||
'/schedule/{deviceUuid}/{scheduleUuid}';
|
static const String factoryReset = '/devices/batch';
|
||||||
static const String updateScheduleByDeviceId =
|
|
||||||
'/schedule/enable/{deviceUuid}';
|
|
||||||
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
|
|
||||||
static const String powerClamp =
|
|
||||||
'/device/{powerClampUuid}/power-clamp/status';
|
|
||||||
|
|
||||||
//product
|
//product
|
||||||
static const String listProducts = '/products';
|
static const String listProducts = '/products';
|
||||||
|
|||||||
@@ -408,9 +408,9 @@ class Assets {
|
|||||||
static const String spaceLinkIcon = 'assets/icons/space_link_icon.svg';
|
static const String spaceLinkIcon = 'assets/icons/space_link_icon.svg';
|
||||||
static const String successIcon = 'assets/icons/success_icon.svg';
|
static const String successIcon = 'assets/icons/success_icon.svg';
|
||||||
static const String spaceLocationIcon = 'assets/icons/spaseLocationIcon.svg';
|
static const String spaceLocationIcon = 'assets/icons/spaseLocationIcon.svg';
|
||||||
static const String scenesPlayIcon = 'assets/icons/scenesPlayIcon.svg';
|
static const String scenesPlayIcon = 'assets/icons/scenesPlayIcon.png';
|
||||||
static const String scenesPlayIconCheck =
|
static const String scenesPlayIconCheck =
|
||||||
'assets/icons/scenesPlayIconCheck.svg';
|
'assets/icons/scenesPlayIconCheck.png';
|
||||||
static const String presenceStateIcon = 'assets/icons/presence_state.svg';
|
static const String presenceStateIcon = 'assets/icons/presence_state.svg';
|
||||||
static const String currentDistanceIcon =
|
static const String currentDistanceIcon =
|
||||||
'assets/icons/current_distance_icon.svg';
|
'assets/icons/current_distance_icon.svg';
|
||||||
@@ -427,5 +427,4 @@ class Assets {
|
|||||||
static const String presenceTimeIcon = 'assets/icons/presence_time_icon.svg';
|
static const String presenceTimeIcon = 'assets/icons/presence_time_icon.svg';
|
||||||
static const String IlluminanceIcon = 'assets/icons/Illuminance_icon.svg';
|
static const String IlluminanceIcon = 'assets/icons/Illuminance_icon.svg';
|
||||||
|
|
||||||
//Illuminance_icon
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user