}
}
+class CopyDbFields extends FieldMetaData {
+ CopyDbFields(String name, {String options = ''})
+ : super(name, options, dataType: DataType.undefined);
+}
+
/// Describes a field related to a database column.
class DbFieldMetaData extends WidgetMetaData {
PropertyMetaData? reference;
}
enum DisplayType {
- text,
- combobox,
checkbox,
+ combobox,
custom,
+ text,
}
class DummyModule extends ModuleMetaData {
: super(name, WidgetType.field);
}
+class ListPageMetaData extends PageMetaData {
+ final String tableHeaders;
+ final String tableColumns;
+ ListPageMetaData(String label,
+ {String name = '',
+ required List<WidgetMetaData> fields,
+ required this.tableColumns,
+ required this.tableHeaders,
+ String globalComboBoxes = ''})
+ : super(label, PageType.list,
+ name: name, fields: fields, globalComboBoxes: globalComboBoxes);
+}
+
class MetaException extends FormatException {}
/// Stores the meta data of a module.
///
/// Override it if needed.
void onInitialized() {
- // do nothing
+ for (var page in this.pageList){
+ page.onInitialized();
+ }
}
/// Returns the meta data of a page given by its [name] or null if missing.
final String label;
final PageType pageType;
ModuleMetaData module = DummyModule();
- final List<FieldMetaData>? field = [];
- PageMetaData(this.label, this.pageType, {String name = ''}) {
+ final List<WidgetMetaData> fields;
+ final String globalComboBoxes;
+ PageMetaData(this.label, this.pageType,
+ {String name = '', required this.fields, this.globalComboBoxes = ''}) {
if (name.isEmpty) {
name = enumToString(pageType);
}
this.name = name;
}
+ void onInitialized(){
+ var newFields = <WidgetMetaData>[];
+ var toDelete = <WidgetMetaData>[];
+ for (var field in fields){
+ if (field is CopyDbFields){
+ String excluded = '';
+ final start = field.options.indexOf('excluded=');
+ if (start >= 0){
+ var end = field.options.indexOf(':', start);
+ if (end < 0){
+ end = field.options.length;
+ }
+ excluded = ' ' + field.options.substring(start, end) + ' ';
+ }
+ for (var property in module.propertyList){
+ if (excluded.contains(" ${property.name} ")){
+ continue;
+ }
+ if (! property.hasOption(':hidden:')) {
+ newFields.add(property);
+ }
+ }
+ toDelete.add(field);
+ }
+ }
+ for (var field in toDelete){
+ fields.remove(field);
+ }
+ fields.addAll(newFields);
+ }
}
enum PageType { create, custom, delete, edit, list }
/// Stores the meta data of a module property stored as column in a database.
-class PropertyMetaData {
- /// Name of the property (Dart name).
- final String name;
+class PropertyMetaData extends WidgetMetaData {
ModuleMetaData module = DummyModule();
final String label;
/// The size if dataType is DataType.string.
final int size;
String columnName;
-
+ var validators = <String>[];
/// The foreign key if dataType is DataType.reference, e.g. 'users.user_id'
String? foreignKey;
- PropertyMetaData(this.name, this.label, this.dataType, this.options,
+ PropertyMetaData(String name, this.label, this.dataType, this.options,
{this.displayType = DisplayType.text,
this.columnName = '',
this.size = 0,
this.foreignKey,
- int weight = 6}) {
+ int weight = 6, List<String>? validators})
+ : super(name, WidgetType.property) {
this.weight = weight > 12 ? 12 : weight;
+ this.validators = validators ?? [];
}
/// Returns whether a given [option] is set.
WidgetMetaData(this.name, this.widgetType);
}
-enum WidgetType { button, field, dbField }
+enum WidgetType { button, field, dbField, property }
import 'roles_meta.dart';
import 'structures_meta.dart';
import 'users_meta.dart';
-
/// Returns the meta data of the module given by [name].
/// Returns null if not found.
ModuleMetaData? moduleByName(String name) {
}
return rc;
}
-
/// Returns the module names as string list.
-List<String> moduleNames() {
+List<String> moduleNames(){
return [
'Roles',
'Structures',
'changedBy', i18n.tr('Changed by'), DataType.string, ':hidden:',
size: 32),
], [
- PageMetaData('New Role', PageType.create),
- PageMetaData('Change Role', PageType.edit),
- PageMetaData('Roles Overview', PageType.list),
+ PageMetaData('New Role', PageType.create,
+ fields: [CopyDbFields('filters')]),
+ PageMetaData('Change Role', PageType.edit,
+ fields: [CopyDbFields('filters')]),
+ ListPageMetaData(
+ 'Roles Overview',
+ fields: [
+ PropertyMetaData('text', i18n.tr('Text'), DataType.string,
+ ':where=!text IS NONE OR (role_name like !text):',
+ size: 64),
+ ],
+ tableColumns: 'role_id;role_name',
+ tableHeaders: i18n.tr('Id;Name'),
+ ),
]);
@override
- void onInitialized() {}
+ void onInitialized() {
+ super.onInitialized();
+ }
}
'changedBy', i18n.tr('Changed by'), DataType.string, ':hidden:',
size: 32),
], [
- PageMetaData('New Structure', PageType.create),
- PageMetaData('Change Structure', PageType.edit),
- PageMetaData('Delete Structure', PageType.delete),
- PageMetaData('Structures Overview', PageType.list),
+ PageMetaData('New Structure', PageType.create,
+ fields: [CopyDbFields('filters')]),
+ PageMetaData('Change Structure', PageType.edit,
+ fields: [CopyDbFields('filters')]),
+ PageMetaData('Delete Structure', PageType.delete,
+ fields: [CopyDbFields('filters')]),
+ ListPageMetaData(
+ 'Structures Overview',
+ fields: [
+ PropertyMetaData('text', i18n.tr('Text'), DataType.string,
+ ':where=!text IS NONE OR structure_name like !text OR structure_value like !text:',
+ size: 64),
+ ],
+ tableColumns:
+ 'structure_id;structure_scope;structure_name;structure_value;structure_position',
+ tableHeaders: i18n.tr('Id;Scope;Name;Value;Position'),
+ ),
]);
+ @override
+ void onInitialized() {
+ super.onInitialized();
+ }
}
size: 32),
PropertyMetaData(
'email', i18n.tr('EMail', M), DataType.string, ':unique:notnull:',
- size: 255),
+ size: 255, validators: ['isEmail(input)']),
PropertyMetaData(
'role', i18n.tr('Role'), DataType.reference, ':notnull:',
displayType: DisplayType.combobox,
'changedBy', i18n.tr('Changed by'), DataType.string, ':hidden:',
size: 32),
], [
- PageMetaData('New User', PageType.create),
- PageMetaData('Change User', PageType.edit),
- PageMetaData('Delete User', PageType.delete),
- PageMetaData('Users Overview', PageType.list),
+ PageMetaData(
+ 'New User',
+ PageType.create,
+ fields: [CopyDbFields('filters')],
+ globalComboBoxes: 'comboRoles',
+ ),
+ PageMetaData(
+ 'Change User',
+ PageType.edit,
+ fields: [CopyDbFields('filters')],
+ globalComboBoxes: 'comboRoles',
+ ),
+ PageMetaData(
+ 'Delete User',
+ PageType.delete,
+ fields: [CopyDbFields('filters')],
+ globalComboBoxes: 'comboRoles',
+ ),
+ ListPageMetaData(
+ 'Users Overview',
+ fields: [
+ PropertyMetaData('text', i18n.tr('Text'), DataType.string, '',
+ size: 64),
+ PropertyMetaData('role', i18n.tr('Role'), DataType.reference, '',
+ displayType: DisplayType.combobox,
+ foreignKey: 'roles.role_id;role_name;role'),
+ ],
+ tableColumns: 'user_id;user_displayname;user_email;role',
+ tableHeaders: i18n.tr('Id;Display Name;Email;Role'),
+ globalComboBoxes: 'comboRoles',
+ ),
]);
+ @override
+ void onInitialized() {
+ super.onInitialized();
+ }
}
}
class _CreateRolePageState extends CreateRoleCustom {
- _CreateRolePageState() : super();
+ _CreateRolePageState(): super();
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
}
class _EditRolePageState extends EditRoleCustom {
- _EditRolePageState(int primaryKey) : super(primaryKey);
+ _EditRolePageState(int primaryKey): super(primaryKey);
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
}
class _ListRolePageState extends ListRoleCustom {
- _ListRolePageState() : super();
+ _ListRolePageState(): super();
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
@override
_CreateStructurePageState createState() {
final rc = _CreateStructurePageState();
- rc.attendedPage = AttendedPage(
- this, rc, GlobalData(), StructureMeta.instance, pageStates);
+ rc.attendedPage =
+ AttendedPage(this, rc, GlobalData(), StructureMeta.instance, pageStates);
pageStates.attendedPage = rc.attendedPage;
return rc;
}
}
class _CreateStructurePageState extends CreateStructureCustom {
- _CreateStructurePageState() : super();
+ _CreateStructurePageState(): super();
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
@override
_DeleteStructurePageState createState() {
final rc = _DeleteStructurePageState(this.primaryKey);
- rc.attendedPage = AttendedPage(
- this, rc, GlobalData(), StructureMeta.instance, pageStates);
+ rc.attendedPage =
+ AttendedPage(this, rc, GlobalData(), StructureMeta.instance, pageStates);
pageStates.attendedPage = rc.attendedPage;
return rc;
}
}
class _DeleteStructurePageState extends DeleteStructureCustom {
- _DeleteStructurePageState(int primaryKey) : super(primaryKey);
+ _DeleteStructurePageState(int primaryKey): super(primaryKey);
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
@override
_EditStructurePageState createState() {
final rc = _EditStructurePageState(this.primaryKey);
- rc.attendedPage = AttendedPage(
- this, rc, GlobalData(), StructureMeta.instance, pageStates);
+ rc.attendedPage =
+ AttendedPage(this, rc, GlobalData(), StructureMeta.instance, pageStates);
pageStates.attendedPage = rc.attendedPage;
return rc;
}
}
class _EditStructurePageState extends EditStructureCustom {
- _EditStructurePageState(int primaryKey) : super(primaryKey);
+ _EditStructurePageState(int primaryKey): super(primaryKey);
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
@override
_ListStructurePageState createState() {
final rc = _ListStructurePageState();
- rc.attendedPage = AttendedPage(
- this, rc, GlobalData(), StructureMeta.instance, pageStates);
+ rc.attendedPage =
+ AttendedPage(this, rc, GlobalData(), StructureMeta.instance, pageStates);
pageStates.attendedPage = rc.attendedPage;
return rc;
}
}
class _ListStructurePageState extends ListStructureCustom {
- _ListStructurePageState() : super();
+ _ListStructurePageState(): super();
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
final _fieldData = _FieldData();
final GlobalKey<FormState> _formKey =
GlobalKey<FormState>(debugLabel: 'CreateUser');
+ final nameController = TextEditingController();
+ final displayNameController = TextEditingController();
+ final emailController = TextEditingController();
CreateUserCustom();
@override
Widget build(BuildContext context) {
final padding = GlobalThemeData.padding;
comboRolesFromBackend(
attendedPage: attendedPage!, onDone: () => setState(() => 1));
- final itemsRole = comboRoles(
+ final itemsRoles = comboRoles(
i18n.trDyn(GlobalTranslations.comboboxSelect), attendedPage!);
+ nameController.text = _fieldData.name;
+ displayNameController.text = _fieldData.displayName;
+ emailController.text = _fieldData.email;
final formItems = <FormItem>[
FormItem(
TextFormField(
- initialValue: _fieldData.name,
- style: TextStyle(
- backgroundColor: GlobalThemeData.formTextBackgroundColor,
- decorationStyle: TextDecorationStyle.double),
- decoration: InputDecoration(
- labelText: i18n.tr('Name'),
- ),
+ controller: nameController,
+ decoration: InputDecoration(labelText: i18n.tr('Name')),
validator: (input) => notEmpty(input),
onSaved: (value) => _fieldData.name = value ?? '',
),
weight: 6),
FormItem(
TextFormField(
- initialValue: _fieldData.displayName,
+ controller: displayNameController,
decoration: InputDecoration(labelText: i18n.tr('Display name')),
validator: (input) => notEmpty(input),
onSaved: (value) => _fieldData.displayName = value ?? '',
weight: 6),
FormItem(
TextFormField(
- initialValue: _fieldData.email,
- decoration: InputDecoration(labelText: i18n.tr('Email')),
- validator: (input) => validateMultiple(
- input, [(input) => notEmpty(input), (input) => isEmail(input)]),
+ controller: emailController,
+ decoration: InputDecoration(labelText: i18n.tr('EMail')),
+ validator: (input) => notEmpty(input),
onSaved: (value) => _fieldData.email = value ?? '',
),
weight: 6),
FormItem(
DropdownButtonFormField<int>(
value: _fieldData.role,
- items: itemsRole,
+ items: itemsRoles,
isExpanded: true,
decoration: InputDecoration(labelText: i18n.tr('Role')),
onChanged: (value) => _fieldData.role = value ?? 0,
ElevatedButton(
onPressed: () => verifyAndStore(), child: Text(i18n.tr('Save'))),
weight: 8,
- gapAbove: padding),
+ gapAbove: 2 * padding),
FormItem(
ElevatedButton(
onPressed: () {
+ attendedPage!.pageStates.dbDataState.clear();
globalData.navigate(context, '/Users/list');
},
child: Text(i18n.tr('Cancel')),
weight: 4)
];
final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Create an User')),
+ appBar: globalData.appBarBuilder(i18n.tr('New User')),
drawer: globalData.drawerBuilder(context),
body: SafeArea(
- child: Card(
- color: GlobalThemeData.formBackgroundColor,
- elevation: GlobalThemeData.formElevation,
- margin: EdgeInsets.symmetric(
- vertical: padding, horizontal: padding),
- child: Padding(
- padding: EdgeInsets.symmetric(
+ child: Form(
+ key: _formKey,
+ child: Card(
+ margin: EdgeInsets.symmetric(
vertical: padding, horizontal: padding),
- child: WidgetForm.flexibleGrid(
- formItems,
- screenWidth: attendedPage!.pageStates.screenWidth,
- padding: padding,
- )))));
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage!.pageStates.screenWidth,
+ padding: padding,
+ ))))));
return rc;
}
setError(i18n.tr('Saving data failed: $answer'));
setState(() => 1);
} else {
+ attendedPage!.pageStates.dbDataState.clear();
globalData.navigate(context, '/Users/edit;$id');
}
}
store();
}
}
+
+ @override
+ void dispose() {
+ nameController.dispose();
+ displayNameController.dispose();
+ emailController.dispose();
+ super.dispose();
+ }
}
class _FieldData {
String displayName = '';
String email = '';
int role = 0;
+
void toMap(Map<String, dynamic> map) {
map[':name'] = name;
map[':displayName'] = displayName;
}
class _CreateUserPageState extends CreateUserCustom {
- _CreateUserPageState() : super();
+ _CreateUserPageState(): super();
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
import 'package:flutter/material.dart';
import '../../base/i18n.dart';
+import '../../base/validators.dart';
+import '../../services/global_widget.dart';
import '../../setting/global_data.dart';
import '../../widget/attended_page.dart';
+import '../../widget/message_line.dart';
import '../../widget/widget_form.dart';
import 'delete_user_page.dart';
final i18n = I18N();
-class DeleteUserCustom extends State<DeleteUserPage> {
+class DeleteUserCustom extends State<DeleteUserPage> with MessageLine {
final int primaryKey;
final globalData = GlobalData();
AttendedPage? attendedPage;
-
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'DeleteUser');
+ final nameController = TextEditingController();
+ final displayNameController = TextEditingController();
+ final emailController = TextEditingController();
DeleteUserCustom(this.primaryKey);
@override
Widget build(BuildContext context) {
final padding = GlobalThemeData.padding;
+ comboRolesFromBackend(
+ attendedPage: attendedPage!, onDone: () => setState(() => 1));
+ final itemsRoles = comboRoles(
+ i18n.trDyn(GlobalTranslations.comboboxSelect), attendedPage!);
+ attendedPage?.loadRecord(
+ name: 'record',
+ reload: () => setState(() => 1),
+ onDone: (record) => _fieldData.fromMap(record),
+ parameters: {'module': 'Users', 'sql': 'byId', ':id': primaryKey});
+ nameController.text = _fieldData.name;
+ displayNameController.text = _fieldData.displayName;
+ emailController.text = _fieldData.email;
+ final formItems = <FormItem>[
+ FormItem(
+ TextFormField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: i18n.tr('Name')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.name = value ?? '',
+ ),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: displayNameController,
+ decoration: InputDecoration(labelText: i18n.tr('Display name')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.displayName = value ?? '',
+ ),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: emailController,
+ decoration: InputDecoration(labelText: i18n.tr('EMail')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.email = value ?? '',
+ ),
+ weight: 6),
+ FormItem(
+ DropdownButtonFormField<int>(
+ value: _fieldData.role,
+ items: itemsRoles,
+ isExpanded: true,
+ decoration: InputDecoration(labelText: i18n.tr('Role')),
+ onChanged: (value) => _fieldData.role = value ?? 0,
+ ),
+ weight: 6),
+ FormItem(
+ ElevatedButton(
+ onPressed: () => verifyAndDelete(), child: Text(i18n.tr('Delete'))),
+ weight: 8,
+ gapAbove: 2 * padding),
+ FormItem(
+ ElevatedButton(
+ onPressed: () {
+ attendedPage!.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/Users/list');
+ },
+ child: Text(i18n.tr('Cancel')),
+ ),
+ weight: 4)
+ ];
final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Change User data')),
+ appBar: globalData.appBarBuilder(i18n.tr('Delete User')),
drawer: globalData.drawerBuilder(context),
body: SafeArea(
- child: WidgetForm.flexibleGridAttended(
- attendedPage!.attendedWidgets(),
- screenWidth: attendedPage!.pageStates.screenWidth,
- padding: padding)));
+ child: Form(
+ key: _formKey,
+ child: Card(
+ margin: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage!.pageStates.screenWidth,
+ padding: padding,
+ ))))));
return rc;
}
void initState() {
super.initState();
}
+
+ void delete() {
+ final parameters = <String, dynamic>{
+ 'module': 'Users',
+ 'sql': 'delete',
+ };
+ _fieldData.toMap(parameters);
+ globalData.restPersistence!
+ .store(what: 'store', map: parameters)
+ .then((answer) {
+ globalData.navigate(context, '/Users/list');
+ });
+ }
+
+ void verifyAndDelete() {
+ if (_formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ delete();
+ }
+ }
+
+ @override
+ void dispose() {
+ nameController.dispose();
+ displayNameController.dispose();
+ emailController.dispose();
+ super.dispose();
+ }
+}
+
+class _FieldData {
+ String name = '';
+ String displayName = '';
+ String email = '';
+ int role = 0;
+
+ void fromMap(Map<String, dynamic> map) {
+ name = map['user_name'];
+ displayName = map['user_displayname'];
+ email = map['user_email'];
+ role = map['user_role'];
+ }
}
}
class _DeleteUserPageState extends DeleteUserCustom {
- _DeleteUserPageState(int primaryKey) : super(primaryKey);
+ _DeleteUserPageState(int primaryKey): super(primaryKey);
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
final padding = GlobalThemeData.padding;
comboRolesFromBackend(
attendedPage: attendedPage!, onDone: () => setState(() => 1));
- final itemsRole = comboRoles(
+ final itemsRoles = comboRoles(
i18n.trDyn(GlobalTranslations.comboboxSelect), attendedPage!);
attendedPage?.loadRecord(
name: 'record',
FormItem(
TextFormField(
controller: emailController,
- decoration: InputDecoration(labelText: i18n.tr('Email')),
- validator: (input) => validateMultiple(
- input, [(input) => notEmpty(input), (input) => isEmail(input)]),
+ decoration: InputDecoration(labelText: i18n.tr('EMail')),
+ validator: (input) => notEmpty(input),
onSaved: (value) => _fieldData.email = value ?? '',
),
weight: 6),
FormItem(
DropdownButtonFormField<int>(
value: _fieldData.role,
- items: itemsRole,
+ items: itemsRoles,
isExpanded: true,
decoration: InputDecoration(labelText: i18n.tr('Role')),
onChanged: (value) => _fieldData.role = value ?? 0,
weight: 4)
];
final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Change an User')),
+ appBar: globalData.appBarBuilder(i18n.tr('Change User')),
drawer: globalData.drawerBuilder(context),
body: SafeArea(
child: Form(
child: Card(
margin: EdgeInsets.symmetric(
vertical: padding, horizontal: padding),
- child: WidgetForm.flexibleGrid(
- formItems,
- screenWidth: attendedPage!.pageStates.screenWidth,
- padding: padding,
- )))));
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage!.pageStates.screenWidth,
+ padding: padding,
+ ))))));
return rc;
}
final parameters = <String, dynamic>{
'module': 'Users',
'sql': 'update',
- ':id': primaryKey,
- ':name': _fieldData.name,
- ':displayName': _fieldData.displayName,
- ':email': _fieldData.email,
- ':role': _fieldData.role,
- ':createdBy': GlobalData.loginUserName,
};
_fieldData.toMap(parameters);
globalData.restPersistence!
.store(what: 'store', map: parameters)
.then((answer) {
- if (answer.startsWith('id:')) {
- final id = int.tryParse(answer.substring(3));
- if (id == null || id == 0) {
- setError(i18n.tr('Saving data failed: $answer'));
- setState(() => 1);
- } else {
- attendedPage!.pageStates.dbDataState.clear();
- globalData.navigate(context, '/Users/edit;$id');
- }
- }
+
});
}
store();
}
}
+
+ @override
+ void dispose() {
+ nameController.dispose();
+ displayNameController.dispose();
+ emailController.dispose();
+ super.dispose();
+ }
}
class _FieldData {
String displayName = '';
String email = '';
int role = 0;
+
void fromMap(Map<String, dynamic> map) {
name = map['user_name'];
displayName = map['user_displayname'];
email = map['user_email'];
role = map['user_role'];
}
-
void toMap(Map<String, dynamic> map) {
+ map[':id'] = primaryKey;
map[':name'] = name;
map[':displayName'] = displayName;
map[':email'] = email;
map[':role'] = role;
- map[':createdBy'] = GlobalData.loginUserName;
+ map[':changedBy'] = GlobalData.loginUserName;
}
}
}
class _EditUserPageState extends EditUserCustom {
- _EditUserPageState(int primaryKey) : super(primaryKey);
+ _EditUserPageState(int primaryKey): super(primaryKey);
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
final padding = GlobalThemeData.padding;
comboRolesFromBackend(
attendedPage: attendedPage!, onDone: () => setState(() => 1));
- final itemsRole = comboRoles(
+ final itemsRoles = comboRoles(
i18n.trDyn(GlobalTranslations.comboboxItemAll), attendedPage!);
final formItems = <FormItem>[
FormItem(
TextFormField(
controller: textController,
decoration: InputDecoration(labelText: i18n.tr('Text')),
- onChanged: (value) => _fieldData.text = value,
+ onSaved: (value) => _fieldData.text = value ?? '',
),
weight: 6),
FormItem(
DropdownButtonFormField<int>(
value: _fieldData.role,
- items: itemsRole,
+ items: itemsRoles,
isExpanded: true,
decoration: InputDecoration(labelText: i18n.tr('Role')),
onChanged: (value) => _fieldData.role = value ?? 0,
ElevatedButton(
onPressed: () => search(), child: Text(i18n.tr('Search'))),
weight: 12,
- gapAbove: padding)
+ gapAbove: padding),
];
final form = Form(
key: _formKey,
child: WidgetForm.flexibleGrid(formItems,
screenWidth: attendedPage!.pageStates.screenWidth,
padding: padding))));
-
final rows = attendedPage!.getRows(
columnList: 'user_id;user_displayname;user_email;role',
what: 'query',
label: Text(i18n.tr('Id')),
),
DataColumn(
- label: Text(i18n.tr('Name')),
+ label: Text(i18n.tr('Display Name')),
),
DataColumn(
- label: Text(i18n.tr('EMail')),
+ label: Text(i18n.tr('Email')),
),
DataColumn(
label: Text(i18n.tr('Role')),
void initState() {
super.initState();
}
+ @override
+ void dispose(){
+ textController.dispose();
+ super.dispose();
+ }
}
class _FieldData {
}
class _ListUserPageState extends ListUserCustom {
- _ListUserPageState() : super();
+ _ListUserPageState(): super();
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
import 'package:dart_bones/dart_bones.dart';
+import '../lib/base/defines.dart';
import '../lib/meta/module_meta_data.dart';
import '../lib/meta/modules.dart';
import 'generator.dart';
}
''';
- static final templateCustom = '''// This file is created by the meta_tool. But it can be customized.
+ static final templateGlobalComboBox = ''' comboRolesFromBackend(
+ attendedPage: attendedPage!, onDone: () => setState(() => 1));
+ final itemsRoles = comboRoles(
+ i18n.trDyn(GlobalTranslations.combobox#UNDEF), attendedPage!);''';
+
+ static final templateListCustom =
+ '''// This file is created by the meta_tool. But it can be customized.
// It will never overridden by the meta_tool.
import 'package:flutter/material.dart';
import '../../setting/global_data.dart';
import '../../widget/attended_page.dart';
import '../../widget/widget_form.dart';
-import 'edit_user_page.dart';
+import '../../services/global_widget.dart';
+import 'list_user_page.dart';
final i18n = I18N();
-class EditUserCustom extends State<EditUserPage> {
-DEF_PRIMARY final globalData = GlobalData();
+class ListUserCustom extends State<ListUserPage> {
+ final globalData = GlobalData();
AttendedPage? attendedPage;
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'CreateUser');
+#DEF_CONTROLLERS ListUserCustom();
+ @override
+ Widget build(BuildContext context) {
+ final padding = GlobalThemeData.padding;
+#INIT_COMBOS final formItems = <FormItem>[
+#FORM_ITEMS FormItem(
+ ElevatedButton(
+ onPressed: () => search(), child: Text(i18n.tr('Search'))),
+ weight: 12,
+ gapAbove: padding),
+ ];
+ final form = Form(
+ key: _formKey,
+ child: Card(
+ color: GlobalThemeData.formBackgroundColor,
+ elevation: GlobalThemeData.formElevation,
+ margin:
+ EdgeInsets.symmetric(vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(formItems,
+ screenWidth: attendedPage!.pageStates.screenWidth,
+ padding: padding))));
+ final rows = attendedPage!.getRows(
+ columnList: '#ROW_COLUMNS',
+ what: 'query',
+ parameters: {
+ 'module': 'Users',
+ 'sql': 'list',
+ 'offset': '0',
+ 'size': '10',
+#PARAM_DEF },
+ onDone: () => setState(() => 1),
+ route#EDIT1: '/Users/#EDIT2',
+ context: context);
+ final table = DataTable(
+ columns: <DataColumn>[
+#TABLE_HEADER ],
+ rows: rows,
+ );
+ final frameWidget = Column(children: [
+ form,
+ SizedBox(height: padding),
+ SizedBox(width: double.infinity, child: table),
+ ]);
+ final rc = Scaffold(
+ appBar: globalData.appBarBuilder(i18n.tr('Overview users')),
+ drawer: globalData.drawerBuilder(context),
+ floatingActionButton: FloatingActionButton(
+ onPressed: () {
+ globalData.navigate(context, '/Users/create');
+ },
+ child: const Icon(Icons.add),
+ //backgroundColor: Colors.green,
+ ),
+ body: SafeArea(child: frameWidget));
+ return rc;
+ }
- EditUserCustom(THIS_PRIMARY);
+ void search() {
+ //@ToDo
+ }
+ @override
+ void initState() {
+ super.initState();
+ }
+ @override
+ void dispose(){
+#DISPOSE_CONTROLLER super.dispose();
+ }
+}
+
+class _FieldData {
+#DEF_FIELDS}
+''';
+
+ static final templateRecordCustom =
+ '''// This file is created by the meta_tool. But it can be customized.
+// It will never overridden by the meta_tool.
+import 'package:flutter/material.dart';
+
+import '../../base/i18n.dart';
+import '../../base/validators.dart';
+import '../../services/global_widget.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import '../../widget/message_line.dart';
+import '../../widget/widget_form.dart';
+import 'edit_user_page.dart';
+
+final i18n = I18N();
+
+class EditUserCustom extends State<EditUserPage> with MessageLine {
+#DEF_PRIMARY final globalData = GlobalData();
+ AttendedPage? attendedPage;
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'EditUser');
+#DEF_CONTROLLER EditUserCustom(#THIS_PRIMARY);
@override
Widget build(BuildContext context) {
final padding = GlobalThemeData.padding;
+#INIT_COMBO#LOAD_RECORD#ASSIGN_CONTROLLER final formItems = <FormItem>[
+#FORM_ITEMS FormItem(
+ ElevatedButton(
+ onPressed: () => #ACTION2(), child: Text(i18n.tr('#BUTTON'))),
+ weight: 8,
+ gapAbove: 2 * padding),
+ FormItem(
+ ElevatedButton(
+ onPressed: () {
+ attendedPage!.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/Users/list');
+ },
+ child: Text(i18n.tr('Cancel')),
+ ),
+ weight: 4)
+ ];
final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Change User data')),
+ appBar: globalData.appBarBuilder(i18n.tr('#PAGE_LABEL')),
drawer: globalData.drawerBuilder(context),
body: SafeArea(
- child: WidgetForm.flexibleGrid(attendedPage!.attendedWidgets(),
- screenWidth: attendedPage!.pageStates.screenWidth,
- padding: padding)));
+ child: Form(
+ key: _formKey,
+ child: Card(
+ margin: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage!.pageStates.screenWidth,
+ padding: padding,
+ ))))));
return rc;
}
+
@override
void initState() {
super.initState();
}
+
+ void #ACTION1() {
+ final parameters = <String, dynamic>{
+ 'module': 'Users',
+ 'sql': '#SQL_TYPE',
+ };
+ _fieldData.toMap(parameters);
+ globalData.restPersistence!
+ .store(what: 'store', map: parameters)
+ .then((answer) {
+#STORAGE_DONE
+ });
+ }
+
+ void #ACTION2() {
+ if (_formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ #ACTION1();
+ }
+ }
+
+ @override
+ void dispose() {
+#DISP_CONTROLLER super.dispose();
+ }
}
+
+class _FieldData {
+#DEF_FIELD
+#FROM_MAP#TO_MAP}
+''';
+ static final templateStorageDoneCreate =
+ ''' if (answer.startsWith('id:')) {
+ final id = int.tryParse(answer.substring(3));
+ if (id == null || id == 0) {
+ setError(i18n.tr('Saving data failed: \$answer'));
+ setState(() => 1);
+ } else {
+ attendedPage!.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/#MODULE/edit;\$id');
+ }
+ }''';
+ static final templateStorageDoneEdit = ' setState(() => 1);';
+ static final templateStorageDoneDelete =
+ " globalData.navigate(context, '/#MODULE/list');";
+ static final templateFromMap = ''' void fromMap(Map<String, dynamic> map) {
+#BODY_FROM }
''';
- static final templatePageManager = '''// DO NOT CHANGE. This file is created by the meta_tool!
+ static final templatePageManager =
+ '''// DO NOT CHANGE. This file is created by the meta_tool!
import 'package:flutter/material.dart';
import 'page_manager_custom.dart';
#IMPORTS#
-
/// Manages all meta data driven pages of the program.
class PageManager {
static PageManager? _instance;
}
}
''';
- static final templatePageManagerCustom = '''// This file is created by the meta_tool. But it can be customized.
+
+ static final templatePageManagerCustom =
+ '''// This file is created by the meta_tool. But it can be customized.
// It will never overridden by the meta_tool.
import 'package:flutter/material.dart';
import 'info_page.dart';
return rc;
}
''';
+
static final templateCase = ''' case '/Users/edit':
rc = EditUserPage(ARG1);
break;
''';
+
PageGenerator(BaseLogger logger) : super(logger);
- String replaceVariables(String template, PageMetaData page) {
- final camelModules = toCamelCase(page.module.moduleName);
- final camelModule = toCamelCase(page.module.moduleNameSingular);
- final camelPageName = toCamelCase(page.name);
- final rc = template
- .replaceAll('Users', camelModules)
- .replaceAll('User', camelModule)
- .replaceAll('Edit', camelPageName)
- .replaceAll('edit', page.name)
- .replaceAll('users', page.module.moduleName.toLowerCase())
- .replaceAll('user', page.module.moduleNameSingular.toLowerCase());
- return rc;
+ String buildAssignControllers(PageMetaData page) {
+ final buffer = StringBuffer();
+ for (var field in page.fields) {
+ if (field.widgetType == WidgetType.property &&
+ (field as PropertyMetaData).displayType == DisplayType.text) {
+ buffer.writeln(
+ ' ${field.name}Controller.text = _fieldData.${field.name};');
+ }
+ }
+ return buffer.toString();
+ }
+
+ String buildButton(
+ {required String onPressed, required String label, String indent = ''}) {
+ final rc = '''^ElevatedButton(
+^ onPressed: () => ONPRESSED,
+^ child: Text(i18n.tr('$label')))'''
+ .replaceAll('^', indent)
+ .replaceFirst('ONPRESSED', onPressed)
+ .replaceFirst('LABEL', label);
+ return rc;
+ }
+
+ String buildDefinitionControllers(PageMetaData page) {
+ final buffer = StringBuffer();
+ for (var field in page.fields) {
+ if (field.widgetType == WidgetType.property &&
+ (field as PropertyMetaData).displayType == DisplayType.text) {
+ buffer.writeln(
+ ' final ${field.name}Controller = TextEditingController();');
+ }
+ }
+ return buffer.toString();
+ }
+
+ String buildDefinitionFields(PageMetaData page) {
+ final buffer = StringBuffer();
+ for (var field in page.fields) {
+ if (field.widgetType != WidgetType.property ||
+ (field as PropertyMetaData).hasOption(':primary:')) {
+ continue;
+ }
+ final name = field.name;
+ final field2 = field as PropertyMetaData;
+ String type;
+ String value;
+ switch (field2.dataType) {
+ case DataType.bool:
+ type = 'bool';
+ value = 'false';
+ break;
+ case DataType.reference:
+ case DataType.int:
+ case DataType.nat:
+ type = 'int';
+ value = '0';
+ break;
+ case DataType.currency:
+ case DataType.float:
+ type = 'double';
+ value = '0';
+ break;
+ case DataType.date:
+ type = 'Date';
+ value = 'Date()';
+ break;
+ case DataType.datetime:
+ type = 'DateTime';
+ value = 'DateTime()';
+ break;
+ case DataType.string:
+ type = 'String';
+ value = "''";
+ break;
+ default:
+ type = 'Object';
+ value = "''";
+ break;
+ // throw FormatException('buildDefinitionFields(): missing ${field2.dataType}');
+ }
+ buffer.writeln(" $type $name = $value;");
+ }
+ return buffer.toString();
+ }
+
+ String buildDisposeControllers(PageMetaData page) {
+ final buffer = StringBuffer();
+ for (var field in page.fields) {
+ if (field.widgetType == WidgetType.property &&
+ (field as PropertyMetaData).displayType == DisplayType.text) {
+ buffer.writeln(' ${field.name}Controller.dispose();');
+ }
+ }
+ return buffer.toString();
}
+
+ String buildField(PropertyMetaData field,
+ {String indent = '', bool withController = false}) {
+ final name = field.name;
+ String rc = '';
+ switch (field.displayType) {
+ case DisplayType.text:
+ final validators = <String>[];
+ if (field.hasOption(':notnull:')) {
+ validators.add('notEmpty(input)');
+ }
+ var validator = '';
+ if (validators.length == 1) {
+ validator = ' validator: (input) => ${validators[0]},\n';
+ } else if (validators.length > 1) {
+ validator =
+ ' validator: (input) => validateMultiple(input, [\n';
+ for (var item in validators) {
+ validator += ' (input) => $item(input),\n';
+ }
+ validator += ' ]),\n';
+ }
+ rc = '''^TextFormField(
+#CONTR^ decoration: InputDecoration(labelText: i18n.tr('${field.label}')),
+#VALIDATOR^ onSaved: (value) => _fieldData.$name = value ?? '',
+^)'''
+ .replaceFirst('#CONTR',
+ withController ? '^ controller: ${name}Controller,\n' : '')
+ .replaceFirst('#VALIDATOR', validator)
+ .replaceAll('^', indent);
+ break;
+ case DisplayType.combobox:
+ String name2;
+ if (field.dataType == DataType.reference) {
+ name2 = toCamelCase(field.foreignKey?.split('.')[0] ?? field.name);
+ } else {
+ name2 = field.name;
+ }
+ rc = '''^DropdownButtonFormField<int>(
+^ value: _fieldData.$name,
+^ items: items$name2,
+^ isExpanded: true,
+^ decoration: InputDecoration(labelText: i18n.tr('${field.label}')),
+^ onChanged: (value) => _fieldData.$name = value ?? 0,
+^)'''
+ .replaceAll('^', indent);
+ break;
+ default:
+ throw FormatException(
+ 'buildField(): not implemented: ${field.displayType}');
+ }
+ return rc;
+ }
+
+ String buildFormItems(PageMetaData page, {bool withController = false}) {
+ final buffer = StringBuffer();
+ for (var field in page.fields) {
+ if (field is PropertyMetaData && field.hasOption(':primary:')) {
+ continue;
+ }
+ final weight = (field.widgetType != WidgetType.property)
+ ? 6
+ : (field as PropertyMetaData).weight;
+ buffer.writeln(' FormItem(');
+ if (field is PropertyMetaData) {
+ buffer.writeln(buildField(field,
+ indent: ' ', withController: withController) +
+ ',');
+ buffer.writeln(' weight: $weight),');
+ } else {
+ throw FormatException(
+ 'buildFormItems(): not implemented: ${field.widgetType}');
+ }
+ }
+ return buffer.toString();
+ }
+
+ String buildFromMap(PageMetaData page) {
+ String? rc;
+ if (page.pageType == PageType.edit || page.pageType == PageType.delete) {
+ final buffer =
+ StringBuffer(' void fromMap(Map<String, dynamic> map) {\n');
+ for (var field in page.fields) {
+ if (field is PropertyMetaData && !field.hasOption(':primary:')) {
+ buffer.writeln(" ${field.name} = map['${field.columnName}'];");
+ }
+ }
+ buffer.writeln(' }');
+ rc = buffer.toString();
+ }
+ return rc ?? '';
+ }
+
+ String buildInitializeComboBoxes(PageMetaData page) {
+ final buffer = StringBuffer();
+ if (page.globalComboBoxes.isNotEmpty) {
+ for (var item in page.globalComboBoxes.split(';')) {
+ buffer.writeln(templateGlobalComboBox
+ .replaceFirst(
+ '#UNDEF', page.pageType == PageType.list ? 'ItemAll' : 'Select')
+ .replaceAll('comboRoles', item)
+ .replaceAll('Roles', item.substring(5)));
+ }
+ }
+ return buffer.toString();
+ }
+
+ String buildLoadRecord(PageMetaData page) {
+ String? rc;
+ if (page.pageType == PageType.edit || page.pageType == PageType.delete) {
+ rc = ''' attendedPage?.loadRecord(
+ name: 'record',
+ reload: () => setState(() => 1),
+ onDone: (record) => _fieldData.fromMap(record),
+ parameters: {'module': '${page.module.moduleName}', 'sql': 'byId', ':id': primaryKey});
+''';
+ }
+ return rc ?? '';
+ }
+
+ String buildParamDefinitions(PageMetaData page,
+ {bool withController = false}) {
+ final buffer = StringBuffer();
+ for (var field in page.fields) {
+ final name = field.name;
+ final suffix = field.widgetType != WidgetType.property ||
+ (field as PropertyMetaData).displayType != DisplayType.text
+ ? '.toString()'
+ : '';
+ buffer.writeln(" ':$name': _fieldData.$name$suffix,");
+ }
+ return buffer.toString();
+ }
+
+ String buildTableHeader(ListPageMetaData page) {
+ final buffer = StringBuffer();
+ for (var item in page.tableHeaders.split(';')) {
+ buffer.writeln(''' DataColumn(
+ label: Text(i18n.tr('$item')),
+ ),''');
+ }
+ return buffer.toString();
+ }
+
+ String buildToMap(PageMetaData page) {
+ String? rc;
+ if (page.pageType == PageType.edit || page.pageType == PageType.create) {
+ final buffer = StringBuffer(' void toMap(Map<String, dynamic> map) {\n');
+ if (page.pageType == PageType.edit) {
+ buffer.writeln(" map[':id'] = primaryKey;");
+ }
+ for (var field in page.fields) {
+ if (!(field is PropertyMetaData) || field.hasOption(':primary:')) {
+ continue;
+ }
+ final name = field.name;
+ buffer.writeln(" map[':$name'] = $name;");
+ }
+ buffer.writeln(" map[':#'] = GlobalData.loginUserName;".replaceFirst(
+ '#', page.pageType == PageType.edit ? 'changedBy' : 'createdBy'));
+ buffer.writeln(' }');
+ rc = buffer.toString();
+ }
+ return rc ?? '';
+ }
+
/// Returns a Dart class definition of the [page] that should not be modified.
String createCustomized(PageMetaData page) {
- var rc = replaceVariables(templateCustom, page);
- if (page.pageType == PageType.edit || page.pageType == PageType.delete) {
- rc = rc.replaceAll('DEF_PRIMARY', ' final int primaryKey;\n')
- .replaceAll('THIS_PRIMARY', 'this.primaryKey');
- } else {
- rc = rc.replaceAll('DEF_PRIMARY', '')
- .replaceAll('THIS_PRIMARY', '');
+ String rc;
+ switch (page.pageType) {
+ case PageType.list:
+ rc = createListPage(page as ListPageMetaData);
+ break;
+ case PageType.edit:
+ case PageType.create:
+ case PageType.delete:
+ case PageType.custom:
+ rc = createRecordCustomized(page);
+ break;
}
return rc;
}
+ /// Returns a Dart class definition of the [page] that should not be modified.
+ String createListPage(ListPageMetaData page) {
+ var rc = replaceVariables(templateListCustom, page)
+ .replaceFirst('#DEF_CONTROLLERS', buildDefinitionControllers(page))
+ .replaceFirst('#INIT_COMBOS', buildInitializeComboBoxes(page))
+ .replaceFirst('#FORM_ITEMS', buildFormItems(page, withController: true))
+ .replaceFirst('#PARAM_DEF', buildParamDefinitions(page))
+ .replaceFirst('#ROW_COLUMNS', page.tableColumns)
+ .replaceFirst('#TABLE_HEADER', buildTableHeader(page))
+ .replaceFirst('#DISPOSE_CONTROLLER', buildDisposeControllers(page))
+ .replaceFirst('#DEF_FIELDS', buildDefinitionFields(page))
+ .replaceFirst('#EDIT1', 'Edit')
+ .replaceFirst('#EDIT2', 'edit');
+ return rc;
+ }
+
/// Returns a Dart class definition of the [page] that should not be modified.
String createPage(PageMetaData page) {
var rc = replaceVariables(templatePage, page);
- if (page.pageType == PageType.edit || page.pageType == PageType.delete){
- rc = rc.replaceAll('DEF_PRIMARY', ' final int primaryKey;\n')
+ if (page.pageType == PageType.edit || page.pageType == PageType.delete) {
+ rc = rc
+ .replaceAll('DEF_PRIMARY', ' final int primaryKey;\n')
.replaceAll('THIS_PRIMARY', 'this.primaryKey')
.replaceAll('PARAM_PRIMARY', 'int primaryKey')
.replaceAll('VAL_PRIMARY', 'primaryKey');
} else {
- rc = rc.replaceAll('DEF_PRIMARY', '')
+ rc = rc
+ .replaceAll('DEF_PRIMARY', '')
.replaceAll('THIS_PRIMARY', '')
.replaceAll('PARAM_PRIMARY', '')
.replaceAll('VAL_PRIMARY', '');
return rc;
}
+ /// Creates the customized part of a page displaying one record.
+ ///
+ /// [page] contains the meta data information about the page.
+ ///
+ /// Returns the file content.
+ String createRecordCustomized(PageMetaData page) {
+ var hasPrimary = false;
+ page.pageType == PageType.edit || page.pageType == PageType.delete;
+ var action1 = 'store';
+ var action2 = 'verifyAndStore';
+ var storageDone = '';
+ var buttonText = 'Save';
+ String sqlType = '';
+ page.pageType == PageType.edit
+ ? 'update'
+ : (page.pageType == PageType.delete ? 'delete' : 'insert');
+
+ switch (page.pageType) {
+ case PageType.create:
+ sqlType = 'insert';
+ storageDone = templateStorageDoneCreate.replaceFirst(
+ '#MODULE', page.module.moduleName);
+ break;
+ case PageType.edit:
+ sqlType = 'update';
+ storageDone = templateStorageDoneEdit;
+ hasPrimary = true;
+ storageDone = '';
+ break;
+ case PageType.delete:
+ sqlType = 'delete';
+ buttonText = 'Delete';
+ action1 = 'delete';
+ action2 = 'verifyAndDelete';
+ storageDone = templateStorageDoneDelete.replaceFirst(
+ '#MODULE', page.module.moduleName);
+ hasPrimary = true;
+ break;
+ case PageType.custom:
+ break;
+ case PageType.list:
+ break;
+ }
+ var rc = replaceVariables(templateRecordCustom, page)
+ .replaceFirst('#DEF_CONTROLLER', buildDefinitionControllers(page))
+ .replaceFirst('#INIT_COMBO', buildInitializeComboBoxes(page))
+ .replaceFirst('#FORM_ITEMS', buildFormItems(page, withController: true))
+ .replaceFirst('#LOAD_RECORD', buildLoadRecord(page))
+ .replaceFirst('#PAGE_LABEL', page.label)
+ .replaceFirst('#SQL_TYPE', sqlType)
+ .replaceAll('#ACTION1', action1)
+ .replaceAll('#ACTION2', action2)
+ .replaceFirst('#BUTTON', buttonText)
+ .replaceFirst('#STORAGE_DONE', storageDone)
+ .replaceFirst('#DEF_PARAMS', buildParamDefinitions(page))
+ .replaceFirst('#DISP_CONTROLLER', buildDisposeControllers(page))
+ .replaceFirst('#DEF_FIELD', buildDefinitionFields(page))
+ .replaceFirst('#ASSIGN_CONTROLLER', buildAssignControllers(page))
+ .replaceFirst(
+ '#DEF_PRIMARY', hasPrimary ? ' final int primaryKey;\n' : '')
+ .replaceFirst('#THIS_PRIMARY', hasPrimary ? 'this.primaryKey' : '')
+ .replaceFirst('#TO_MAP', buildToMap(page))
+ .replaceFirst('#FROM_MAP', buildFromMap(page));
+ return rc;
+ }
+
+ String replaceVariables(String template, PageMetaData page) {
+ final camelModules = toCamelCase(page.module.moduleName);
+ final camelModule = toCamelCase(page.module.moduleNameSingular);
+ final camelPageName = toCamelCase(page.name);
+ final rc = template
+ .replaceAll('Users', camelModules)
+ .replaceAll('User', camelModule)
+ .replaceAll('Edit', camelPageName)
+ .replaceAll('edit', page.name)
+ .replaceAll('users', page.module.moduleName.toLowerCase())
+ .replaceAll('user', page.module.moduleNameSingular.toLowerCase());
+ return rc;
+ }
+
/// Creates the file page_manager.dart and (if it does not exist) the file
/// page_manager_custom.dart.
- void updatePageManager(){
+ void updatePageManager() {
final modules = moduleNames();
final imports = StringBuffer();
final cases = StringBuffer();
- for (var name in modules){
+ for (var name in modules) {
ModuleMetaData? module = moduleByName(name);
for (var page in module!.pageList) {
imports.writeln("import '${name.toLowerCase()}/${page.name}_"
- "${module.moduleNameSingular.toLowerCase()}_page.dart';");
+ "${module.moduleNameSingular.toLowerCase()}_page.dart';");
var case1 = replaceVariables(templateCase, page);
- if (page.pageType == PageType.edit || page.pageType == PageType.delete){
+ if (page.pageType == PageType.edit ||
+ page.pageType == PageType.delete) {
case1 = case1.replaceFirst('ARG1', 'arg1');
} else {
case1 = case1.replaceFirst('ARG1', '');
cases.write(case1);
}
}
- final content = templatePageManager.replaceFirst('#IMPORTS#', imports.toString())
- .replaceFirst('#CASES#', cases.toString());
+ final content = templatePageManager
+ .replaceFirst('#IMPORTS#', imports.toString())
+ .replaceFirst('#CASES#', cases.toString());
writeFile('../lib/page/page_manager.dart', content);
final full = '../lib/page/page_manager_custom.dart';
- if (File(full).existsSync()){
+ if (File(full).existsSync()) {
logger.log('$full already exists. We do not override');
} else {
writeFile(full, templatePageManagerCustom);
}
}
+
/// Generates all modules defined in the meta data.
void updatePages(Generator generator) {
if (!Directory('bin').existsSync() ||
if (module == null) {
logger.error('+++ unknown module: $name');
} else {
+ module.onInitialized();
for (var page in module.pageList) {
String filename = page.name +
'_' +