feat: refactor SDUI widget model to use sealed classes for type-safe handling, enhance form widget with stepper support, and improve error handling in SDUIFormWidget

This commit is contained in:
2025-12-31 13:36:13 +03:30
parent 8c25e2c65c
commit fb0b817cf9
14 changed files with 4879 additions and 654 deletions

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/features/vet_farm/presentation/pages/root/logic.dart';
import 'package:rasadyar_chicken/presentation/widget/sdui/model/sdui_widget_model.dart';
import 'package:rasadyar_chicken/presentation/widget/sdui/model/sdui_widget.dart';
import 'package:rasadyar_core/core.dart';
class NewPageLogic extends GetxController {
@@ -14,19 +15,11 @@ class NewPageLogic extends GetxController {
@override
void onInit() {
super.onInit();
getSDUIForm();
}
@override
void onReady() {
super.onReady();
// Ready logic here
}
@override
void onClose() {
// Dispose all controllers
for (var controller in controllers.values) {
controller.dispose();
}
@@ -40,10 +33,6 @@ class NewPageLogic extends GetxController {
onSuccess: (result) {
if (result.data != null) {
try {
iLog('SDUI JSON received: ${result.data}');
// Extract SDUI data from info structure
// JSON structure: { "info": { "type": "column", "visible": true, "data": {...}, "children": [...] } }
Map<String, dynamic>? sduiData;
if (result.data!['info'] != null && result.data!['info'] is Map) {
final infoMap = result.data!['info'] as Map<String, dynamic>;
@@ -68,9 +57,63 @@ class NewPageLogic extends GetxController {
if (sduiData != null) {
iLog('SDUI data to parse: $sduiData');
sduiModel.value = SDUIWidgetModel.fromJson(sduiData);
sduiModel.value = SDUIWidgetModel.fromRawJson(sduiData);
// Log model info using pattern matching
final modelType =
sduiModel.value?.maybeWhen(
textFormField: (data, visible) => 'text_form_field',
cardLabelItem:
(data, child, children, visible, visibleCondition) =>
'card_label_item',
chipSelection: (data, visible) => 'chip_selection',
dropdown: (data, visible) => 'dropdown',
imagePicker: (data, visible) => 'image_picker',
column:
(
children,
spacing,
mainAxisSize,
crossAxisAlignment,
visible,
paddingHorizontal,
paddingVertical,
) => 'column',
row: (children, spacing, mainAxisAlignment, visible) =>
'row',
sizedBox: (width, height, visible) => 'sized_box',
stepper: (data, children, visible, index) => 'stepper',
pageView: (data, children, visible) => 'page_view',
orElse: () => 'unknown',
) ??
'null';
final childrenCount =
sduiModel.value?.maybeWhen(
column:
(
children,
spacing,
mainAxisSize,
crossAxisAlignment,
visible,
paddingHorizontal,
paddingVertical,
) => children.length,
row: (children, spacing, mainAxisAlignment, visible) =>
children.length,
cardLabelItem:
(data, child, children, visible, visibleCondition) =>
(child != null ? 1 : 0) + (children?.length ?? 0),
stepper: (data, children, visible, index) =>
children?.length ?? 0,
pageView: (data, children, visible) => children.length,
orElse: () => 0,
) ??
0;
iLog(
'SDUI Model parsed successfully. Type: ${sduiModel.value?.type}, Visible: ${sduiModel.value?.visible}, Children count: ${sduiModel.value?.children?.length ?? 0}',
'SDUI Model parsed successfully. Type: $modelType, Visible: ${sduiModel.value?.visible}, Children count: $childrenCount',
);
_initializeControllers(sduiModel.value!);
} else {
@@ -98,23 +141,54 @@ class NewPageLogic extends GetxController {
}
void _extractTextFields(SDUIWidgetModel model) {
if (model.type == 'text_form_field' && model.data != null) {
final key = model.data!['key'] as String?;
final value = model.data!['value'] as String?;
if (key != null && !controllers.containsKey(key)) {
controllers[key] = TextEditingController(text: value ?? '');
}
}
// Extract text form field using pattern matching
model.maybeWhen(
textFormField: (data, visible) {
final key = data.key;
final value = data.value;
if (key != null && !controllers.containsKey(key)) {
controllers[key] = TextEditingController(text: value ?? '');
}
},
orElse: () {},
);
if (model.child != null) {
_extractTextFields(SDUIWidgetModel.fromJson(model.child!));
}
if (model.children != null) {
for (var child in model.children!) {
_extractTextFields(SDUIWidgetModel.fromJson(child));
}
}
// Recursively extract from children using pattern matching
model.maybeWhen(
column: (children, spacing, mainAxisSize, crossAxisAlignment, visible, paddingHorizontal, paddingVertical) {
for (var child in children) {
_extractTextFields(child);
}
},
row: (children, spacing, mainAxisAlignment, visible) {
for (var child in children) {
_extractTextFields(child);
}
},
cardLabelItem: (data, child, children, visible, visibleCondition) {
if (child != null) {
_extractTextFields(child);
}
if (children != null) {
for (var child in children) {
_extractTextFields(child);
}
}
},
stepper: (data, children, visible, index) {
if (children != null) {
for (var child in children) {
_extractTextFields(child);
}
}
},
pageView: (data, children, visible) {
for (var child in children) {
_extractTextFields(child);
}
},
orElse: () {},
);
}
void onButtonPressed() {

View File

@@ -34,10 +34,9 @@ class NewPage extends GetView<NewPageLogic> {
isScrollControlled: true,
enableDrag: true,
BaseBottomSheet(
height: Get.height * 0.8,
child: ObxValue((data) {
rootChild: ObxValue((data) {
if (data.value == null) {
return Center(child: CircularProgressIndicator());
}
@@ -61,6 +60,27 @@ class NewPage extends GetView<NewPageLogic> {
},
),
SizedBox(height: 24.h),
RElevated(
text: '222222222222دکمه نمونه',
onPressed: () {
Get.bottomSheet(
isScrollControlled: true,
enableDrag: true,
BaseBottomSheet(
height: Get.height * 0.8,
rootChild: Column(
children: [
Container(height: 100, width: 100, color: Colors.red),
Expanded(child: Container(color: Colors.blue)),
Container(height: 100, width: 100, color: Colors.green),
],
),
),
);
},
),
],
),
);