test base project

This commit is contained in:
Azmat-7860
2026-09-15 09:09:11 +05:30
commit 8094da30c4
471 changed files with 27174 additions and 0 deletions
@@ -0,0 +1,279 @@
import 'package:flutter/material.dart';
import '../../providers/token_manager.dart';
import 'dynamic_form_service.dart';
class EditForm extends StatefulWidget {
final Map<String, dynamic> formData;
EditForm({required this.formData});
@override
_EditFormState createState() => _EditFormState();
}
class _EditFormState extends State<EditForm> {
TextEditingController formNameController = TextEditingController();
TextEditingController formDescController = TextEditingController();
TextEditingController relatedToController = TextEditingController();
TextEditingController pageEventController = TextEditingController();
TextEditingController buttonCaptionController = TextEditingController();
final DynamicForApiService apiService = DynamicForApiService();
List<dynamic> components = []; // List to store table data
List<dynamic> relatedToFixedDropdown = ['Menu', 'Related To',];
List<dynamic> pageEventFixedDropdown = ['OnClick', 'OnBlur',];
List<dynamic> typeFixedDropdown = ['text', 'dropdown','date','checkbox','textarea','togglebutton'];
List<dynamic> mappingFixedDropdown = ['TEXTFIELD1', 'TEXTFIELD2','TEXTFIELD3','TEXTFIELD4','TEXTFIELD5','TEXTFIELD6','TEXTFIELD7','TEXTFIELD8','TEXTFIELD9','TEXTFIELD10','TEXTFIELD11','TEXTFIELD12','TEXTFIELD13','TEXTFIELD14','TEXTFIELD15','TEXTFIELD16','TEXTFIELD17','TEXTFIELD18','TEXTFIELD19','TEXTFIELD20','TEXTFIELD21','TEXTFIELD22','TEXTFIELD23',
'TEXTFIELD24','TEXTFIELD25','TEXTFIELD26','LONGTEXT1','LONGTEXT2','LONGTEXT3','LONGTEXT4',];
List<dynamic> truefalseFixedDropdown = ['true', 'false',];
@override
void initState() {
super.initState();
// Initialize text controllers with the data from the selected row
formNameController.text = widget.formData['form_name'] ?? '';
formDescController.text = widget.formData['form_desc'] ?? '';
relatedToController.text = widget.formData['related_to'] ?? '';
pageEventController.text = widget.formData['page_event'] ?? '';
buttonCaptionController.text = widget.formData['button_caption'] ?? '';
// Initialize the components data, or you can load it from formData['components'].
// For this example, we'll use an empty list.
components = widget.formData['components'] ?? [];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Form'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: formNameController,
decoration: InputDecoration(labelText: 'Form Name'),
),
TextFormField(
controller: formDescController,
decoration: InputDecoration(labelText: 'Form Description'),
),
DropdownButtonFormField<String>(
value: relatedToController.text,
decoration:
const InputDecoration(labelText: 'Select Related To'),
items: [
...relatedToFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
relatedToController.text = value!;
});
},
),
DropdownButtonFormField<String>(
value: pageEventController.text,
decoration:
const InputDecoration(labelText: 'Select Page Event'),
items: [
...pageEventFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
pageEventController.text = value!;
});
},
),
TextFormField(
controller: buttonCaptionController,
decoration: InputDecoration(labelText: 'Button Caption'),
),
const Text('Components Details'),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Label')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Mapping')),
DataColumn(label: Text('Mandatory')),
DataColumn(label: Text('Readonly')),
DataColumn(label: Text('Drop Values')),
DataColumn(label: Text('SP')),
DataColumn(label: Text('Actions'), numeric: false), // Add Actions column
],
rows: components.asMap().entries.map((entry) {
final index = entry.key;
final component = entry.value;
return DataRow(
cells: <DataCell>[
DataCell(TextField(
controller: TextEditingController(text: component['label'] ?? ''),
onChanged: (value){
component['label']=value;
},
)),
DataCell(
DropdownButtonFormField<String>(
value: component['type'],
decoration:
const InputDecoration(labelText: 'Select Type'),
items: [
...typeFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['type'] = value;
});
},
),
),
DataCell(
DropdownButtonFormField<String>(
value: component['mapping'],
decoration:
const InputDecoration(labelText: 'Select Mapping'),
items: [
...mappingFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['mapping'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['mandatory'] ?? ''),
onChanged: (value){
component['mandatory']=value;
},
)),
DataCell(
DropdownButtonFormField<String>(
value: component['readonly'],
decoration:
const InputDecoration(labelText: 'Select Read Only'),
items: [
...truefalseFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item),
);
},
),
],
onChanged: (value) {
setState(() {
component['readonly'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['drop_values'] ?? ''),
onChanged: (value){
component['drop_values']=value;
},
)),
DataCell(TextField(
controller: TextEditingController(text: component['sp'] ?? ''),
onChanged: (value){
component['sp']=value;
},
)),
DataCell(
ElevatedButton(
onPressed: () {
setState(() {
components.removeAt(index);
});
},
child: Text('Delete'),
),
),
],
);
}).toList(),
),
),
ElevatedButton(
onPressed: () {
// Add a new row to the components table
components.add({
'label': '',
'type': null,
'mapping': null,
'mandatory': '',
'readonly': null,
'drop_values': '',
'sp': '',
});
setState(() {}); // Refresh the UI to show the new row
},
child: Text('Add Row'),
),
ElevatedButton(
onPressed: () async {
// Save the updated data back to the original data list
widget.formData['form_name'] = formNameController.text;
widget.formData['form_desc'] = formDescController.text;
widget.formData['related_to'] = relatedToController.text;
widget.formData['page_event'] = pageEventController.text;
widget.formData['button_caption'] = buttonCaptionController.text;
widget.formData['components'] = components;
final token = await TokenManager.getToken();
apiService.updateDynamicForm(token!, widget.formData['form_id'], widget.formData);
Navigator.of(context).pop();
},
child: Text('Update'),
),
],
),
),
),
);
}
}
@@ -0,0 +1,333 @@
import 'package:flutter/material.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../theme/app_style.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import '../../widgets/custom_button.dart';
import '../../widgets/custom_dropdown_field.dart';
import '../../widgets/custom_text_form_field.dart';
import 'dynamic_form_service.dart';
class CreateForm extends StatefulWidget {
@override
_CreateFormState createState() => _CreateFormState();
}
class _CreateFormState extends State<CreateForm> {
TextEditingController formNameController = TextEditingController();
TextEditingController formDescController = TextEditingController();
TextEditingController relatedToController = TextEditingController();
TextEditingController pageEventController = TextEditingController();
TextEditingController buttonCaptionController = TextEditingController();
final DynamicForApiService apiService = DynamicForApiService();
List<Map<String, dynamic>> components = [];
List<dynamic> relatedToFixedDropdown = ['Menu', 'Related To',];
List<dynamic> pageEventFixedDropdown = ['OnClick', 'OnBlur',];
List<dynamic> typeFixedDropdown = ['text', 'dropdown','date','checkbox','textarea','togglebutton'];
List<dynamic> mappingFixedDropdown = ['TEXTFIELD1', 'TEXTFIELD2','TEXTFIELD3','TEXTFIELD4','TEXTFIELD5','TEXTFIELD6','TEXTFIELD7','TEXTFIELD8','TEXTFIELD9','TEXTFIELD10','TEXTFIELD11','TEXTFIELD12','TEXTFIELD13','TEXTFIELD14','TEXTFIELD15','TEXTFIELD16','TEXTFIELD17','TEXTFIELD18','TEXTFIELD19','TEXTFIELD20','TEXTFIELD21','TEXTFIELD22','TEXTFIELD23',
'TEXTFIELD24','TEXTFIELD25','TEXTFIELD26','LONGTEXT1','LONGTEXT2','LONGTEXT3','LONGTEXT4',];
List<dynamic> truefalseFixedDropdown = ['true', 'false',];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleft,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
centerTitle: true,
title: AppbarTitle(text: "Create Dynamic Form"),),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Form Name",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Form Name",
controller: formNameController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Form Description",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Form Description",
controller: formDescController,
margin: getMargin(top: 6))
])),
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Select Related To",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900,
),
CustomDropdownFormField(
items: [
...relatedToFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item, style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
relatedToController.text = value!;
});
},
)
],
),
),
Padding(
padding: getPadding(top: 18),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Select Page Event",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroyMedium16Bluegray900,
),
CustomDropdownFormField(
items: [
...pageEventFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
pageEventController.text = value!;
});
},
)
],
),
),
Padding(
padding: getPadding(top: 19),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text("Button Caption",
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle
.txtGilroyMedium16Bluegray900),
CustomTextFormField(
focusNode: FocusNode(),
hintText: "Enter Button Caption",
controller: buttonCaptionController,
margin: getMargin(top: 6))
])),
const Text('Components Details'),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Label')),
DataColumn(label: Text('Type')),
DataColumn(label: Text('Mapping')),
DataColumn(label: Text('Mandatory')),
DataColumn(label: Text('Readonly')),
DataColumn(label: Text('Drop Values')),
DataColumn(label: Text('SP')),
],
rows: components.asMap().entries.map((entry) {
final index = entry.key;
final component = entry.value;
bool? isReadonly = false;
return DataRow(
cells: <DataCell>[
DataCell(TextField(
controller: TextEditingController(text: component['label'] ?? ''),
onChanged: (value) {
component['label'] = value;
},
)),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Type'),
items: [
...typeFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['type'] = value;
});
},
),
),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Mapping'),
items: [
...mappingFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['mapping'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['mandatory'] ?? ''),
onChanged: (value) {
component['mandatory'] = value;
},
)),
DataCell(
DropdownButtonFormField<String>(
decoration:
const InputDecoration(labelText: 'Select Read Only'),
items: [
...truefalseFixedDropdown.map<DropdownMenuItem<String>>(
(item) {
return DropdownMenuItem<String>(
value: item.toString(),
child: Text(item,style: AppStyle.txtGilroyMedium16Bluegray900),
);
},
),
],
onChanged: (value) {
setState(() {
component['readonly'] = value;
});
},
),
),
DataCell(TextField(
controller: TextEditingController(text: component['drop_values'] ?? ''),
onChanged: (value) {
component['drop_values'] = value;
},
)),
DataCell(TextField(
controller: TextEditingController(text: component['sp'] ?? ''),
onChanged: (value) {
component['sp'] = value;
},
)),
],
);
}).toList(),
),
),
CustomButton(
height: getVerticalSize(50),
text: "Add Row",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
components.add({
'label': '',
'type': '',
'mapping': '',
'mandatory': '',
'readonly': '',
'drop_values': '',
'sp': '',
});
setState(() {});
},
),
CustomButton(
height: getVerticalSize(50),
text: "Create Dynamic Form",
margin: getMargin(top: 24, bottom: 5),
onTap: () async {
final dynamicFormData = {
'form_name': formNameController.text,
'form_desc': formDescController.text,
'related_to': relatedToController.text,
'page_event': pageEventController.text,
'button_caption': buttonCaptionController.text,
'components': components,
};
final token = await TokenManager.getToken();
apiService.createDynamicForm(token!, dynamicFormData);
Navigator.of(context).pop();
},
),
],
),
),
),
);
}
}
@@ -0,0 +1,100 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../../resources/api_constants.dart';
import '../LogoutService/Logoutservice.dart';
class DynamicForApiService {
final String baseUrl = ApiConstants.baseUrl;
final Dio dio = Dio();
//api/dynamic_form_build
Future<void> BuildForms(String token, int id) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response =
await dio.get('$baseUrl/api/dynamic_form_build?form_id=$id');
if (response.statusCode == 401) {
LogoutService.logout();
}
if (response.statusCode! <= 209) {
Fluttertoast.showToast(
msg: 'Build success',
backgroundColor: Colors.red,
);
} else {
Fluttertoast.showToast(
msg: 'Unable to build',
backgroundColor: Colors.red,
);
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to Build form: $e');
}
}
Future<List<Map<String, dynamic>>> getallDynamicForms(
String token,
) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
final response = await dio.get('$baseUrl/api/form_setup');
if (response.statusCode == 401) {
LogoutService.logout();
}
final responseData = response.data['items'];
if (responseData is List) {
final entities = responseData.cast<Map<String, dynamic>>();
return entities;
} else if (responseData is Map<String, dynamic>) {
return [responseData];
} else {
throw Exception('Unexpected response type');
}
} catch (e) {
throw Exception('Failed to get modules by projectId: $e');
}
}
Future<void> createDynamicForm(
String token, Map<String, dynamic> entity) async {
try {
print("in post api...$entity");
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.post('$baseUrl/api/form_setup', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to create Dynamic form: $e');
}
}
Future<void> updateDynamicForm(
String token, int entityId, Map<String, dynamic> entity) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response =
await dio.put('$baseUrl/api/form_setup/$entityId', data: entity);
if (response.statusCode == 401) {
LogoutService.logout();
}
print(entity);
} catch (e) {
throw Exception('Failed to update Dynamic form: $e');
}
}
Future<void> deleteDynamicForm(String token, int entityId) async {
try {
dio.options.headers['Authorization'] = 'Bearer $token';
var response = await dio.delete('$baseUrl/api/form_setup/$entityId');
if (response.statusCode == 401) {
LogoutService.logout();
}
} catch (e) {
throw Exception('Failed to delete Dynamic form: $e');
}
}
}
@@ -0,0 +1,224 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../../Utils/color_constants.dart';
import '../../Utils/image_constant.dart';
import '../../Utils/size_utils.dart';
import '../../providers/token_manager.dart';
import '../../widgets/app_bar/appbar_image.dart';
import '../../widgets/app_bar/appbar_title.dart';
import '../../widgets/app_bar/custom_app_bar.dart';
import 'UpdatedynamicForm.dart';
import 'create_dynamicform.dart';
import 'dynamic_form_service.dart';
class DynamicForm extends StatefulWidget {
@override
_DynamicFormState createState() => _DynamicFormState();
}
class _DynamicFormState extends State<DynamicForm> {
final DynamicForApiService apiService = DynamicForApiService();
late List<Map<String, dynamic>> allData = [];
bool isLoading = false;
@override
void initState() {
super.initState();
_loadDynamicForms();
}
Future<void> _loadDynamicForms() async {
final token = await TokenManager.getToken();
try {
final alData = await apiService.getallDynamicForms(token!);
setState(() {
allData = alData;
print('allData fetched...');
});
isLoading = true;
} catch (e) {
isLoading = true;
print('Failed to load allData: $e');
}
}
Future<void> deleteEntity(Map<String, dynamic> entity) async {
try {
final token = await TokenManager.getToken();
await apiService.deleteDynamicForm(token!, entity['form_id']);
setState(() {
allData.remove(entity);
});
} catch (e) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Error'),
content: Text('Failed to delete entity: $e'),
actions: [
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
height: getVerticalSize(49),
leadingWidth: 40,
leading: AppbarImage(
height: getSize(24),
width: getSize(24),
svgPath: ImageConstant.imgArrowleftBlueGray900,
margin: getMargin(left: 16, top: 12, bottom: 13),
onTap: () {
Navigator.pop(context);
}),
actions: [
GestureDetector(
child: Icon(
Icons.add,
color: Colors.black,
size: 20,
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CreateForm(),
),
).then((value) => {_loadDynamicForms()});
},
),
const SizedBox(
width: 20,
)
],
centerTitle: true,
title: AppbarTitle(text: "Dynamic Form")),
body: isLoading == false
? const Center(child: CircularProgressIndicator())
: allData.isEmpty
? const Center(
child: Text('No Services available.'),
)
: Scrollable(
viewportBuilder:
(BuildContext context, ViewportOffset position) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: [
DataColumn(label: Text('Form Name')),
DataColumn(label: Text('Form Description')),
DataColumn(label: Text('Related To')),
DataColumn(label: Text('Page Event')),
DataColumn(label: Text('Button Caption')),
DataColumn(label: Text('Build')),
DataColumn(label: Text('Actions')),
],
rows: allData.map((module) {
return DataRow(
cells: [
DataCell(
Text('${module['form_name'] ?? 'N/A'}')),
DataCell(
Text('${module['form_desc'] ?? 'N/A'}')),
DataCell(
Text('${module['related_to'] ?? 'N/A'}')),
DataCell(
Text('${module['page_event'] ?? 'N/A'}')),
DataCell(Text(
'${module['button_caption'] ?? 'N/A'}')),
DataCell(Row(
children: [
ElevatedButton(
onPressed: () async {
print(module);
final token =
await TokenManager.getToken();
apiService.BuildForms(
token!, module['form_id']);
},
child: Text("build"),
style: ElevatedButton.styleFrom(
backgroundColor: ColorConstant.blue700,
),
)
],
)),
DataCell(Row(
children: [
IconButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
EditForm(formData: module),
),
).then(
(value) => {_loadDynamicForms()});
},
icon: Icon(Icons.edit),
),
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(
'Confirm Deletion'),
content: const Text(
'Are you sure you want to delete this Module?'),
actions: [
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Delete'),
onPressed: () {
Navigator.of(context).pop();
deleteEntity(module);
},
),
],
);
},
);
},
icon: Icon(Icons.delete),
),
],
)),
],
);
}).toList(),
),
),
);
},
),
);
}
}