add_user_dialog

This commit is contained in:
mohammad
2024-12-17 16:51:32 +03:00
parent c31f1262a2
commit bd1204c03a
12 changed files with 481 additions and 212 deletions

View File

@ -0,0 +1,22 @@
class RoleTypeModel {
final String uuid;
final String createdAt;
final String updatedAt;
final String type;
RoleTypeModel({
required this.uuid,
required this.createdAt,
required this.updatedAt,
required this.type,
});
factory RoleTypeModel.fromJson(Map<String, dynamic> json) {
return RoleTypeModel(
uuid: json['uuid'],
createdAt: json['createdAt'],
updatedAt: json['updatedAt'],
type: json['type'],
);
}
}

View File

@ -1,12 +1,15 @@
import 'package:bloc/bloc.dart';
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/roles_and_permission/model/role_type_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/model/roles_user_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_event.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_status.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/model/tree_node_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/view/roles_and_permission.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
import 'package:syncrow_web/services/space_mana_api.dart';
import 'package:syncrow_web/services/user_permission.dart';
class UsersBloc extends Bloc<UsersEvent, UsersState> {
UsersBloc() : super(UsersInitial()) {
@ -16,6 +19,9 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
on<LoadCommunityAndSpacesEvent>(_onLoadCommunityAndSpaces);
on<SearchAnode>(searchTreeNode);
on<CheckSpacesStepStatus>(isCompleteSpacesFun);
on<RoleEvent>(_getRolePermission);
on<PermissionEvent>(_getPermissions);
on<SearchPermission>(searchRolePermission);
}
List<RolesUserModel> users = [];
@ -112,7 +118,6 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
void isCompleteSpacesFun(
CheckSpacesStepStatus event, Emitter<UsersState> emit) {
emit(UsersLoadingState());
try {
List<String> selectedIds = getSelectedIds(updatedCommunities);
isCompleteSpaces = selectedIds.isNotEmpty;
@ -224,4 +229,61 @@ class UsersBloc extends Bloc<UsersEvent, UsersState> {
}
return selectedIds;
}
List<RoleTypeModel> roles = [];
List<PermissionOption> permissions = [];
_getRolePermission(RoleEvent event, Emitter<UsersState> emit) async {
try {
emit(UsersLoadingState());
roles = await UserPermissionApi().fetchRoles();
add(PermissionEvent(roleUuid: roles.first.uuid));
emit(RolePermissionInitial());
} catch (e) {
emit(ErrorState('Error loading communities and spaces: $e'));
}
}
_getPermissions(PermissionEvent event, Emitter<UsersState> emit) async {
try {
emit(UsersLoadingState());
permissions = await UserPermissionApi().fetchPermission(
event.roleUuid == "" ? roles.first.uuid : event.roleUuid);
emit(RolePermissionInitial());
} catch (e) {
emit(ErrorState('Error loading communities and spaces: $e'));
}
}
bool _searchRolePermission(List<PermissionOption> nodes, String searchTerm) {
bool anyMatch = false;
for (var node in nodes) {
bool isMatch =
node.title.toLowerCase().contains(searchTerm.toLowerCase());
bool childMatch = _searchRolePermission(node.subOptions, searchTerm);
node.isHighlighted = isMatch || childMatch;
anyMatch = anyMatch || node.isHighlighted;
}
return anyMatch;
}
void searchRolePermission(SearchPermission event, Emitter<UsersState> emit) {
emit(UsersLoadingState());
if (event.searchTerm!.isEmpty) {
_clearHighlightsRolePermission(permissions);
} else {
_searchRolePermission(permissions, event.searchTerm!);
}
emit(ChangeStatusSteps());
}
void _clearHighlightsRolePermission(List<PermissionOption> nodes) {
for (var node in nodes) {
node.isHighlighted = false;
if (node.subOptions.isNotEmpty) {
_clearHighlightsRolePermission(node.subOptions);
}
}
}
}

View File

@ -1,5 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/model/tree_node_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/view/roles_and_permission.dart';
sealed class UsersEvent extends Equatable {
const UsersEvent();
@ -10,6 +11,7 @@ class GetUsers extends UsersEvent {
@override
List<Object?> get props => [];
}
class CheckSpacesStepStatus extends UsersEvent {
const CheckSpacesStepStatus();
@override
@ -22,6 +24,19 @@ class LoadCommunityAndSpacesEvent extends UsersEvent {
List<Object?> get props => [];
}
class RoleEvent extends UsersEvent {
const RoleEvent();
@override
List<Object?> get props => [];
}
class PermissionEvent extends UsersEvent {
final String? roleUuid;
const PermissionEvent({this.roleUuid = ""});
@override
List<Object?> get props => [roleUuid];
}
class GetBatchStatus extends UsersEvent {
final List<String> uuids;
const GetBatchStatus(this.uuids);
@ -29,7 +44,6 @@ class GetBatchStatus extends UsersEvent {
List<Object?> get props => [uuids];
}
//LoadCommunityAndSpacesEvent
class ChangeUserStatus extends UsersEvent {
final String userId;
final String newStatus;
@ -54,9 +68,20 @@ class SearchAnode extends UsersEvent {
@override
List<Object?> get props => [nodes, searchTerm];
}
class SearchPermission extends UsersEvent {
List<PermissionOption>? nodes;
String? searchTerm;
SearchPermission({this.nodes, this.searchTerm});
@override
List<Object?> get props => [nodes, searchTerm];
}
class SelecteId extends UsersEvent {
List<TreeNode>? nodes;
SelecteId({this.nodes,});
SelecteId({
this.nodes,
});
@override
List<Object?> get props => [nodes];
}

View File

@ -9,6 +9,10 @@ final class UsersInitial extends UsersState {
@override
List<Object> get props => [];
}
final class RolePermissionInitial extends UsersState {
@override
List<Object> get props => [];
}
final class ChangeStatusSteps extends UsersState {
@override

View File

@ -23,8 +23,9 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (BuildContext context) =>
UsersBloc()..add(LoadCommunityAndSpacesEvent()),
create: (BuildContext context) => UsersBloc()
..add(const LoadCommunityAndSpacesEvent())
..add(const RoleEvent()),
child: BlocConsumer<UsersBloc, UsersState>(
listener: (context, state) {},
builder: (context, state) {
@ -45,7 +46,9 @@ class _AddNewUserDialogState extends State<AddNewUserDialog> {
child: Text(
"Add New User",
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
fontSize: 20,
fontWeight: FontWeight.w700,
color: ColorsManager.secondaryColor),
),
),
),

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; // Import Bloc package
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl_phone_field/country_picker_dialog.dart';
import 'package:intl_phone_field/intl_phone_field.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_bloc.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_status.dart';
import 'package:syncrow_web/utils/color_manager.dart';
@ -47,9 +49,16 @@ class BasicsView extends StatelessWidget {
SizedBox(
child: Row(
children: [
Text(
// SizedBox(
// width: 15,
// ),
const Text(
" * ",
style: TextStyle(color: ColorsManager.red),
style: TextStyle(
color: ColorsManager.red,
fontWeight: FontWeight.w900,
fontSize: 15,
),
),
Text(
'First Name',
@ -97,7 +106,11 @@ class BasicsView extends StatelessWidget {
children: [
const Text(
" * ",
style: TextStyle(color: ColorsManager.red),
style: TextStyle(
color: ColorsManager.red,
fontWeight: FontWeight.w900,
fontSize: 15,
),
),
Text('Last Name',
style: context.textTheme.bodyMedium?.copyWith(
@ -140,9 +153,13 @@ class BasicsView extends StatelessWidget {
SizedBox(
child: Row(
children: [
Text(
const Text(
" * ",
style: TextStyle(color: ColorsManager.red),
style: TextStyle(
color: ColorsManager.red,
fontWeight: FontWeight.w900,
fontSize: 15,
),
),
Text(
'Email Address',
@ -187,10 +204,6 @@ class BasicsView extends StatelessWidget {
SizedBox(
child: Row(
children: [
Text(
"*",
style: TextStyle(color: ColorsManager.red),
),
Text(
'Mobile Number',
style: context.textTheme.bodyMedium?.copyWith(
@ -200,11 +213,55 @@ class BasicsView extends StatelessWidget {
),
],
)),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
style: const TextStyle(color: Colors.black),
controller: _blocRole.phoneController,
// InternationalPhoneNumberInput(
// spaceBetweenSelectorAndTextField: 50,
// initialValue: PhoneNumber(isoCode: 'AE'),
// inputDecoration: inputTextFormDeco(
// hintText: "x xxx xxxx",
// ).copyWith(
// hintStyle: context.textTheme.bodyMedium?.copyWith(
// fontWeight: FontWeight.w400,
// fontSize: 12,
// color: ColorsManager.textGray),
// ),
// onInputChanged: (PhoneNumber number) {
// print(number.phoneNumber);
// },
// onInputValidated: (bool value) {
// print(value);
// },
// selectorConfig: const SelectorConfig(
// selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
// useBottomSheetSafeArea: true,
// leadingPadding: 15,
// trailingSpace: false,
// setSelectorButtonAsPrefixIcon: true),
// ignoreBlank: true,
// autoValidateMode: AutovalidateMode.disabled,
// selectorTextStyle:
// TextStyle(color: ColorsManager.blackColor),
// // initialValue: number,
// // textFieldController: controller,
// formatInput: true,
// keyboardType: const TextInputType.numberWithOptions(
// signed: true, decimal: true),
// // inputBorder: OutlineInputBorder(
// // borderSide:
// // BorderSide(color: Colors.black,)),
// onSaved: (PhoneNumber number) {
// print('On Saved: $number');
// },
// textStyle:
// const TextStyle(color: ColorsManager.blackColor),
// ),
IntlPhoneField(
pickerDialogStyle: PickerDialogStyle(),
dropdownIconPosition: IconPosition.leading,
disableLengthCheck: true,
dropdownTextStyle: TextStyle(color: Colors.black),
textInputAction: TextInputAction.done,
decoration: inputTextFormDeco(
hintText: "05x xxx xxxx",
).copyWith(
@ -213,15 +270,36 @@ class BasicsView extends StatelessWidget {
fontSize: 12,
color: ColorsManager.textGray),
),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a phone number';
}
return null;
initialCountryCode: 'AE',
style: TextStyle(color: Colors.black),
onChanged: (phone) {
print(phone.completeNumber);
},
keyboardType: TextInputType.phone,
),
),
)
// Padding(
// padding: const EdgeInsets.all(8.0),
// child: TextFormField(
// style: const TextStyle(color: Colors.black),
// controller: _blocRole.phoneController,
// decoration: inputTextFormDeco(
// hintText: "05x xxx xxxx",
// ).copyWith(
// hintStyle: context.textTheme.bodyMedium?.copyWith(
// fontWeight: FontWeight.w400,
// fontSize: 12,
// color: ColorsManager.textGray),
// ),
// validator: (value) {
// if (value == null || value.isEmpty) {
// return 'Please enter a phone number';
// }
// return null;
// },
// keyboardType: TextInputType.phone,
// ),
// ),
],
),
),
@ -236,10 +314,6 @@ class BasicsView extends StatelessWidget {
SizedBox(
child: Row(
children: [
Text(
"*",
style: TextStyle(color: ColorsManager.red),
),
Text(
'Job Title',
style: context.textTheme.bodyMedium?.copyWith(

View File

@ -5,14 +5,14 @@ import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_blo
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_status.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class AddNewUserDialog extends StatefulWidget {
const AddNewUserDialog({super.key});
class DeleteUserDialog extends StatefulWidget {
const DeleteUserDialog({super.key});
@override
_AddNewUserDialogState createState() => _AddNewUserDialogState();
_DeleteUserDialogState createState() => _DeleteUserDialogState();
}
class _AddNewUserDialogState extends State<AddNewUserDialog> {
class _DeleteUserDialogState extends State<DeleteUserDialog> {
int currentStep = 1;
@override

View File

@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; // Import Bloc package
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_bloc.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_event.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/bloc/users_status.dart';
import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
@ -34,7 +35,12 @@ class RolesAndPermission extends StatelessWidget {
const SizedBox(
height: 15,
),
const SizedBox(width: 300, height: 110, child: DropdownExample()),
SizedBox(
width: 300,
height: 110,
child: DropdownExample(
bloc: _blocRole,
)),
const SizedBox(height: 10),
Expanded(
child: SizedBox(
@ -64,6 +70,11 @@ class RolesAndPermission extends StatelessWidget {
style:
const TextStyle(color: Colors.black),
controller: _blocRole.firstNameController,
onChanged: (value) {
_blocRole.add(SearchPermission(
nodes: _blocRole.permissions,
searchTerm: value));
},
decoration: textBoxDecoration(radios: 20)!
.copyWith(
fillColor: Colors.white,
@ -97,7 +108,9 @@ class RolesAndPermission extends StatelessWidget {
padding: const EdgeInsets.all(8.0),
child: Container(
color: ColorsManager.whiteColors,
child: const DeviceManagement())))
child: DeviceManagement(
bloc: _blocRole,
))))
],
),
),
@ -111,7 +124,8 @@ class RolesAndPermission extends StatelessWidget {
}
class DropdownExample extends StatefulWidget {
const DropdownExample({super.key});
final UsersBloc? bloc;
const DropdownExample({super.key, this.bloc});
@override
_DropdownExampleState createState() => _DropdownExampleState();
@ -119,7 +133,13 @@ class DropdownExample extends StatefulWidget {
class _DropdownExampleState extends State<DropdownExample> {
String? selectedRole;
List<String> roles = ['Admin', 'User', 'Guest', 'Moderator'];
@override
void initState() {
super.initState();
if (widget.bloc != null && widget.bloc!.roles.isNotEmpty) {
selectedRole = widget.bloc!.roles.first.uuid;
}
}
@override
Widget build(BuildContext context) {
@ -140,19 +160,20 @@ class _DropdownExampleState extends State<DropdownExample> {
SizedBox(
child: DropdownButtonFormField<String>(
alignment: Alignment.center,
focusColor: ColorsManager.whiteColors,
focusColor: Colors.white,
autofocus: true,
value: selectedRole,
items: roles.map((role) {
return DropdownMenuItem(
value: role,
child: Text(role),
items: widget.bloc!.roles.map((role) {
return DropdownMenuItem<String>(
value: role.uuid,
child: Text(role.type),
);
}).toList(),
onChanged: (value) {
setState(() {
selectedRole = value;
});
widget.bloc!.add(PermissionEvent(roleUuid: selectedRole));
},
padding: EdgeInsets.zero,
icon: const SizedBox.shrink(),
@ -168,13 +189,13 @@ class _DropdownExampleState extends State<DropdownExample> {
width: 70,
height: 50,
decoration: BoxDecoration(
color: ColorsManager.graysColor,
color: Colors.grey[200],
borderRadius: const BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10),
),
border: Border.all(
color: ColorsManager.grayBorder,
color: Colors.grey,
width: 1.0,
),
),
@ -192,60 +213,17 @@ class _DropdownExampleState extends State<DropdownExample> {
}
class DeviceManagement extends StatefulWidget {
const DeviceManagement({Key? key}) : super(key: key);
final UsersBloc? bloc;
const DeviceManagement({Key? key, this.bloc}) : super(key: key);
@override
_DeviceManagementState createState() => _DeviceManagementState();
}
class _DeviceManagementState extends State<DeviceManagement> {
final List<MainRoleOption> options = [
MainRoleOption(
id: '1',
title: "Device Management",
subOptions: [
SubRoleOption(
id: '11',
title: "Manage devices in private spaces",
children: [
ChildRoleOption(id: '111', title: "Control"),
ChildRoleOption(id: '112', title: "Assign device"),
ChildRoleOption(id: '113', title: "View"),
],
),
SubRoleOption(
id: '12',
title: "Manage",
children: [
ChildRoleOption(id: '121', title: "cc"),
ChildRoleOption(id: '122', title: "Assign"),
ChildRoleOption(id: '123', title: "s"),
],
),
],
),
MainRoleOption(
id: '2',
title: "Device Management",
subOptions: [
SubRoleOption(
id: '22',
title: "Manage devices in private spaces",
children: [
ChildRoleOption(id: '211', title: "Control"),
ChildRoleOption(id: '212', title: "Assign device"),
ChildRoleOption(id: '213', title: "View"),
],
),
],
),
];
void toggleOptionById(String id) {
setState(() {
for (var mainOption in options) {
for (var mainOption in widget.bloc!.permissions) {
if (mainOption.id == id) {
final isChecked =
checkifOneOfthemChecked(mainOption) == CheckState.all;
@ -253,7 +231,7 @@ class _DeviceManagementState extends State<DeviceManagement> {
for (var subOption in mainOption.subOptions) {
subOption.isChecked = !isChecked;
for (var child in subOption.children) {
for (var child in subOption.subOptions) {
child.isChecked = !isChecked;
}
}
@ -263,7 +241,7 @@ class _DeviceManagementState extends State<DeviceManagement> {
for (var subOption in mainOption.subOptions) {
if (subOption.id == id) {
subOption.isChecked = !subOption.isChecked;
for (var child in subOption.children) {
for (var child in subOption.subOptions) {
child.isChecked = subOption.isChecked;
}
mainOption.isChecked =
@ -271,11 +249,11 @@ class _DeviceManagementState extends State<DeviceManagement> {
return;
}
for (var child in subOption.children) {
for (var child in subOption.subOptions) {
if (child.id == id) {
child.isChecked = !child.isChecked;
subOption.isChecked =
subOption.children.every((child) => child.isChecked);
subOption.subOptions.every((child) => child.isChecked);
mainOption.isChecked =
mainOption.subOptions.every((sub) => sub.isChecked);
return;
@ -286,7 +264,7 @@ class _DeviceManagementState extends State<DeviceManagement> {
});
}
CheckState checkifOneOfthemChecked(MainRoleOption mainOption) {
CheckState checkifOneOfthemChecked(PermissionOption mainOption) {
bool allSelected = true;
bool someSelected = false;
@ -297,7 +275,7 @@ class _DeviceManagementState extends State<DeviceManagement> {
allSelected = false;
}
for (var child in subOption.children) {
for (var child in subOption.subOptions) {
if (child.isChecked) {
someSelected = true;
} else {
@ -319,16 +297,16 @@ class _DeviceManagementState extends State<DeviceManagement> {
Widget build(BuildContext context) {
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: options.length,
itemCount: widget.bloc!.permissions.length,
itemBuilder: (context, index) {
final option = options[index];
final option = widget.bloc!.permissions[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
InkWell(
onTap: () => toggleOptionById(option.id),
// onTap: () => toggleOptionById(option.id),
child: Builder(
builder: (context) {
final checkState = checkifOneOfthemChecked(option);
@ -372,14 +350,18 @@ class _DeviceManagementState extends State<DeviceManagement> {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
Container(
color: option.isHighlighted
? Colors.blue.shade50
: Colors.white,
child: Row(
children: [
InkWell(
onTap: () => toggleOptionById(subOption.id),
// onTap: () => toggleOptionById(subOption.id),
child: Builder(
builder: (context) {
final checkState =
checkifOneOfthemChecked(MainRoleOption(
checkifOneOfthemChecked(PermissionOption(
id: subOption.id,
title: subOption.title,
subOptions: [subOption],
@ -417,6 +399,7 @@ class _DeviceManagementState extends State<DeviceManagement> {
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 50.0),
child: GridView.builder(
@ -424,15 +407,18 @@ class _DeviceManagementState extends State<DeviceManagement> {
physics: const NeverScrollableScrollPhysics(),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 2 items per row
mainAxisSpacing: 2.0, // Space between rows
crossAxisSpacing: 0.2, // Space between columns
childAspectRatio: 5, // Adjust aspect ratio as needed
crossAxisCount: 2,
mainAxisSpacing: 2.0,
crossAxisSpacing: 0.2,
childAspectRatio: 5,
),
itemCount: subOption.children.length,
itemCount: subOption.subOptions.length,
itemBuilder: (context, index) {
final child = subOption.children[index];
final child = subOption.subOptions[index];
return CheckboxListTile(
selectedTileColor: child.isHighlighted
? Colors.blue.shade50
: Colors.white,
dense: true,
controlAffinity: ListTileControlAffinity.leading,
title: Text(
@ -444,6 +430,7 @@ class _DeviceManagementState extends State<DeviceManagement> {
),
value: child.isChecked,
onChanged: (value) => toggleOptionById(child.id),
enabled: false,
);
},
),
@ -458,43 +445,44 @@ class _DeviceManagementState extends State<DeviceManagement> {
}
}
class MainRoleOption {
String id;
String title;
bool isChecked;
List<SubRoleOption> subOptions;
MainRoleOption({
required this.id,
required this.title,
this.isChecked = false,
this.subOptions = const [],
});
}
class SubRoleOption {
String id;
String title;
bool isChecked;
List<ChildRoleOption> children;
SubRoleOption({
required this.id,
required this.title,
this.isChecked = false,
this.children = const [],
});
}
class ChildRoleOption {
String id;
String title;
bool isChecked;
ChildRoleOption({
required this.id,
required this.title,
this.isChecked = false,
});
}
enum CheckState { none, some, all }
class PermissionOption {
String id;
String title;
bool isChecked;
bool isHighlighted;
List<PermissionOption> subOptions;
PermissionOption({
required this.id,
required this.title,
this.isChecked = false,
this.isHighlighted = false,
this.subOptions = const [],
});
factory PermissionOption.fromJson(Map<String, dynamic> json) {
return PermissionOption(
id: json['id'] ?? '',
title: json['title'] ?? '',
isChecked: json['isChecked'] ?? false,
isHighlighted: json['isHighlighted'] ?? false,
subOptions: (json['subOptions'] as List?)
?.map((sub) => PermissionOption.fromJson(sub))
.toList() ??
[],
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'title': title,
'isChecked': isChecked,
'isHighlighted': isHighlighted,
'subOptions': subOptions.map((sub) => sub.toJson()).toList(),
};
}
}

View File

@ -0,0 +1,36 @@
import 'package:syncrow_web/pages/roles_and_permission/model/role_type_model.dart';
import 'package:syncrow_web/pages/roles_and_permission/users_page/view/roles_and_permission.dart';
import 'package:syncrow_web/services/api/http_service.dart';
import 'package:syncrow_web/utils/constants/api_const.dart';
class UserPermissionApi {
static final HTTPService _httpService = HTTPService();
fetchRoles() async {
final response = await _httpService.get(
path: ApiEndpoints.roleTypes,
showServerMessage: true,
expectedResponseModel: (json) {
final List<RoleTypeModel> fetchedRoles = (json['data'] as List)
.map((item) => RoleTypeModel.fromJson(item))
.toList();
return fetchedRoles;
},
);
return response;
}
Future<List<PermissionOption>> fetchPermission(roleUuid) async {
final response = await _httpService.get(
path: ApiEndpoints.permission.replaceAll("roleUuid", roleUuid),
showServerMessage: true,
expectedResponseModel: (json) {
return (json as List)
.map((data) => PermissionOption.fromJson(data))
.toList();
},
);
return response ?? [];
}
}

View File

@ -11,12 +11,14 @@ abstract class ApiEndpoints {
static const String visitorPassword = '/visitor-password';
static const String getDevices = '/visitor-password/devices';
static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time';
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 sendOffLineOneTime =
'/visitor-password/temporary-password/offline/one-time';
static const String sendOffLineMultipleTime =
'/visitor-password/temporary-password/offline/multiple-time';
@ -38,8 +40,10 @@ abstract class ApiEndpoints {
// Space Module
static const String createSpace = '/communities/{communityId}/spaces';
static const String listSpaces = '/communities/{communityId}/spaces';
static const String deleteSpace = '/communities/{communityId}/spaces/{spaceId}';
static const String updateSpace = '/communities/{communityId}/spaces/{spaceId}';
static const String deleteSpace =
'/communities/{communityId}/spaces/{spaceId}';
static const String updateSpace =
'/communities/{communityId}/spaces/{spaceId}';
static const String getSpace = '/communities/{communityId}/spaces/{spaceId}';
static const String getSpaceHierarchy = '/communities/{communityId}/spaces';
@ -55,11 +59,15 @@ abstract class ApiEndpoints {
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
static const String scheduleByDeviceId = '/schedule/{deviceUuid}';
static const String getScheduleByDeviceId = '/schedule/{deviceUuid}?category={category}';
static const String deleteScheduleByDeviceId = '/schedule/{deviceUuid}/{scheduleUuid}';
static const String updateScheduleByDeviceId = '/schedule/enable/{deviceUuid}';
static const String getScheduleByDeviceId =
'/schedule/{deviceUuid}?category={category}';
static const String deleteScheduleByDeviceId =
'/schedule/{deviceUuid}/{scheduleUuid}';
static const String updateScheduleByDeviceId =
'/schedule/enable/{deviceUuid}';
static const String factoryReset = '/device/factory/reset/{deviceUuid}';
static const String powerClamp = '/device/{powerClampUuid}/power-clamp/status';
static const String powerClamp =
'/device/{powerClampUuid}/power-clamp/status';
//product
static const String listProducts = '/products';
@ -68,8 +76,10 @@ abstract class ApiEndpoints {
static const String getIconScene = '/scene/icon';
static const String createScene = '/scene/tap-to-run';
static const String createAutomation = '/automation';
static const String getUnitScenes = '/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
static const String getAutomationDetails = '/automation/details/{automationId}';
static const String getUnitScenes =
'/communities/{communityUuid}/spaces/{spaceUuid}/scenes';
static const String getAutomationDetails =
'/automation/details/{automationId}';
static const String getScene = '/scene/tap-to-run/{sceneId}';
static const String deleteScene = '/scene/tap-to-run/{sceneId}';
@ -77,4 +87,7 @@ abstract class ApiEndpoints {
static const String updateScene = '/scene/tap-to-run/{sceneId}';
static const String updateAutomation = '/automation/{automationId}';
static const String roleTypes = '/role/types';
static const String permission = '/permission/{roleUuid}';
// static const String updateAutomation = '/automation/{automationId}';
}

View File

@ -304,6 +304,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.19.0"
intl_phone_field:
dependency: "direct main"
description:
name: intl_phone_field
sha256: "73819d3dfcb68d2c85663606f6842597c3ddf6688ac777f051b17814fe767bbf"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
intl_phone_number_input:
dependency: "direct main"
description:
name: intl_phone_number_input
sha256: "1c4328713a9503ab26a1fdbb6b00b4cada68c18aac922b35bedbc72eff1297c3"
url: "https://pub.dev"
source: hosted
version: "0.7.4"
js:
dependency: transitive
description:
@ -336,6 +352,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.1"
libphonenumber_platform_interface:
dependency: transitive
description:
name: libphonenumber_platform_interface
sha256: f801f6c65523f56504b83f0890e6dad584ab3a7507dca65fec0eed640afea40f
url: "https://pub.dev"
source: hosted
version: "0.4.2"
libphonenumber_plugin:
dependency: transitive
description:
name: libphonenumber_plugin
sha256: c615021d9816fbda2b2587881019ed595ecdf54d999652d7e4cce0e1f026368c
url: "https://pub.dev"
source: hosted
version: "0.3.3"
libphonenumber_web:
dependency: transitive
description:
name: libphonenumber_web
sha256: "8186f420dbe97c3132283e52819daff1e55d60d6db46f7ea5ac42f42a28cc2ef"
url: "https://pub.dev"
source: hosted
version: "0.3.2"
lints:
dependency: transitive
description:

View File

@ -52,6 +52,8 @@ dependencies:
fl_chart: ^0.69.0
uuid: ^4.4.2
time_picker_spinner: ^1.0.0
intl_phone_field: ^3.2.0
intl_phone_number_input: ^0.7.4
dev_dependencies:
flutter_test: