From: Hamatoma Date: Mon, 16 Nov 2020 15:13:40 +0000 (+0100) Subject: daily work X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=56b031e5b090a8bdf664d7e478c0616347af7fca;p=flutter_bones.git daily work --- diff --git a/data/ddl/menu.sql b/data/ddl/menu.sql index 44cc7f3..cf8a24e 100644 --- a/data/ddl/menu.sql +++ b/data/ddl/menu.sql @@ -1,8 +1,8 @@ DROP TABLE IF EXISTS menu; CREATE TABLE menu ( menu_id INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, - menu_name VARCHAR(64) UNIQUE NOT NULL, - menu_icon INT(10) UNSIGNED, + menu_role INT(10) UNSIGNED, + menu_starter INT(10) UNSIGNED, menu_createdat TIMESTAMP NULL, menu_createdby VARCHAR(16), menu_changedat TIMESTAMP NULL, diff --git a/data/ddl/starter.sql b/data/ddl/starter.sql new file mode 100644 index 0000000..5c7b4b4 --- /dev/null +++ b/data/ddl/starter.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS starter; +CREATE TABLE starter ( + starter_id INT(10) UNSIGNED NOT NULL UNIQUE AUTO_INCREMENT, + starter_name VARCHAR(64) UNIQUE NOT NULL, + starter_icon INT(10) UNSIGNED, + starter_createdat TIMESTAMP NULL, + starter_createdby VARCHAR(16), + starter_changedat TIMESTAMP NULL, + starter_changedby VARCHAR(16), + PRIMARY KEY(starter_id) +); diff --git a/data/rest/configuration.yaml b/data/rest/configuration.yaml index 6fd0ce3..9c40415 100644 --- a/data/rest/configuration.yaml +++ b/data/rest/configuration.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for configuration: -created: 2020.11.10 23:47:43 +created: 2020.11.16 18:30:01 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: diff --git a/data/rest/menu.yaml b/data/rest/menu.yaml index 54966a8..6b4a821 100644 --- a/data/rest/menu.yaml +++ b/data/rest/menu.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for menu: -created: 2020.11.10 23:47:43 +created: 2020.11.16 18:30:01 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: @@ -8,12 +8,12 @@ modules: sqlInfos: - name: insert type: insert - sql: "INSERT INTO menu(menu_name,menu_icon,menu_createdat,menu_createdby) - VALUES(:menu_name,:menu_icon,NOW(),:menu_createdby);" + sql: "INSERT INTO menu(menu_role,menu_starter,menu_createdat,menu_createdby) + VALUES(:menu_role,:menu_starter,NOW(),:menu_createdby);" - name: update type: update sql: "UPDATE menu SET - menu_name=:menu_name,menu_icon=:menu_icon,menu_changedat=NOW(),menu_changedby=:menu_changedby + menu_role=:menu_role,menu_starter=:menu_starter,menu_changedat=NOW(),menu_changedby=:menu_changedby WHERE menu_id=:menu_id;" - name: delete type: delete @@ -21,11 +21,9 @@ modules: - name: record type: record sql: "SELECT * from menu WHERE menu_id=:menu_id;" - - name: by_menu_name - type: record - sql: "SELECT * from menu WHERE menu_name=:menu_name&&menu_id!=:excluded;" - name: list type: list - sql: "SELECT t0.*,t1.configuration_property as menu_icon from menu t0 - left join configuration t1 on t1.configuration_id=t0.menu_icon - WHERE menu_name like :menu_name;" + sql: "SELECT t0.*,t1.role_name as menu_role,t2.starter_name as menu_starter from menu t0 + left join role t1 on t1.role_id=t0.menu_role + left join starter t2 on t2.starter_id=t0.menu_starter + WHERE menu_role like :menu_role;" diff --git a/data/rest/role.yaml b/data/rest/role.yaml index f59f8a2..23da879 100644 --- a/data/rest/role.yaml +++ b/data/rest/role.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for role: -created: 2020.11.10 23:47:43 +created: 2020.11.16 18:30:01 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: diff --git a/data/rest/starter.yaml b/data/rest/starter.yaml new file mode 100644 index 0000000..4eedbd2 --- /dev/null +++ b/data/rest/starter.yaml @@ -0,0 +1,31 @@ +--- +# configuration of the bones backend for starter: +created: 2020.11.16 18:30:01 +author: flutter_bones.module_model.exportSqlBackend() +version: 1.0.0 +modules: + - module: starter + sqlInfos: + - name: insert + type: insert + sql: "INSERT INTO starter(starter_name,starter_icon,starter_createdat,starter_createdby) + VALUES(:starter_name,:starter_icon,NOW(),:starter_createdby);" + - name: update + type: update + sql: "UPDATE starter SET + starter_name=:starter_name,starter_icon=:starter_icon,starter_changedat=NOW(),starter_changedby=:starter_changedby + WHERE starter_id=:starter_id;" + - name: delete + type: delete + sql: "DELETE from starter WHERE starter_id=:starter_id;" + - name: record + type: record + sql: "SELECT * from starter WHERE starter_id=:starter_id;" + - name: by_starter_name + type: record + sql: "SELECT * from starter WHERE starter_name=:starter_name&&starter_id!=:excluded;" + - name: list + type: list + sql: "SELECT t0.*,t1.configuration_value as starter_icon from starter t0 + left join configuration t1 on t1.configuration_id=t0.starter_icon + WHERE starter_name like :starter_name;" diff --git a/data/rest/user.yaml b/data/rest/user.yaml index f99d0ac..fe0759e 100644 --- a/data/rest/user.yaml +++ b/data/rest/user.yaml @@ -1,6 +1,6 @@ --- # configuration of the bones backend for user: -created: 2020.11.10 23:47:43 +created: 2020.11.16 18:30:01 author: flutter_bones.module_model.exportSqlBackend() version: 1.0.0 modules: diff --git a/lib/app.dart b/lib/app.dart index 452ebfe..5e4670d 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -13,6 +13,8 @@ import 'src/page/role/role_list_page.dart'; import 'src/page/user/user_create_page.dart'; import 'src/page/user/user_list_page.dart'; import 'src/page/user/user_login_page.dart'; +import 'src/page/starter/starter_list_page.dart'; +import 'src/page/starter/starter_create_page.dart'; import 'src/private/bsettings.dart'; class BoneApp extends StatefulWidget { @@ -35,12 +37,13 @@ class BoneAppState extends State { @override Widget build(BuildContext context) { return MaterialApp( - title: 'Test Standardseiten', + debugShowCheckedModeBanner: true, + title: 'Flutter Bones Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), - initialRoute: '/menu/list', + initialRoute: '/role/list', //initialRoute: '/async', onGenerateRoute: _getRoute, ); @@ -81,6 +84,12 @@ Route _getRoute(RouteSettings settings) { case '/menu/create': page = MenuCreatePage(BSettings.lastInstance.pageData); break; + case '/starter/list': + page = StarterListPage(BSettings.lastInstance.pageData); + break; + case '/starter/create': + page = StarterCreatePage(BSettings.lastInstance.pageData); + break; case '/user/login': default: page = UserLoginPage(BSettings.lastInstance.pageData); diff --git a/lib/flutter_bones.dart b/lib/flutter_bones.dart index 18f3e84..ad28944 100644 --- a/lib/flutter_bones.dart +++ b/lib/flutter_bones.dart @@ -20,14 +20,12 @@ export 'src/model/section_model.dart'; export 'src/model/standard/configuration_model.dart'; export 'src/model/standard/menu_model.dart'; export 'src/model/standard/role_model.dart'; -export 'src/model/standard/standard_modules.dart'; export 'src/model/standard/user_model.dart'; export 'src/model/text_field_model.dart'; export 'src/model/text_model.dart'; export 'src/model/widget_model.dart'; export 'src/page/application_data.dart'; export 'src/page/configuration/configuration_create_page.dart'; -export 'src/page/login_page.dart.01'; export 'src/page/role/role_create_page.dart'; export 'src/page/user/user_create_page.dart'; export 'src/page/user_page.dart'; diff --git a/lib/src/helper/string_helper.dart b/lib/src/helper/string_helper.dart index ea9e5ee..b0ced96 100644 --- a/lib/src/helper/string_helper.dart +++ b/lib/src/helper/string_helper.dart @@ -150,6 +150,40 @@ class StringHelper { return rc; } + /// Returns null or the index of the first match of a [string] + /// or a regular expression defined by [regExp] or a string [pattern]. + /// Note: exactly one of [string], [regExp] or [pattern] must be not null. + static int listIndexOf(List list, + {String string, RegExp regExp, String pattern}) { + int rc; + int ix = -1; + if (list != null) { + if (string != null) { + for (var line in list) { + ix++; + if (line.contains(string)) { + rc = ix; + break; + } + } + } else { + if (pattern != null) { + regExp = RegExp(pattern); + } + if (regExp != null) { + for (var line in list) { + ix++; + if (regExp.firstMatch(line) != null) { + rc = ix; + break; + } + } + } + } + } + return rc; + } + /// Splits a argument list into an [option] list and a true arguments list. /// [args]: the argument list to split. /// [options]: OUT: the options list @@ -165,4 +199,10 @@ class StringHelper { } return rc; } + + /// Converts a [string] to camelCase with an uppercase first character. + static String capitalize(String string) { + final rc = string[0].toUpperCase() + string.substring(1); + return rc; + } } diff --git a/lib/src/model/all_db_fields_model.dart b/lib/src/model/all_db_fields_model.dart index 65b591b..9e8506a 100644 --- a/lib/src/model/all_db_fields_model.dart +++ b/lib/src/model/all_db_fields_model.dart @@ -40,9 +40,9 @@ class AllDbFieldsModel extends WidgetModel { if (col.hasOption('doStore') || (!col.hasOption('hidden') && (!isCreatePage || !col.hasOption('primary')))) { - final field = DbReferenceModel.fromColumn(section, page, col, logger); - page.addField(field); - page.widgets.add(field); + final model = DbReferenceModel.fromColumn(section, page, col, logger); + page.addModel(model); + section.children.add(model); } }); } diff --git a/lib/src/model/model_helper.dart b/lib/src/model/model_helper.dart new file mode 100644 index 0000000..4ccd334 --- /dev/null +++ b/lib/src/model/model_helper.dart @@ -0,0 +1,40 @@ +import 'package:dart_bones/dart_bones.dart'; +import 'module_model.dart'; +import 'standard/role_model.dart'; +import 'standard/user_model.dart'; +import 'standard/menu_model.dart'; +import 'standard/starter_model.dart'; +import 'standard/configuration_model.dart'; + +class ModelHelper { + /// Returns an instance of a module given by [name]. + ModuleModel moduleByName(String name, BaseLogger logger) { + var rc; + switch (name) { + case 'role': + rc = RoleModel(logger); + break; + case 'user': + rc = UserModel(logger); + break; + case 'configuration': + rc = ConfigurationModel(logger); + break; + case 'menu': + rc = MenuModel(logger); + break; + case 'starter': + rc = StarterModel(logger); + break; + default: + logger.error('unknown standard module: $name'); + break; + } + return rc; + } + + /// Returns the names of the modules. + List moduleNames() => + ['configuration', 'menu', 'role', 'starter', 'user']; + +} diff --git a/lib/src/model/module_model.dart b/lib/src/model/module_model.dart index 9ecc131..ac8d7b8 100644 --- a/lib/src/model/module_model.dart +++ b/lib/src/model/module_model.dart @@ -119,32 +119,33 @@ class ModuleModel extends ModelBase { type: list sql: "SELECT $select from ${table.name} t0\n$buffer2'''); // @ToDo: joins - final fields = page.fields + final models = page.models.values .where((item) => item is FieldModel && item.filterType != null); - if (fields.isEmpty) { + if (models.isEmpty) { buffer.write(' WHERE 1;"'); } else { buffer.write(' WHERE '); var first = true; - for (var field in fields) { + for (var item in models) { + FieldModel model = item as FieldModel; if (!first) { buffer.write(' AND '); } - switch (field.filterType) { + switch (model.filterType) { case FilterType.dateFrom: case FilterType.dateTimeFrom: - buffer.write('${field.name}>=:${field.name}'); + buffer.write('${model.name}>=:${model.name}'); break; case FilterType.dateTil: case FilterType.dateTimeTil: - buffer.write('${field.name}<=:${field.name}'); + buffer.write('${model.name}<=:${model.name}'); break; case FilterType.equals: buffer.write( - '(:${field.name} IS NULL OR ${field.name}=:${field.name})'); + '(:${model.name} IS NULL OR ${model.name}=:${model.name})'); break; case FilterType.pattern: - buffer.write('${field.name} like :${field.name}'); + buffer.write('${model.name} like :${model.name}'); break; } first = false; diff --git a/lib/src/model/page_model.dart b/lib/src/model/page_model.dart index 536a843..01bb896 100644 --- a/lib/src/model/page_model.dart +++ b/lib/src/model/page_model.dart @@ -16,10 +16,12 @@ class PageModel extends ModelBase { final ModuleModel module; final List sections = []; PageModelType pageModelType; - final fields = []; - final buttons = []; - final widgets = []; + final fieldsDeprecated = []; + final buttonsDeprecated = []; + final widgetsDeprecated = []; + final models = {}; String sql; + String title; List tableTitles; List tableColumns; NameBuilder nameBuilder; @@ -29,34 +31,22 @@ class PageModel extends ModelBase { nameBuilder = NameBuilder(logger); } - /// Adds a [button] to the [this.buttons]. + /// Adds a [model] to the [this.fields]. /// If already defined and error is logged. - void addButton(ButtonModel button) { - if (buttonByName(button.name, required: false) != null) { - logger.error('button ${button.fullName()} already defined: ' + - buttonByName(button.name, required: false).fullName()); - } else { - buttons.add(button); - } - } - - /// Adds a [field] to the [this.fields]. - /// If already defined and error is logged. - void addField(FieldModel field) { - final name = field.name; - if (hasField(name)) { - logger.error('field ${field.fullName()} already defined: ' + + void addModel(WidgetModel model) { + final name = model.name; + if (models.containsKey(name)) { + logger.error('model ${model.fullName()} already defined: ' + fieldByName(name).fullName()); } else { - fields.add(field); + models[model.name] = model; } } /// Returns a button named [name] or null if not found. ButtonModel buttonByName(String name, {bool required = true}) { - final rc = - buttons.firstWhere((item) => item.name == name, orElse: () => null); - if (rc == null && required) { + final rc = models.containsKey(name) ? models[name] : null; + if ((rc == null || rc.modelType != ModelTypeBones.button) && required) { logger.error('missing button $name in page ${fullName()}'); } return rc; @@ -74,9 +64,10 @@ class PageModel extends ModelBase { /// Returns a field by [name] or null on error. FieldModel fieldByName(String name, {bool required = true}) { - final rc = fields.firstWhere((element) => element.name == name, - orElse: () => null); - if (required && rc == null) { + final rc = !models.containsKey(name) + ? null + : (models[name] is FieldModel ? models[name] : null); + if ((rc == null || !(rc is FieldModel)) && required) { logger.error('missing field $name in page ${fullName()}'); } return rc; @@ -90,8 +81,8 @@ class PageModel extends ModelBase { /// If [filter] is none all widgets will be returned. List getWidgets(FilterWidget filter) { final rc = filter == null - ? widgets - : widgets.fold([], (prevValue, item) { + ? sections[0].children + : sections[0].children.fold([], (prevValue, item) { if (filter(item)) { prevValue.add(item); } @@ -102,9 +93,7 @@ class PageModel extends ModelBase { /// Tests whether the field with [name] is part of the page. bool hasField(String name) { - final first = fields.firstWhere((element) => element.name == name, - orElse: () => null); - final rc = first != null; + final rc = models.containsKey(name) && models[name] is FieldModel; return rc; } @@ -116,11 +105,12 @@ class PageModel extends ModelBase { } checkSuperfluousAttributes( map, - 'options page pageType sections sql tableColumns tableTitles' + 'options page pageType sections sql tableColumns tableTitles title' .split(' ')); pageModelType = parseEnum( 'pageType', map, PageModelType.values, required: true); + title = parseString('title', map, required: true); if (!map.containsKey('sections')) { logger.error('missing sections in page ${fullName()}'); } else { @@ -149,23 +139,29 @@ class PageModel extends ModelBase { } if (!options.contains('noAutoButton')) { - final section = null; + final section = sections[0]; switch (pageModelType) { case PageModelType.list: if (buttonByName('search', required: false) == null) { - addButton(ButtonModel.direct(section, this, 'search', 'Suchen', - ButtonModelType.search, [], logger)); + final model = ButtonModel.direct(section, this, 'search', 'Suchen', + ButtonModelType.search, [], logger); + addModel(model); + sections[0].buttonBar.insert(0, model); } break; case PageModelType.create: case PageModelType.change: if (buttonByName('cancel', required: false) == null) { - addButton(ButtonModel.direct(section, this, 'cancel', 'Abbruch', - ButtonModelType.cancel, [], logger)); + final model = ButtonModel.direct(section, this, 'cancel', 'Abbruch', + ButtonModelType.cancel, [], logger); + addModel(model); + sections[0].buttonBar.insert(0, model); } if (buttonByName('store', required: false) == null) { - addButton(ButtonModel.direct(section, this, 'store', 'Speichern', - ButtonModelType.store, [], logger)); + final model = ButtonModel.direct(section, this, 'store', + 'Speichern', ButtonModelType.store, [], logger); + addModel(model); + sections[0].buttonBar.insert(0, model); } break; default: diff --git a/lib/src/model/section_model.dart b/lib/src/model/section_model.dart index fff2419..e44c4c7 100644 --- a/lib/src/model/section_model.dart +++ b/lib/src/model/section_model.dart @@ -17,10 +17,11 @@ class SectionModel extends WidgetModel { static final regExprOptions = RegExp(r'^(unknown)$'); SectionModelType sectionModelType; final children = []; - final buttons = []; - final int no; + final buttonBar = []; + final int sectionNo; - SectionModel(this.no, PageModel page, SectionModel section, BaseLogger logger) + SectionModel( + this.sectionNo, PageModel page, SectionModel section, BaseLogger logger) : super(section, page, ModelTypeBones.section, null, logger); /// Dumps the internal structure into a [stringBuffer] @@ -39,6 +40,58 @@ class SectionModel extends WidgetModel { String fullName() => section == null ? '${page.name}.$name' : '${section.name}.$name'; + WidgetModel buildModel(child, String parentName, int no) { + WidgetModel model; + if (!ModelBase.isMap(child)) { + logger.error('child $no of "children" is not a map in ${fullName()}: ' + '${StringUtils.limitString(child.toString(), 80)}'); + } else { + if (!child.containsKey('modelType')) { + logger.error( + 'child $no of "$parentName" does not have "modelType" in ${fullName()}: ' + '${StringUtils.limitString(child.toString(), 80)}'); + } else { + final modelType = StringUtils.stringToEnum( + child['modelType'].toString(), ModelTypeBones.values); + switch (modelType) { + case ModelTypeBones.allDbFields: + model = AllDbFieldsModel(this, page, logger); + break; + case ModelTypeBones.checkbox: + model = CheckboxModel(this, page, logger); + break; + case ModelTypeBones.combobox: + model = ComboboxModel(this, page, logger); + break; + case ModelTypeBones.textField: + model = TextFieldModel(this, page, logger); + break; + case ModelTypeBones.button: + model = ButtonModel(this, page, logger); + break; + case ModelTypeBones.text: + model = TextModel(this, page, logger); + break; + case ModelTypeBones.emptyLine: + model = EmptyLineModel(this, page, logger); + break; + case ModelTypeBones.dbReference: + model = DbReferenceModel(this, page, logger); + break; + default: + //@ToDo: nested section + logger.error( + 'Section: unknown "modelType" ${child["modelType"]} in ${fullName()}'); + break; + } + if (model != null){ + model.parse(child); + } + } + } + return model; + } + /// Parses the [map]and stores the data in the instance. void parse(Map map) { super.parseBase(map, nameLabel: 'section'); @@ -47,8 +100,10 @@ class SectionModel extends WidgetModel { } sectionModelType = parseEnum( 'sectionType', map, SectionModelType.values); - checkSuperfluousAttributes(map, - 'children fields modelType section options sectionType'.split(' ')); + checkSuperfluousAttributes( + map, + 'buttons children fields modelType section options sectionType' + .split(' ')); checkOptionsByRegExpr(regExprOptions); if (!map.containsKey('children')) { @@ -62,73 +117,32 @@ class SectionModel extends WidgetModel { int no = 0; for (var child in childrenList) { no++; - if (!ModelBase.isMap(child)) { - logger - .error('child $no of "children" is not a map in ${fullName()}: ' - '${StringUtils.limitString(child.toString(), 80)}'); - } else { - if (!child.containsKey('modelType')) { - logger.error( - 'child $no of "children" does not have "modelType" in ${fullName()}: ' - '${StringUtils.limitString(child.toString(), 80)}'); - } else { - final modelType = StringUtils.stringToEnum( - child['modelType'].toString(), ModelTypeBones.values); - WidgetModel widget; - switch (modelType) { - case ModelTypeBones.allDbFields: - widget = AllDbFieldsModel(this, page, logger); - break; - case ModelTypeBones.checkbox: - widget = CheckboxModel(this, page, logger); - break; - case ModelTypeBones.combobox: - widget = ComboboxModel(this, page, logger); - break; - case ModelTypeBones.textField: - widget = TextFieldModel(this, page, logger); - break; - case ModelTypeBones.button: - widget = ButtonModel(this, page, logger); - break; - case ModelTypeBones.text: - widget = TextModel(this, page, logger); - break; - case ModelTypeBones.emptyLine: - widget = EmptyLineModel(this, page, logger); - break; - case ModelTypeBones.dbReference: - widget = DbReferenceModel(this, page, logger); - break; - default: - //@ToDo: nested section - logger.error( - 'Section: unknown "modelType" ${child["modelType"]} in ${fullName()}'); - break; - } - if (widget != null) { - children.add(widget); - widget.parse(child); - page.widgets.add(widget); - switch (widget.modelType) { - case ModelTypeBones.button: - page.addButton(widget); - break; - case ModelTypeBones.textField: - case ModelTypeBones.combobox: - case ModelTypeBones.checkbox: - case ModelTypeBones.dbReference: - page.addField(widget); - break; - default: - break; - } - } - } + WidgetModel widget = buildModel(child, 'children', no); + if (widget != null) { + children.add(widget); + page.addModel(widget); + } + } + } + //parseSections(page, this, childrenList, logger); + } + if (map.containsKey('buttonBar')) { + final childrenList = map['buttonBar']; + if (!ModelBase.isList(childrenList)) { + logger.error('"children" is not a list in ${fullName()}: ' + '${StringUtils.limitString(childrenList.toString(), 80)}'); + } else { + int no = 0; + for (var child in childrenList) { + no++; + WidgetModel model = buildModel(child, 'buttonBar', no); + if (model != null) { + buttonBar.add(model); + page.addModel(model); } } - //parseSections(page, this, childrenList, logger); } + //parseSections(page, this, childrenList, logger); } } diff --git a/lib/src/model/standard/configuration_model.dart b/lib/src/model/standard/configuration_model.dart index f9b47df..5377270 100644 --- a/lib/src/model/standard/configuration_model.dart +++ b/lib/src/model/standard/configuration_model.dart @@ -6,8 +6,8 @@ import '../module_model.dart'; class ConfigurationModel extends ModuleModel { static final yamlMap = { // - "module": "configuration", - "tables": [ + 'module': 'configuration', + 'tables': [ { // configuration_id | configuration_scope | configuration_property | configuration_order | configuration_type // | configuration_value | configuration_description @@ -66,55 +66,58 @@ class ConfigurationModel extends ModuleModel { ], 'pages': [ { - "page": "create", - "pageType": "create", - "sections": [ + 'page': 'create', + 'title': 'Konfiguration hinzufügen', + 'pageType': 'create', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "allDbFields", + 'modelType': 'allDbFields', } ] } ] }, { - "page": "change", - "pageType": "change", - "sections": [ + 'page': 'change', + 'title': 'Konfiguration ändern', + 'pageType': 'change', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "allDbFields", + 'modelType': 'allDbFields', } ] } ] }, { - "page": "list", - "pageType": "list", - "tableColumns": - "configuration_id configuration_scope configuration_property configuration_order configuration_value configuration_type", - "tableTitles": ";Id;Bereich;Eigenschaft;Reihe;Wert;Typ", - "sections": [ + 'page': 'list', + 'title': 'Konfiguration', + 'pageType': 'list', + 'tableColumns': + 'configuration_id configuration_scope configuration_property configuration_order configuration_value configuration_type', + 'tableTitles': ';Id;Bereich;Eigenschaft;Reihe;Wert;Typ', + 'sections': [ { - "sectionType": "filterPanel", - "children": [ + 'sectionType': 'filterPanel', + 'children': [ { - "name": "configuration_scope", - "label": "Bereich", - 'modelType': "textField", - "filterType": "pattern", - //"options": 'undef', + 'name': 'configuration_scope', + 'label': 'Bereich', + 'modelType': 'textField', + 'filterType': 'pattern', + //'options': 'undef', }, { - "name": "configuration_property", - "label": "Eigenschaft", - 'modelType': "textField", - "filterType": "pattern", + 'name': 'configuration_property', + 'label': 'Eigenschaft', + 'modelType': 'textField', + 'filterType': 'pattern', }, ] } diff --git a/lib/src/model/standard/menu_model.dart b/lib/src/model/standard/menu_model.dart index f4bf5ec..e3c7687 100644 --- a/lib/src/model/standard/menu_model.dart +++ b/lib/src/model/standard/menu_model.dart @@ -16,20 +16,20 @@ class MenuModel extends ModuleModel { 'options': 'primary', }, { - 'column': 'menu_name', - 'dataType': 'string', - 'label': 'Name', - 'size': 64, - 'options': 'unique notnull', + 'column': 'menu_role', + 'dataType': 'reference', + 'label': 'Rolle', + 'foreignKey': 'role.role_id role_name', + 'listType': 'dbColumn', + 'listOption': 'all.role.list;role_name role_id;', }, { - 'column': 'menu_icon', + 'column': 'menu_starter', 'dataType': 'reference', - 'label': 'Bild', - 'foreignKey': 'configuration.configuration_id configuration_value', - 'listType': 'configuration', - 'listOption': - 'std.scope.icons;configuration_value configuration_id;', + 'label': 'Programmpunkt', + 'foreignKey': 'starter.starter_id starter_name', + 'listType': 'dbColumn', + 'listOption': 'all.starter.list;starter_name starter_id;', }, ] }, @@ -37,6 +37,7 @@ class MenuModel extends ModuleModel { 'pages': [ { 'page': 'create', + 'title': 'Startmenü hinzufügen', 'pageType': 'create', 'sections': [ { @@ -51,6 +52,7 @@ class MenuModel extends ModuleModel { }, { 'page': 'change', + 'title': 'Startmenü ändern', 'pageType': 'change', 'sections': [ { @@ -65,9 +67,10 @@ class MenuModel extends ModuleModel { }, { 'page': 'list', + 'title': 'Startmenü', 'pageType': 'list', - 'tableColumns': 'menu_id menu_name menu_icon', - 'tableTitles': ';Id;Name;Bild', + 'tableColumns': 'menu_id menu_role menu_order menu_name', + 'tableTitles': ';Id;Rolle;Reihe;Programmpunkt', 'sections': [ { 'sectionType': 'filterPanel', @@ -75,10 +78,10 @@ class MenuModel extends ModuleModel { { 'modelType': 'dbReference', 'filterType': 'pattern', - 'name': 'menu_name', - 'column': 'menu_name', + 'name': 'menu_role', + 'column': 'menu_role', 'toolTip': - "Filter bezüglich des Namens der anzuzeigenden Einträge: Joker '*' (beliebiger String) ist erlaubt." + 'Filter bezüglich der Rolle der anzuzeigenden Einträge.' }, ] } diff --git a/lib/src/model/standard/role_model.dart b/lib/src/model/standard/role_model.dart index 937f303..6cb2a39 100644 --- a/lib/src/model/standard/role_model.dart +++ b/lib/src/model/standard/role_model.dart @@ -3,9 +3,11 @@ import 'package:dart_bones/dart_bones.dart'; import '../module_model.dart'; class RoleModel extends ModuleModel { + RoleModel(BaseLogger logger) : super(yamlMap, logger); + static final yamlMap = { - "module": "role", - "tables": [ + 'module': 'role', + 'tables': [ { 'table': 'role', 'columns': [ @@ -38,59 +40,69 @@ class RoleModel extends ModuleModel { ], 'pages': [ { - "page": "create", - "pageType": "create", - "sections": [ + 'page': 'create', + 'title': 'Rolle hinzufügen', + 'pageType': 'create', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "allDbFields", + 'modelType': 'allDbFields', } ] } ] }, { - "page": "change", - "pageType": "change", - "sections": [ + 'page': 'change', + 'title': 'Rolle ändern', + 'pageType': 'change', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "allDbFields", + 'modelType': 'allDbFields', } ] } ] }, { - "page": "list", - "pageType": "list", - "tableColumns": "role_id role_name role_priority", - "tableTitles": ";Id;Rolle;Priorität", - "sections": [ + 'page': 'list', + 'title': 'Rollen', + 'pageType': 'list', + 'tableColumns': 'role_id role_name role_priority', + 'tableTitles': ';Id;Rolle;Priorität', + 'sections': [ { - "sectionType": "filterPanel", - "children": [ + 'sectionType': 'filterPanel', + 'children': [ { - 'modelType': "textField", - "filterType": "pattern", - "name": "role_name", - "label": "Name", - "toolTip": - "Suchmuster des Rollennamens: Joker: '*' (beliebiger Text), z.B. '*min*'" - } - ] + 'modelType': 'textField', + 'filterType': 'pattern', + 'name': 'role_name', + 'label': 'Name', + 'toolTip': + 'Suchmuster des Rollennamens: Joker: "*" (beliebiger Text), z.B. "*min*"' + }, + ], + 'buttonBar': [ + { + 'modelType': 'button', + 'buttonType': 'custom', + 'name': 'new', + 'label': 'Neue Rolle', + 'toolTip': 'Erzeugen einer neuen Rolle' + }, + ], } - ] - }, - ], + ], + } + ] }; - RoleModel(BaseLogger logger) : super(yamlMap, logger); - /// Returns the name including the names of the parent @override String fullName() => name; diff --git a/lib/src/model/standard/standard_modules.dart b/lib/src/model/standard/standard_modules.dart deleted file mode 100644 index efd1217..0000000 --- a/lib/src/model/standard/standard_modules.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:dart_bones/dart_bones.dart'; -import '../module_model.dart'; -import 'role_model.dart'; -import 'user_model.dart'; -import 'menu_model.dart'; -import 'configuration_model.dart'; - -/// Returns an instance of a standard module given by [name]. -ModuleModel standardModule(String name, BaseLogger logger) { - var rc; - switch (name) { - case 'role': - rc = RoleModel(logger); - break; - case 'user': - rc = UserModel(logger); - break; - case 'configuration': - rc = ConfigurationModel(logger); - break; - case 'menu': - rc = MenuModel(logger); - break; - default: - logger.error('unknown standard module: $name'); - break; - } - return rc; -} - -/// Returns the names of the standard modules. -List standardModules() => ['configuration', 'menu', 'role', 'user']; diff --git a/lib/src/model/standard/starter_model.dart b/lib/src/model/standard/starter_model.dart new file mode 100644 index 0000000..eb090c3 --- /dev/null +++ b/lib/src/model/standard/starter_model.dart @@ -0,0 +1,101 @@ +import 'package:dart_bones/dart_bones.dart'; + +import '../module_model.dart'; + +class StarterModel extends ModuleModel { + static final mapStarter = { + 'module': 'starter', + 'tables': [ + { + 'table': 'starter', + 'columns': [ + { + 'column': 'starter_id', + 'dataType': 'int', + 'label': 'Id', + 'options': 'primary', + }, + { + 'column': 'starter_name', + 'dataType': 'string', + 'label': 'Name', + 'size': 64, + 'options': 'unique notnull', + }, + { + 'column': 'starter_icon', + 'dataType': 'reference', + 'label': 'Bild', + 'foreignKey': 'configuration.configuration_id configuration_value', + 'listType': 'configuration', + 'listOption': + 'std.scope.icons;configuration_value configuration_id;', + }, + ] + }, + ], + 'pages': [ + { + 'page': 'create', + 'title': 'Programmpunkt hinzufügen', + 'pageType': 'create', + 'sections': [ + { + 'sectionType': 'simpleForm', + 'children': [ + { + 'modelType': 'allDbFields', + } + ] + } + ] + }, + { + 'page': 'change', + 'title': 'Programmpunkt hinzufügen', + 'pageType': 'change', + 'sections': [ + { + 'sectionType': 'simpleForm', + 'children': [ + { + 'modelType': 'allDbFields', + }, + ] + } + ] + }, + { + 'page': 'list', + 'title': 'Programmpunkte', + 'pageType': 'list', + 'tableColumns': 'starter_id starter_name starter_icon', + 'tableTitles': ';Id;Name;Bild', + 'sections': [ + { + 'sectionType': 'filterPanel', + 'children': [ + { + 'modelType': 'dbReference', + 'filterType': 'pattern', + 'name': 'starter_name', + 'column': 'starter_name', + 'toolTip': + 'Filter bezüglich des Namens der anzuzeigenden Einträge: Joker "*" (beliebiger String) ist erlaubt.' + }, + ] + } + ] + }, + ] + }; + + StarterModel(BaseLogger logger) : super(mapStarter, logger); + + /// Returns the name including the names of the parent + @override + String fullName() => name; + + @override + String widgetName() => name; +} diff --git a/lib/src/model/standard/user_model.dart b/lib/src/model/standard/user_model.dart index ef8a81e..23c6423 100644 --- a/lib/src/model/standard/user_model.dart +++ b/lib/src/model/standard/user_model.dart @@ -4,8 +4,8 @@ import '../module_model.dart'; class UserModel extends ModuleModel { static final mapUser = { - "module": "user", - "tables": [ + 'module': 'user', + 'tables': [ { 'table': 'user', 'columns': [ @@ -49,136 +49,141 @@ class UserModel extends ModuleModel { 'dataType': 'reference', 'label': 'Rolle', 'foreignKey': 'role.role_id role_name', - "listType": "dbColumn", - "listOption": "all.role.list;role_name role_id;:role_name=%", - "options": "undef", - "defaultValue": "4", + 'listType': 'dbColumn', + 'listOption': 'all.role.list;role_name role_id;:role_name=%', + 'options': 'undef', + 'defaultValue': '4', }, ] }, ], 'pages': [ { - "page": "create", - "pageType": "create", - "sections": [ + 'page': 'create', + 'title': 'Benutzer hinzufügen', + 'pageType': 'create', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "allDbFields", + 'modelType': 'allDbFields', } ] } ] }, { - "page": "change", - "pageType": "change", - "sections": [ + 'page': 'change', + 'title': 'Benutzer ändern', + 'pageType': 'change', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "allDbFields", + 'modelType': 'allDbFields', }, { - 'modelType': "button", - "name": "set_password", - "label": "Passwort ändern", - "buttonType": "custom", + 'modelType': 'button', + 'name': 'set_password', + 'label': 'Passwort ändern', + 'buttonType': 'custom', }, ] } ] }, { - "page": "password", - "pageType": "change", - "sql": "update_pw", - "sections": [ + 'page': 'password', + 'title': 'Passwort ändern', + 'pageType': 'change', + 'sql': 'update_pw', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "text", - "text": "Ändern des Passworts von Benutzer ~user~", - "options": "placeholder h3" + 'modelType': 'text', + 'text': 'Ändern des Passworts von Benutzer ~user~', + 'options': 'placeholder h3' }, { - 'modelType': "textField", - "name": "user_password", - "label": "Passwort", - "options": "password", - "validators": "required", + 'modelType': 'textField', + 'name': 'user_password', + 'label': 'Passwort', + 'options': 'password', + 'validators': 'required', }, { - 'modelType': "textField", - "name": "repetition", - "label": "Wiederholung", - "options": "password", - "validators": "required equals=user_password" + 'modelType': 'textField', + 'name': 'repetition', + 'label': 'Wiederholung', + 'options': 'password', + 'validators': 'required equals=user_password' }, ] } ] }, { - "page": "list", - "pageType": "list", - "tableColumns": - "user_id user_name user_displayname user_email user_role", - "tableTitles": ";Id;Name;Anzeigename;EMail;Rolle", - "sections": [ + 'page': 'list', + 'title': 'Benutzer', + 'pageType': 'list', + 'tableColumns': + 'user_id user_name user_displayname user_email user_role', + 'tableTitles': ';Id;Name;Anzeigename;EMail;Rolle', + 'sections': [ { - "sectionType": "filterPanel", - "children": [ + 'sectionType': 'filterPanel', + 'children': [ { - 'modelType': "dbReference", - "filterType": "pattern", - "name": "user_name", - "column": "user_name", - "toolTip": - "Filter bezüglich des Namens der anzuzeigenden Einträge: Joker '*' (beliebiger String) ist erlaubt." + 'modelType': 'dbReference', + 'filterType': 'pattern', + 'name': 'user_name', + 'column': 'user_name', + 'toolTip': + 'Filter bezüglich des Namens der anzuzeigenden Einträge: Joker "*" (beliebiger String) ist erlaubt.' }, { - 'modelType': "dbReference", - "name": "user_role", - "filterType": "equals", - "column": "user_role", - "toolTip": - "Filter bezüglich der Rolle der anzuzeigenden Einträge. '-' bedeutet keine Einschränkung", + 'modelType': 'dbReference', + 'name': 'user_role', + 'filterType': 'equals', + 'column': 'user_role', + 'toolTip': + 'Filter bezüglich der Rolle der anzuzeigenden Einträge. "-" bedeutet keine Einschränkung', } ] } ] }, { - "page": "login", - "pageType": "change", - "options": "noAutoButton", - "sections": [ + 'page': 'login', + 'title': 'Anmelden', + 'pageType': 'change', + 'options': 'noAutoButton', + 'sections': [ { - "sectionType": "simpleForm", - "children": [ + 'sectionType': 'simpleForm', + 'children': [ { - 'modelType': "textField", - "name": "user", - "label": "Benutzer oder EMail", - "validators": "required", + 'modelType': 'textField', + 'name': 'user', + 'label': 'Benutzer oder EMail', + 'validators': 'required', }, { - 'modelType': "textField", - "name": "password", - "label": "Password", - "options": "password", - "validators": "required", + 'modelType': 'textField', + 'name': 'password', + 'label': 'Password', + 'options': 'password', + 'validators': 'required', }, { - 'modelType': "button", - "buttonType": "custom", - "name": "login", - "label": "Anmelden", + 'modelType': 'button', + 'buttonType': 'custom', + 'name': 'login', + 'label': 'Anmelden', }, ] } diff --git a/lib/src/page/application_data.dart b/lib/src/page/application_data.dart index 3db0d3e..be00740 100644 --- a/lib/src/page/application_data.dart +++ b/lib/src/page/application_data.dart @@ -5,6 +5,10 @@ import '../persistence/persistence.dart'; import '../persistence/persistence_cache.dart'; import '../widget/page_controller_bones.dart'; +abstract class FooterBones { + List widgets(PageControllerBones controller); +} + /// Data class for storing parameter to build a page. class ApplicationData { final BaseConfiguration configuration; @@ -13,6 +17,7 @@ class ApplicationData { /// Signature: AppBar func(String title) final AppBar Function(String title) appBarBuilder; final Drawer Function(dynamic context) drawerBuilder; + final FooterBones Function() footerBuilder; final Persistence persistence; PersistenceCache persistenceCache; int currentUserId; @@ -33,9 +38,10 @@ class ApplicationData { /// Constructor. /// [configuration] is a map with the widget data (e.g. padding) /// [appBarBuilder] is a factory of a function returning a outside designed AppBar - /// [drawerBuilder] is a factory of a function returning a Drawer which handles the "Hamburger menu" + /// [footerBuilder] is a factory of a function returning a footer area (as one widget) + /// ApplicationData(this.configuration, this.appBarBuilder, this.drawerBuilder, - this.persistence, this.logger) { + this.footerBuilder, this.persistence, this.logger) { currentUserId = 0; currentUserName = 'Gast'; currentRoleId = 0; diff --git a/lib/src/page/demo_page.dart b/lib/src/page/demo_page.dart index fddb649..e217a4b 100644 --- a/lib/src/page/demo_page.dart +++ b/lib/src/page/demo_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bones/flutter_bones.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; class DemoPage extends StatefulWidget { final ApplicationData pageData; @@ -30,32 +31,58 @@ class DemoPageState extends State { final items = texts .map((text) => DropdownMenuItem(value: text, child: Text(text))) .toList(); - return Scaffold( - appBar: pageData.appBarBuilder('Demo'), - drawer: pageData.drawerBuilder(context), - body: SimpleForm.simpleForm( - key: _formKey, - configuration: pageData.configuration, - fields: [ - TextFormField( - validator: checkNotEmpty, - decoration: InputDecoration(labelText: 'Name'), - onSaved: (input) => item.name = input, - ), - DropdownButtonFormField( - value: 'two', - items: items, - decoration: InputDecoration(labelText: 'Number'), - onChanged: (value) => item.number = value, - ), - ], - buttons: [ - RaisedButton( - onPressed: () => login(context), - child: Text('Anmelden'), - ), - ], - )); + const String _markdownData = """ +# Minimal Markdown Test +--- +This is a simple Markdown test. Provide a text string with Markdown tags +to the Markdown widget and it will display the formatted output in a +scrollable widget. + +## Section 1 +Maecenas eget **arcu egestas**, mollis ex vitae, posuere magna. Nunc eget +aliquam tortor. Vestibulum porta sodales efficitur. Mauris interdum turpis +eget est condimentum, vitae porttitor diam ornare. + +### Subsection A +Sed et massa finibus, blandit massa vel, vulputate velit. Vestibulum vitae +venenatis libero. **__Curabitur sem lectus, feugiat eu justo in, eleifend +accumsan ante.__** Sed a fermentum elit. Curabitur sodales metus id mi +ornare, in ullamcorper magna congue. +"""; + if ('a'.startsWith('a')) { + return Scaffold( + appBar: pageData.appBarBuilder('Demo'), + drawer: pageData.drawerBuilder(context), + body: SafeArea(child: Markdown(data: _markdownData))); + } else { + return Scaffold( + appBar: pageData.appBarBuilder('Demo'), + drawer: pageData.drawerBuilder(context), + body: SimpleForm.simpleForm( + key: _formKey, + configuration: pageData.configuration, + intro: [Markdown(data: _markdownData)], + fields: [ + TextFormField( + validator: checkNotEmpty, + decoration: InputDecoration(labelText: 'Name'), + onSaved: (input) => item.name = input, + ), + DropdownButtonFormField( + value: 'two', + items: items, + decoration: InputDecoration(labelText: 'Number'), + onChanged: (value) => item.number = value, + ), + ], + buttons: [ + RaisedButton( + onPressed: () => login(context), + child: Text('Anmelden'), + ), + ], + )); + } } void login(context) async { diff --git a/lib/src/page/menu/menu_converter.dart b/lib/src/page/menu/menu_converter.dart index 391455a..5347a98 100644 --- a/lib/src/page/menu/menu_converter.dart +++ b/lib/src/page/menu/menu_converter.dart @@ -1,5 +1,6 @@ import 'package:dart_bones/dart_bones.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bones/src/page/starter/starter_list_page.dart'; import '../application_data.dart'; import '../configuration/configuration_list_page.dart'; @@ -38,6 +39,9 @@ class MenuConverter { rc = UserPasswordPage(applicationData.currentUserId, applicationData.currentUserName, applicationData, null); break; + case 'starter.list': + rc = StarterListPage(applicationData); + break; case 'demo': rc = DemoPage(applicationData); break; @@ -92,6 +96,9 @@ class MenuConverter { case 'construction_outlined': rc = Icons.construction_outlined; break; + case 'radio_button_checked_outlined': + rc = Icons.radio_button_checked_outlined; + break; default: logger.error('MenuConverter.iconByName(): unknown icon $name'); break; diff --git a/lib/src/page/role/role_change_page.dart b/lib/src/page/role/role_change_page.dart index 3c12af1..73b942a 100644 --- a/lib/src/page/role/role_change_page.dart +++ b/lib/src/page/role/role_change_page.dart @@ -1,25 +1,35 @@ import 'package:flutter/material.dart'; + import '../../helper/settings.dart'; import '../../widget/edit_form.dart'; import '../../widget/page_controller_bones.dart'; import '../application_data.dart'; import 'role_controller.dart'; +//! === BeginOfGeneratedCode: Change only in areas marked as customized +//! pageType: change + class RoleChangePage extends StatefulWidget { final ApplicationData applicationData; final Map initialRow; final logger = Settings().logger; final int primaryId; - //RoleChangePageState lastState; - + //! === BeginOfCustomizedVars1 === + //! === EndOfCustomizedVars1 === + //! === BeginOfConstructor1 === RoleChangePage(this.primaryId, this.applicationData, this.initialRow, {Key key}) : super(key: key); + //! === EndOfConstructor1 === + @override RoleChangePageState createState() { - final rc = RoleChangePageState(primaryId, applicationData, initialRow); + //! === BeginOfCall === + final rc = + RoleChangePageStateCustomized(primaryId, applicationData, initialRow); + //! === EndOfCall === /// for unittests: applicationData.lastModuleState = rc; @@ -27,23 +37,32 @@ class RoleChangePage extends StatefulWidget { } } -class RoleChangePageState extends State implements RedrawPage { +abstract class RoleChangePageState extends State + implements RedrawPage { final ApplicationData applicationData; final int primaryId; final Map initialRow; final GlobalKey _formKey = - GlobalKey(debugLabel: 'role_change'); + GlobalKey(debugLabel: 'role_change'); RoleController controller; + //! === BeginOfCustomizedVars2 === + //! === EndOfCustomizedVars2 === + //! === BeginOfConstructor2 === RoleChangePageState(this.primaryId, this.applicationData, this.initialRow); + //! === EndOfConstructor2 === + @override Widget build(BuildContext context) { controller.beginOfBuild(context); + //! === BeginOfScaffold === return Scaffold( - appBar: applicationData.appBarBuilder('Rolle ändern'), + appBar: applicationData.appBarBuilder(controller.page.title), drawer: applicationData.drawerBuilder(context), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller), body: EditForm.editForm( key: _formKey, pageController: controller, @@ -51,6 +70,15 @@ class RoleChangePageState extends State implements RedrawPage { primaryId: primaryId, initialRow: initialRow, )); + //! === EndOfScaffold === + } + + /// Customize the page, e.g. modify the default widget list given by the model + void customize(); + + void dispose() { + controller.dispose(); + super.dispose(); } @override @@ -59,6 +87,7 @@ class RoleChangePageState extends State implements RedrawPage { controller = RoleController(_formKey, this, 'change', context, applicationData); controller.initialize(); + customize(); } @override @@ -69,9 +98,17 @@ class RoleChangePageState extends State implements RedrawPage { customString: customString, callback: callback); }); } +} - void dispose() { - controller.dispose(); - super.dispose(); +//! === EndOfGeneratedCode: Below you can change manually: + +class RoleChangePageStateCustomized extends RoleChangePageState { + RoleChangePageStateCustomized(int primaryId, ApplicationData applicationData, + Map initialRow) + : super(primaryId, applicationData, initialRow); + + @override + void customize() { + // ToDo: write code if needed } } diff --git a/lib/src/page/role/role_create_page.dart b/lib/src/page/role/role_create_page.dart index 0ba6a1b..ed578ac 100644 --- a/lib/src/page/role/role_create_page.dart +++ b/lib/src/page/role/role_create_page.dart @@ -6,15 +6,25 @@ import '../../widget/page_controller_bones.dart'; import '../application_data.dart'; import 'role_controller.dart'; +//! === BeginOfGeneratedCode: Change only in areas marked as customized +//! pageType: change + class RoleCreatePage extends StatefulWidget { final ApplicationData applicationData; final logger = Settings().logger; + //! === BeginOfCustomizedVars1 === + //! === EndOfCustomizedVars1 === + //! === BeginOfConstructor1 === RoleCreatePage(this.applicationData, {Key key}) : super(key: key); + //! === EndOfConstructor1 === + @override RoleCreatePageState createState() { - final rc = RoleCreatePageState(applicationData); + //! === BeginOfCall === + final rc = RoleCreatePageStateCustomized(applicationData); + //! === EndOfCall === /// for unittests: applicationData.lastModuleState = rc; @@ -22,7 +32,8 @@ class RoleCreatePage extends StatefulWidget { } } -class RoleCreatePageState extends State implements RedrawPage { +abstract class RoleCreatePageState extends State + implements RedrawPage { final ApplicationData applicationData; final GlobalKey _formKey = @@ -30,27 +41,40 @@ class RoleCreatePageState extends State implements RedrawPage { RoleController controller; + //! === BeginOfCustomizedVars2 === + //! === EndOfCustomizedVars2 === + //! === BeginOfConstructor2 === RoleCreatePageState(this.applicationData); + //! === EndOfConstructor2 === + @override Widget build(BuildContext context) { controller?.beginOfBuild(context); + //! === BeginOfScaffold === return Scaffold( - appBar: applicationData.appBarBuilder('Neue Rolle'), + appBar: applicationData.appBarBuilder(controller.page.title), drawer: applicationData.drawerBuilder(context), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller), body: EditForm.editForm( key: _formKey, pageController: controller, configuration: applicationData.configuration, )); + //! === EndOfScaffold === } + /// Customize the page, e.g. modify the default widget list given by the model + void customize(); + @override void initState() { super.initState(); controller = RoleController(_formKey, this, 'create', context, applicationData); controller.initialize(); + customize(); } @override @@ -62,3 +86,15 @@ class RoleCreatePageState extends State implements RedrawPage { }); } } + +//! === EndOfGeneratedCode: Below you can change manually: + +class RoleCreatePageStateCustomized extends RoleCreatePageState { + RoleCreatePageStateCustomized(ApplicationData applicationData) + : super(applicationData); + + @override + void customize() { + // ToDo: write code if needed + } +} diff --git a/lib/src/page/role/role_list_page.dart b/lib/src/page/role/role_list_page.dart index d5966f5..77af1b7 100644 --- a/lib/src/page/role/role_list_page.dart +++ b/lib/src/page/role/role_list_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bones/flutter_bones.dart'; import '../../model/page_model.dart'; import '../../widget/list_form.dart'; @@ -6,15 +7,24 @@ import '../../widget/page_controller_bones.dart'; import '../application_data.dart'; import 'role_controller.dart'; +//! === BeginOfGeneratedCode: Change only in areas marked as customized +//! pageType: change + class RoleListPage extends StatefulWidget { final ApplicationData applicationData; + //! === BeginOfCustomizedVars1 === + //! === EndOfCustomizedVars1 === + //! === BeginOfConstructor1 === RoleListPage(this.applicationData, {Key key}) : super(key: key); + //! === EndOfConstructor1 === + @override RoleListPageState createState() { - // RoleListPageState.setPageData(pageData); - final rc = RoleListPageState(applicationData); + //! === BeginOfCall === + final rc = RoleListPageStateCustomized(applicationData); + //! === EndOfCall === /// for unittests: applicationData.lastModuleState = rc; @@ -22,7 +32,8 @@ class RoleListPage extends StatefulWidget { } } -class RoleListPageState extends State implements RedrawPage { +abstract class RoleListPageState extends State + implements RedrawPage { final ApplicationData applicationData; final GlobalKey _formKey = @@ -30,14 +41,23 @@ class RoleListPageState extends State implements RedrawPage { Iterable rowsDeprecated; RoleController controller; + //! === BeginOfCustomizedVars2 === + //! === EndOfCustomizedVars2 === + //! === BeginOfConstructor2 === RoleListPageState(this.applicationData); + //! === EndOfConstructor2 === + @override Widget build(BuildContext context) { controller.beginOfBuild(context); + + //! === BeginOfScaffold === return Scaffold( - appBar: applicationData.appBarBuilder('Rollen'), + appBar: applicationData.appBarBuilder(controller.page.title), drawer: applicationData.drawerBuilder(context), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller), body: ListForm.listForm( key: _formKey, configuration: applicationData.configuration, @@ -47,29 +67,27 @@ class RoleListPageState extends State implements RedrawPage { showEditIcon: true, pageController: controller, buttons: [ - ButtonBar(alignment: MainAxisAlignment.center, children: [ - controller.searchButton(), - RaisedButton( - child: Text('Neue Rolle'), - onPressed: () { - controller.goTo(pageType: PageModelType.create); - }, - ), - ]), - ], + ButtonBar(alignment: MainAxisAlignment.center, + children: View().modelsToWidgets(controller.page.sections[0].buttonBar, controller), + )], filters: controller.modelList, errorMessage: applicationData.lastErrorMessage(controller.page.fullName()), ), ); + //! === EndOfScaffold === } + /// Customize the page, e.g. modify the default widget list given by the model + void customize(); + @override void initState() { super.initState(); controller = RoleController(_formKey, this, 'list', context, applicationData); controller.initialize(); + customize(); } @override @@ -81,3 +99,19 @@ class RoleListPageState extends State implements RedrawPage { }); } } + +//! === EndOfGeneratedCode: Below you can change manually: + +class RoleListPageStateCustomized extends RoleListPageState { + RoleListPageStateCustomized(ApplicationData applicationData) + : super(applicationData); + + @override + void customize() { + final button = controller.page.buttonByName('new'); + button.onPressed = () { + controller.goTo(pageType: PageModelType.create); + }; + controller.modelList.addModel(button.name, button); + } +} diff --git a/lib/src/page/starter/starter_change_page.dart b/lib/src/page/starter/starter_change_page.dart new file mode 100644 index 0000000..453c516 --- /dev/null +++ b/lib/src/page/starter/starter_change_page.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; + +import '../../helper/settings.dart'; +import '../../widget/edit_form.dart'; +import '../../widget/page_controller_bones.dart'; +import '../application_data.dart'; +import 'starter_controller.dart'; + +class StarterChangePage extends StatefulWidget { + final ApplicationData applicationData; + final Map initialRow; + final logger = Settings().logger; + final int primaryId; + + //StarterChangePageState lastState; + + StarterChangePage(this.primaryId, this.applicationData, this.initialRow, + {Key key}) + : super(key: key); + + @override + StarterChangePageState createState() { + final rc = StarterChangePageState(primaryId, applicationData, initialRow); + + /// for unittests: + applicationData.lastModuleState = rc; + return rc; + } +} + +class StarterChangePageState extends State + implements RedrawPage { + final ApplicationData applicationData; + final int primaryId; + final Map initialRow; + final GlobalKey _formKey = + GlobalKey(debugLabel: 'starter_change'); + + StarterController controller; + + StarterChangePageState(this.primaryId, this.applicationData, this.initialRow); + + @override + Widget build(BuildContext context) { + controller.beginOfBuild(context); + // controller.buildWidgetList() is called in editForm + return Scaffold( + appBar: applicationData.appBarBuilder('Startmenü ändern'), + drawer: applicationData.drawerBuilder(context), + body: EditForm.editForm( + key: _formKey, + pageController: controller, + configuration: applicationData.configuration, + primaryId: primaryId, + initialRow: initialRow, + )); + } + + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + void initState() { + super.initState(); + controller = StarterController( + _formKey, + this, + 'change', + context, + applicationData, + ); + controller.initialize(); + } + + @override + void redraw(RedrawReason reason, + {String customString, RedrawCallbackFunctionSimple callback}) { + setState(() { + controller.afterSetState(reason, + customString: customString, callback: callback); + }); + } +} diff --git a/lib/src/page/starter/starter_controller.dart b/lib/src/page/starter/starter_controller.dart new file mode 100644 index 0000000..44d5426 --- /dev/null +++ b/lib/src/page/starter/starter_controller.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +import '../../helper/settings.dart'; +import '../../model/standard/starter_model.dart'; +import '../../widget/page_controller_bones.dart'; +import '../application_data.dart'; +import 'starter_change_page.dart'; + +class StarterController extends PageControllerBones { + /// Controller for a page named [pageName]. + StarterController(GlobalKey formKey, RedrawPage parent, + String pageName, BuildContext context, ApplicationData applicationData, + {Function redrawCallback}) + : super(formKey, parent, StarterModel(Settings().logger), pageName, + context, applicationData, redrawCallback) { + moduleModel.parse(); + } + @override + void startChange(int id, Map row) { + applicationData.pushCaller(this); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => StarterChangePage(id, applicationData, row))); + } +} diff --git a/lib/src/page/starter/starter_create_page.dart b/lib/src/page/starter/starter_create_page.dart new file mode 100644 index 0000000..eab2be4 --- /dev/null +++ b/lib/src/page/starter/starter_create_page.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; + +import '../../helper/settings.dart'; +import '../../widget/edit_form.dart'; +import '../../widget/page_controller_bones.dart'; +import '../application_data.dart'; +import 'starter_controller.dart'; + +class StarterCreatePage extends StatefulWidget { + final ApplicationData applicationData; + final logger = Settings().logger; + + StarterCreatePage(this.applicationData, {Key key}) : super(key: key); + + @override + StarterCreatePageState createState() { + final rc = StarterCreatePageState(applicationData); + + /// for unittests: + applicationData.lastModuleState = rc; + return rc; + } +} + +class StarterCreatePageState extends State + implements RedrawPage { + final ApplicationData applicationData; + + final GlobalKey _formKey = + GlobalKey(debugLabel: 'starter_create'); + + StarterController controller; + + StarterCreatePageState(this.applicationData); + + @override + Widget build(BuildContext context) { + controller.beginOfBuild(context); + return Scaffold( + appBar: applicationData.appBarBuilder('Neues Startmenü'), + drawer: applicationData.drawerBuilder(context), + body: EditForm.editForm( + key: _formKey, + pageController: controller, + configuration: applicationData.configuration, + )); + } + + @override + void initState() { + super.initState(); + controller = + StarterController(_formKey, this, 'create', context, applicationData); + controller.initialize(); + } + + @override + void redraw(RedrawReason reason, + {String customString, RedrawCallbackFunctionSimple callback}) { + setState(() { + controller.afterSetState(reason, + customString: customString, callback: callback); + }); + } +} diff --git a/lib/src/page/starter/starter_list_page.dart b/lib/src/page/starter/starter_list_page.dart new file mode 100644 index 0000000..20e0f06 --- /dev/null +++ b/lib/src/page/starter/starter_list_page.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; + +import '../../model/page_model.dart'; +import '../../widget/list_form.dart'; +import '../../widget/page_controller_bones.dart'; +import '../application_data.dart'; +import 'starter_controller.dart'; + +class StarterListPage extends StatefulWidget { + final ApplicationData applicationData; + + StarterListPage(this.applicationData, {Key key}) : super(key: key); + + @override + StarterListPageState createState() { + // StarterListPageState.setPageData(pageData); + final rc = StarterListPageState(applicationData); + + /// for unittests: + applicationData.lastModuleState = rc; + return rc; + } +} + +class StarterListPageState extends State + implements RedrawPage { + final ApplicationData applicationData; + + final GlobalKey _formKey = + GlobalKey(debugLabel: 'starter_list'); + Iterable rowsDeprecated; + StarterController controller; + + StarterListPageState(this.applicationData); + + @override + Widget build(BuildContext context) { + controller.beginOfBuild(context); + return Scaffold( + appBar: applicationData.appBarBuilder('Programmpunkte'), + drawer: applicationData.drawerBuilder(context), + body: ListForm.listForm( + key: _formKey, + configuration: applicationData.configuration, + titles: ListForm.stringsToTitles(controller.page.tableTitles), + columnNames: controller.page.tableColumns ?? [], + rows: controller.listRows ?? [], + showEditIcon: true, + pageController: controller, + buttons: [ + ButtonBar(alignment: MainAxisAlignment.center, children: [ + controller.searchButton(), + RaisedButton( + child: Text('Neuer Programmpunkt'), + onPressed: () { + controller.goTo(pageType: PageModelType.create); + }, + ), + ]), + ], + filters: controller.modelList, + errorMessage: + applicationData.lastErrorMessage(controller.page.fullName()), + ), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller)); + } + + @override + void initState() { + super.initState(); + controller = + StarterController(_formKey, this, 'list', context, applicationData); + controller.initialize(); + } + + @override + void redraw(RedrawReason reason, + {String customString, RedrawCallbackFunctionSimple callback}) { + setState(() { + controller.afterSetState(reason, + customString: customString, callback: callback); + }); + } +} diff --git a/lib/src/page/user/user_change_page.dart b/lib/src/page/user/user_change_page.dart index 3409db8..e60bea7 100644 --- a/lib/src/page/user/user_change_page.dart +++ b/lib/src/page/user/user_change_page.dart @@ -8,21 +8,30 @@ import '../application_data.dart'; import 'user_controller.dart'; import 'user_password_page.dart'; +//! === BeginOfGeneratedCode: Below you can change manually: +//! pageType: change + class UserChangePage extends StatefulWidget { final ApplicationData applicationData; final Map initialRow; final logger = Settings().logger; final int primaryId; - //UserChangePageState lastState; - + //! === BeginOfCustomizedVars1 === + //! === EndOfCustomizedVars1 === + //! === BeginOfConstructor1 === UserChangePage(this.primaryId, this.applicationData, this.initialRow, {Key key}) : super(key: key); + //! === EndOfConstructor1 === + @override UserChangePageState createState() { - final rc = UserChangePageState(primaryId, applicationData, initialRow); + //! === BeginOfCall === + final rc = + UserChangePageStateCustomized(primaryId, applicationData, initialRow); + //! === EndOfCall === /// for unittests: applicationData.lastModuleState = rc; @@ -30,23 +39,32 @@ class UserChangePage extends StatefulWidget { } } -class UserChangePageState extends State implements RedrawPage { +abstract class UserChangePageState extends State + implements RedrawPage { final ApplicationData applicationData; final int primaryId; final Map initialRow; final GlobalKey _formKey = - GlobalKey(debugLabel: 'user_change'); + GlobalKey(debugLabel: 'user_change'); UserController controller; + //! === BeginOfCustomizedVars2 === + //! === EndOfCustomizedVars2 === + //! === BeginOfConstructor2 === UserChangePageState(this.primaryId, this.applicationData, this.initialRow); + //! === EndOfConstructor2 === + @override Widget build(BuildContext context) { controller.beginOfBuild(context); + //! === BeginOfScaffold === return Scaffold( - appBar: applicationData.appBarBuilder('Benutzer ändern'), + appBar: applicationData.appBarBuilder(controller.page.title), drawer: applicationData.drawerBuilder(context), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller), body: EditForm.editForm( key: _formKey, pageController: controller, @@ -54,20 +72,11 @@ class UserChangePageState extends State implements RedrawPage { primaryId: primaryId, initialRow: initialRow, )); + //! === EndOfScaffold === } - void customize() { - ButtonModel button = controller.page.buttonByName('set_password'); - button?.onPressed = () { - String userName = controller.page.fieldByName('user_name').value; - applicationData.pushCaller(controller); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => UserPasswordPage( - primaryId, userName, applicationData, null))); - }; - } + /// Customize the page, e.g. modify the default widget list given by the model + void customize(); void dispose() { controller.dispose(); @@ -92,3 +101,25 @@ class UserChangePageState extends State implements RedrawPage { }); } } + +//! === EndOfGeneratedCode: Below you can change manually: + +class UserChangePageStateCustomized extends UserChangePageState { + UserChangePageStateCustomized(int primaryId, ApplicationData applicationData, + Map initialRow) + : super(primaryId, applicationData, initialRow); + + @override + void customize() { + ButtonModel button = controller.page.buttonByName('set_password'); + button?.onPressed = () { + String userName = controller.page.fieldByName('user_name').value; + applicationData.pushCaller(controller); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UserPasswordPage( + primaryId, userName, applicationData, null))); + }; + } +} diff --git a/lib/src/page/user/user_create_page.dart b/lib/src/page/user/user_create_page.dart index cb100c9..09689a2 100644 --- a/lib/src/page/user/user_create_page.dart +++ b/lib/src/page/user/user_create_page.dart @@ -6,15 +6,25 @@ import '../../widget/page_controller_bones.dart'; import '../application_data.dart'; import 'user_controller.dart'; +//! === BeginOfGeneratedCode: Below you can change manually: +//! pageType: change + class UserCreatePage extends StatefulWidget { final ApplicationData applicationData; final logger = Settings().logger; + //! === BeginOfCustomizedVars1 === + //! === EndOfCustomizedVars1 === + //! === BeginOfConstructor1 === UserCreatePage(this.applicationData, {Key key}) : super(key: key); + //! === EndOfConstructor1 === + @override UserCreatePageState createState() { - final rc = UserCreatePageState(applicationData); + //! === BeginOfCall === + final rc = UserCreatePageStateCustomized(applicationData); + //! === EndOfCall === /// for unittests: applicationData.lastModuleState = rc; @@ -22,7 +32,8 @@ class UserCreatePage extends StatefulWidget { } } -class UserCreatePageState extends State implements RedrawPage { +abstract class UserCreatePageState extends State + implements RedrawPage { final ApplicationData applicationData; final GlobalKey _formKey = @@ -30,27 +41,40 @@ class UserCreatePageState extends State implements RedrawPage { UserController controller; + //! === BeginOfCustomizedVars2 === + //! === EndOfCustomizedVars2 === + //! === BeginOfConstructor2 === UserCreatePageState(this.applicationData); + //! === EndOfConstructor2 === + @override Widget build(BuildContext context) { - controller.beginOfBuild(context); + controller?.beginOfBuild(context); + //! === BeginOfScaffold === return Scaffold( - appBar: applicationData.appBarBuilder('Neuer Benutzer'), + appBar: applicationData.appBarBuilder('Neue Rolle'), drawer: applicationData.drawerBuilder(context), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller), body: EditForm.editForm( key: _formKey, pageController: controller, configuration: applicationData.configuration, )); + //! === EndOfScaffold === } + /// Customize the page, e.g. modify the default widget list given by the model + void customize(); + @override void initState() { super.initState(); controller = UserController(_formKey, this, 'create', context, applicationData); controller.initialize(); + customize(); } @override @@ -62,3 +86,15 @@ class UserCreatePageState extends State implements RedrawPage { }); } } + +//! === EndOfGeneratedCode: Below you can change manually: + +class UserCreatePageStateCustomized extends UserCreatePageState { + UserCreatePageStateCustomized(ApplicationData applicationData) + : super(applicationData); + + @override + void customize() { + // ToDo: write code if needed + } +} diff --git a/lib/src/page/user/user_list_page.dart b/lib/src/page/user/user_list_page.dart index ee7b4c9..16e6939 100644 --- a/lib/src/page/user/user_list_page.dart +++ b/lib/src/page/user/user_list_page.dart @@ -7,15 +7,24 @@ import '../../widget/page_controller_bones.dart'; import '../application_data.dart'; import 'user_controller.dart'; +//! === BeginOfGeneratedCode: Below you can change manually: +//! pageType: change + class UserListPage extends StatefulWidget { final ApplicationData applicationData; + //! === BeginOfCustomizedVars1 === + //! === EndOfCustomizedVars1 === + //! === BeginOfConstructor1 === UserListPage(this.applicationData, {Key key}) : super(key: key); + //! === EndOfConstructor1 === + @override UserListPageState createState() { - // UserListPageState.setPageData(pageData); - final rc = UserListPageState(applicationData); + //! === BeginOfCall === + final rc = UserListPageStateCustomized(applicationData); + //! === EndOfCall === /// for unittests: applicationData.lastModuleState = rc; @@ -23,7 +32,8 @@ class UserListPage extends StatefulWidget { } } -class UserListPageState extends State implements RedrawPage { +abstract class UserListPageState extends State + implements RedrawPage { final ApplicationData applicationData; final GlobalKey _formKey = @@ -31,14 +41,23 @@ class UserListPageState extends State implements RedrawPage { Iterable rowsDeprecated; UserController controller; + //! === BeginOfCustomizedVars2 === + //! === EndOfCustomizedVars2 === + //! === BeginOfConstructor2 === UserListPageState(this.applicationData); + //! === EndOfConstructor2 === + @override Widget build(BuildContext context) { controller.beginOfBuild(context); + + //! === BeginOfScaffold === return Scaffold( - appBar: applicationData.appBarBuilder('Benutzer'), + appBar: applicationData.appBarBuilder('Rollen'), drawer: applicationData.drawerBuilder(context), + persistentFooterButtons: + applicationData.footerBuilder().widgets(controller), body: ListForm.listForm( key: _formKey, configuration: applicationData.configuration, @@ -63,14 +82,19 @@ class UserListPageState extends State implements RedrawPage { applicationData.lastErrorMessage(controller.page.fullName()), ), ); + //! === EndOfScaffold === } + /// Customize the page, e.g. modify the default widget list given by the model + void customize(); + @override void initState() { super.initState(); controller = UserController(_formKey, this, 'list', context, applicationData); controller.initialize(); + customize(); } @override @@ -82,3 +106,15 @@ class UserListPageState extends State implements RedrawPage { }); } } + +//! === EndOfGeneratedCode: Below you can change manually: + +class UserListPageStateCustomized extends UserListPageState { + UserListPageStateCustomized(ApplicationData applicationData) + : super(applicationData); + + @override + void customize() { + // ToDo: write code if needed + } +} diff --git a/lib/src/page/user/user_login_page.dart b/lib/src/page/user/user_login_page.dart index 0e6da0a..abf3565 100644 --- a/lib/src/page/user/user_login_page.dart +++ b/lib/src/page/user/user_login_page.dart @@ -9,6 +9,7 @@ import '../application_data.dart'; import 'hash.dart'; import 'user_controller.dart'; +// === BeginOfGeneratedCode: Do not change manually class UserLoginPage extends StatefulWidget { final ApplicationData applicationData; final logger = Settings().logger; @@ -19,7 +20,7 @@ class UserLoginPage extends StatefulWidget { @override UserLoginPageState createState() { - final rc = UserLoginPageState(applicationData); + final rc = UserLoginPageStateCustomized(applicationData); /// for unittests: applicationData.lastModuleState = rc; @@ -27,7 +28,8 @@ class UserLoginPage extends StatefulWidget { } } -class UserLoginPageState extends State implements RedrawPage { +abstract class UserLoginPageState extends State + implements RedrawPage { final ApplicationData applicationData; final GlobalKey _formKey = GlobalKey(debugLabel: 'user.login'); @@ -50,6 +52,36 @@ class UserLoginPageState extends State implements RedrawPage { )); } + void customize(); + + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + void initState() { + super.initState(); + controller = + UserController(_formKey, this, 'login', context, applicationData); + controller.initialize(); + customize(); + } + + @override + void redraw(RedrawReason reason, + {String customString, RedrawCallbackFunctionSimple callback}) { + setState(() { + controller.afterSetState(reason, + customString: customString, callback: callback); + }); + } +} +// === EndOfGeneratedCode: Do not change manually + +class UserLoginPageStateCustomized extends UserLoginPageState { + UserLoginPageStateCustomized(ApplicationData applicationData) + : super(applicationData); void customize() { ButtonModel button = controller.page.buttonByName('login'); button?.onPressed = () { @@ -85,27 +117,4 @@ class UserLoginPageState extends State implements RedrawPage { } }; } - - void dispose() { - controller.dispose(); - super.dispose(); - } - - @override - void initState() { - super.initState(); - controller = - UserController(_formKey, this, 'login', context, applicationData); - controller.initialize(); - customize(); - } - - @override - void redraw(RedrawReason reason, - {String customString, RedrawCallbackFunctionSimple callback}) { - setState(() { - controller.afterSetState(reason, - customString: customString, callback: callback); - }); - } } diff --git a/lib/src/persistence/rest_persistence.dart b/lib/src/persistence/rest_persistence.dart index 94c7cc3..9ab874b 100644 --- a/lib/src/persistence/rest_persistence.dart +++ b/lib/src/persistence/rest_persistence.dart @@ -86,8 +86,8 @@ class RestPersistence extends Persistence { Future delete( {@required String module, String sqlName, @required int id}) async { sqlName ??= 'delete'; - await runRequest(module, sqlName, 'delete', body: '{":${module}_id":$id}', - headers: jsonHeader); + await runRequest(module, sqlName, 'delete', + body: '{":${module}_id":$id}', headers: jsonHeader); } @override @@ -98,8 +98,8 @@ class RestPersistence extends Persistence { sqlName ??= 'insert'; var rc = 0; final data2 = data == null ? '{}' : convert.jsonEncode(data); - final answer = await runRequest( - module, sqlName, 'insert', body: data2, headers: jsonHeader); + final answer = await runRequest(module, sqlName, 'insert', + body: data2, headers: jsonHeader); if (answer.isNotEmpty) { final map = convert.jsonDecode(answer); rc = map['id']; @@ -113,8 +113,8 @@ class RestPersistence extends Persistence { sqlName ??= 'list'; Iterable rc; final body = params == null ? '{}' : convert.jsonEncode(params); - final answer = await runRequest( - module, sqlName, 'list', body: body, headers: jsonHeader); + final answer = await runRequest(module, sqlName, 'list', + body: body, headers: jsonHeader); if (answer.isNotEmpty) { rc = convert.jsonDecode(answer); } diff --git a/lib/src/private/bdrawer.dart b/lib/src/private/bdrawer.dart index e7bb134..1ccc012 100644 --- a/lib/src/private/bdrawer.dart +++ b/lib/src/private/bdrawer.dart @@ -32,8 +32,12 @@ class MenuItem { converter.iconByName('build_outlined', logger)), MenuItem( 'Startmenü', - () => converter.pageByName('menu.list', settings.pageData), + () => converter.pageByName('starter.list', settings.pageData), converter.iconByName('menu_open_outlined', logger)), + MenuItem( + 'Programmpunkte', + () => converter.pageByName('menu.list', settings.pageData), + converter.iconByName('radio_button_checked_outlined', logger)), MenuItem('Demo', () => converter.pageByName('demo', settings.pageData), converter.iconByName('article_outlined', logger)), ]; @@ -51,11 +55,10 @@ class BonesDrawer extends Drawer { final list = MenuItem.menuItems(converter); final rc = Card( child: GridView.count( - crossAxisCount: 2, - crossAxisSpacing: 16.0, - children: list - .map((item) => - GridTile( + crossAxisCount: 2, + crossAxisSpacing: 16.0, + children: list + .map((item) => GridTile( child: new InkResponse( enableFeedback: true, child: Card( @@ -90,12 +93,11 @@ class BonesDrawer extends Drawer { shrinkWrap: true, physics: ClampingScrollPhysics(), children: list - .map((item) => - ListTile( - title: Text(item.title), - onTap: () { - // What happens after you tap the navigation item - Navigator.push( + .map((item) => ListTile( + title: Text(item.title), + onTap: () { + // What happens after you tap the navigation item + Navigator.push( context, MaterialPageRoute( builder: (context) => item.page())); diff --git a/lib/src/private/bfooter.dart b/lib/src/private/bfooter.dart new file mode 100644 index 0000000..c13753b --- /dev/null +++ b/lib/src/private/bfooter.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bones/flutter_bones.dart'; +import 'package:flutter_bones/src/widget/page_controller_bones.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class BFooter implements FooterBones { + List widgets(PageControllerBones controller) { + final rc = [ + Row(children: [ + InkWell( + child: Text('Impressum'), + onTap: () => launch('https://public.hamatoma.de'), + ), + SizedBox( + width: 100, + ), + InkWell( + child: Text('Datenschutz'), + onTap: () => launch('https://public.hamatoma.de'), + ), + SizedBox( + width: 150, + ), + Text('Hallo ${controller.applicationData.currentUserName}'), + ]) + ]; + // final rc2 = [ + // GridView.count(crossAxisCount: 3, children: [ + // Text('a'), + // Text('b'), + // Text('c'), + // ]) + // ]; + return rc; + } + + /// Returns a method creating a footer. + static BFooter builder() => BFooter(); +} diff --git a/lib/src/private/bsettings.dart b/lib/src/private/bsettings.dart index 7236b4e..e73d4f7 100644 --- a/lib/src/private/bsettings.dart +++ b/lib/src/private/bsettings.dart @@ -2,6 +2,7 @@ import 'package:dart_bones/dart_bones.dart'; import 'package:flutter_bones/flutter_bones.dart'; import 'package:flutter_bones/src/private/bappbar.dart'; import 'package:flutter_bones/src/private/bdrawer.dart'; +import 'package:flutter_bones/src/private/bfooter.dart'; class BSettings { final BaseConfiguration configuration; @@ -23,8 +24,13 @@ class BSettings { port: 58011, host: 'localhost', logger: logger); - final applicationData = ApplicationData(BaseConfiguration(map, logger), - BAppBar.builder, BonesDrawer.builder, persistence, logger); + final applicationData = ApplicationData( + BaseConfiguration(map, logger), + BAppBar.builder, + BonesDrawer.builder, + BFooter.builder, + persistence, + logger); final rc = BSettings.internal( BaseConfiguration(map, logger), applicationData, persistence, logger); return lastInstance = rc; diff --git a/lib/src/widget/edit_form.dart b/lib/src/widget/edit_form.dart index 161cb99..292b72c 100644 --- a/lib/src/widget/edit_form.dart +++ b/lib/src/widget/edit_form.dart @@ -25,7 +25,7 @@ class EditForm { final widgets = pageController.getWidgets(); final view = View(); final buttons = - view.modelsToWidgets(pageController.page.buttons, pageController); + view.modelsToWidgets(pageController.page.sections[0].buttonBar, pageController); return Form( key: key, child: Card( diff --git a/lib/src/widget/page_controller_bones.dart b/lib/src/widget/page_controller_bones.dart index 9bd8edb..3062ed3 100644 --- a/lib/src/widget/page_controller_bones.dart +++ b/lib/src/widget/page_controller_bones.dart @@ -100,12 +100,12 @@ class PageControllerBones implements ValidatorController { /// Builds the SQL parameters of all members of the [widgets]. Map buildSqlParams() { final rc = {}; - page.fields.forEach((element) { - if (element.filterType != null) { - dynamic value = element.value; - DataType dataType = element.dataType; - String name = element.name; - if (element.filterType == FilterType.pattern) { + page.models.values.forEach((model) { + if (model is FieldModel && model.filterType != null) { + dynamic value = model.value; + DataType dataType = model.dataType; + String name = model.name; + if (model.filterType == FilterType.pattern) { if (value == null || value.isEmpty) { value = '%'; } else if (value is String) { @@ -125,7 +125,7 @@ class PageControllerBones implements ValidatorController { /// e.g. { 'role_name': 'admin', ...} void buildModelList([Map initialRow]) { modelList.clear(); - page.widgets.forEach((model) { + page.sections[0].children.forEach((model) { if (initialRow != null && model is FieldModel) { model.valueFromRow(initialRow); } @@ -138,7 +138,11 @@ class PageControllerBones implements ValidatorController { completeModels(model); modelList.addModel(name, model); }); - page.fields.forEach((element) => prepareModel(element)); + page.sections[0].children.forEach((element) { + if (element is FieldModel) { + prepareModel(element); + } + }); } /// Completes the widgets asynchronously if needed. @@ -195,12 +199,14 @@ class PageControllerBones implements ValidatorController { } /// Gets the data from the database using the [primaryId]. - fetchData(int primaryId) async { + void fetchData(int primaryId) async { applicationData.persistence .recordById(module: moduleModel.name, id: primaryId) .then((row) { - page.fields.forEach((model) { - model.value = row[model.name]; + page.models.values.forEach((model) { + if (model is FieldModel) { + model.value = row[model.name]; + } }); /// navigate to the page "change": @@ -279,9 +285,7 @@ class PageControllerBones implements ValidatorController { globalKey.currentState.save(); final params = modelList.buildSqlParams(this); PageModelType pageType = - moduleModel - .pageByName(pageName) - .pageModelType; + moduleModel.pageByName(pageName).pageModelType; switch (pageType) { case PageModelType.create: applicationData.persistence @@ -388,9 +392,7 @@ class PageControllerBones implements ValidatorController { void initializeFields(Map initialRow) { modelList.models.forEach((model) { if (model is FieldModel && initialRow.containsKey(model.name)) { - page - .fieldByName(model.name) - ?.value = initialRow[model.name]; + page.fieldByName(model.name)?.value = initialRow[model.name]; } }); } diff --git a/lib/src/widget/simple_form.dart b/lib/src/widget/simple_form.dart index e2d6252..5e00cdf 100644 --- a/lib/src/widget/simple_form.dart +++ b/lib/src/widget/simple_form.dart @@ -6,7 +6,8 @@ class SimpleForm { {@required Key key, @required List fields, @required List buttons, - @required BaseConfiguration configuration}) { + @required BaseConfiguration configuration, + List intro}) { final padding = configuration.asFloat('form.card.padding', defaultValue: 16.0); return Form( @@ -16,6 +17,7 @@ class SimpleForm { child: Padding( padding: EdgeInsets.symmetric(vertical: 16.0, horizontal: 16.0), child: ListView(children: [ + ...intro ?? [], ...fields, SizedBox( height: configuration.asFloat( diff --git a/lib/src/widget/view.dart b/lib/src/widget/view.dart index 53d8e39..446b36a 100644 --- a/lib/src/widget/view.dart +++ b/lib/src/widget/view.dart @@ -58,11 +58,11 @@ class View { return rc; } - /// Creates a list of buttons from a list of [controllers]. + /// Creates a list of buttons from a list of [models]. List buttonList( - List buttonModels, PageControllerBones controller) { + List models, PageControllerBones controller) { final rc = []; - for (var model in buttonModels) { + for (var model in models) { rc.add(button(model, controller)); } return rc; @@ -276,15 +276,15 @@ class View { return rc; } - /// Returns a form with the properties given by the [model] + /// Returns a form with the properties given by the [sectionModel] /// [formKey] identifies the form. Used for form validation and saving. Form simpleForm( - {SectionModel model, PageControllerBones controller, Key formKey}) { + {SectionModel sectionModel, PageControllerBones controller, Key formKey}) { assert(formKey != null); final padding = widgetConfiguration.asFloat('form.card.padding', defaultValue: 16.0); - final children = modelsToWidgets(model.children, controller); - final buttons = buttonList(model.buttons, controller); + final children = modelsToWidgets(sectionModel.children, controller); + final buttons = buttonList(sectionModel.buttonBar, controller); final rc = Form( key: formKey, child: Card( diff --git a/model_tool/lib/main.dart b/model_tool/lib/main.dart index 17a4946..c67d095 100644 --- a/model_tool/lib/main.dart +++ b/model_tool/lib/main.dart @@ -1,78 +1,14 @@ import 'package:dart_bones/dart_bones.dart'; - -import 'src/model/module_model.dart'; -import 'src/model/standard/standard_modules.dart'; -import 'src/helper/string_helper.dart'; +import 'package:flutter_bones_tool/src/model/model_helper.dart'; +import 'package:flutter_bones_tool/src/model_tools.dart'; void main(List argv) async { final logger = MemoryLogger(LEVEL_FINE); - final dbHelper = DbHelper(logger); + final ModelHelper modelHelper = ModelHelper(); + final ModelTools modelTools = ModelTools(modelHelper, logger); if (argv.isEmpty) { argv = ['export-sql']; } - final mode = argv[0]; - argv.removeAt(0); - final options = []; - argv = StringHelper.splitArgv(argv, options); - switch (mode) { - case 'export-sql': - dbHelper.exportSql(argv, options); - break; - default: - logger.error('unknown mode: $mode'); - break; - } + modelTools.run(argv); } -class DbHelper { - final BaseLogger logger; - - DbHelper(this.logger); - - void exportSql(List args, List options) { - String directory; - String value; - for (var opt in options) { - value = StringUtils.stringOption('directory', 'd', opt); - if (value != null) { - directory = value; - } - } - directory ??= 'data'; - final dirDDL = FileSync.joinPaths(directory, 'ddl'); - final dirREST = FileSync.joinPaths(directory, 'rest'); - FileSync.ensureDirectory(dirDDL); - FileSync.ensureDirectory(dirREST); - if (args.isEmpty) { - args = standardModules(); - } - while (args.isNotEmpty) { - final name = args[0]; - args.removeAt(0); - ModuleModel module = standardModule(name, logger); - if (module != null) { - module.parse(); - var filename = FileSync.joinPaths(dirDDL, '$name.sql'); - FileSync.toFile(filename, module.exportSqlCreateTable()); - print('exported: $filename'); - filename = FileSync.joinPaths(dirREST, '$name.yaml'); - FileSync.toFile(filename, module.exportSqlBackend()); - print('exported: $filename'); - } - } - } - - void usage(String error) { - print('''usage: dbhelper [] -: - create-sql [] [] - : 'role', 'user' ... - : - -d or --directory=: - the base directory used for the exported files. -Examples: -dbhelper create-sql role role.sql -d/tmp -dbhelper create-sql --directory=/opt/sql-data -'''); - } -} diff --git a/model_tool/lib/src/model_tools.dart b/model_tool/lib/src/model_tools.dart new file mode 100644 index 0000000..8fb97f6 --- /dev/null +++ b/model_tool/lib/src/model_tools.dart @@ -0,0 +1,239 @@ +import 'dart:io'; + +import 'package:dart_bones/dart_bones.dart'; +import 'package:flutter_bones_tool/src/model/page_model.dart'; + +import 'helper/string_helper.dart'; +import 'model/model_helper.dart'; +import 'model/module_model.dart'; + +class ModelTools { + final BaseLogger logger; + final ModelHelper modelHelper; + ModelTools(this.modelHelper, this.logger); + + /// Copies a range of [lines] defined by [start] and [end] markers into [buffer]. + /// [includeStart]: true: the line containing [start] will be copied too. + /// [includeEnd]: true: the line containing [end] will be copied too. + /// [replacements]: null or a map with (key, replacement) pairs. All + /// occurrences of key in the copied lines will be replaced by the replacement. + /// Returns the count of copied lines. + int copyToBuffer(List lines, StringBuffer buffer, + {String start, + bool includeStart = true, + String end, + bool includeEnd = true, + Map replacements}) { + var mode = start == null ? 'copy' : 'ignore'; + var count = 0; + for (var line in lines) { + if (includeStart && start != null && line.contains(start)) { + mode == 'copy'; + } + if (!includeEnd && end != null && line.contains(end)) { + break; + } + if (mode == 'copy') { + if (replacements != null) { + for (var key in replacements.keys) { + line = line.replaceAll(key, replacements[key]); + } + } + buffer.write(line); + buffer.write('\n'); + count++; + } + if (start != null && line.contains(start)) { + mode = 'copy'; + } + if (end != null && line.contains(end)) { + break; + } + } + return count; + } + + void exportSql(List args, List options) { + String directory; + String value; + for (var opt in options) { + value = StringUtils.stringOption('directory', 'd', opt); + if (value != null) { + directory = value; + continue; + } + logger.error('unknown option: $opt'); + } + directory ??= 'data'; + final dirDDL = FileSync.joinPaths(directory, 'ddl'); + final dirREST = FileSync.joinPaths(directory, 'rest'); + FileSync.ensureDirectory(dirDDL); + FileSync.ensureDirectory(dirREST); + if (args.isEmpty) { + args = modelHelper.moduleNames(); + } + while (args.isNotEmpty) { + final name = args[0]; + args.removeAt(0); + ModuleModel module = modelHelper.moduleByName(name, logger); + if (module != null) { + module.parse(); + var filename = FileSync.joinPaths(dirDDL, '$name.sql'); + FileSync.toFile(filename, module.exportSqlCreateTable()); + print('exported: $filename'); + filename = FileSync.joinPaths(dirREST, '$name.yaml'); + FileSync.toFile(filename, module.exportSqlBackend()); + print('exported: $filename'); + } + } + } + + void modifyModule(List args, List options) { + String baseDirectory; + String value; + for (var opt in options) { + value = StringUtils.stringOption('directory', 'd', opt); + if (value != null) { + baseDirectory = value; + continue; + } + logger.error('unknown option: $opt'); + } + baseDirectory ??= 'lib/src/model'; + if (args.isEmpty) { + args = modelHelper.moduleNames(); + } + final regExprFilename = RegExp(r'_(\w+)_page\.dart'); + for (var name in args) { + if (name == 'role') { + logger.log('module "role" ignored.'); + } + final sourceDir = 'lib/src/page/$name'; + logger.log('current directory: ${Directory.current}'); + final files = Directory(sourceDir).listSync(); + final pathSafe = FileSync.tempDirectory( + name + + '.' + + (DateTime.now().millisecondsSinceEpoch / 1000 % 86400) + .round() + .toString(), + subDirs: 'model_tools'); + for (var file in files) { + final lines = FileSync.fileAsList(file.path); + final fnTemplate = file.path.replaceAll(name, 'role'); + final templateLines = FileSync.fileAsList(fnTemplate); + if (templateLines.isEmpty) { + logger.log('ignoring ${file.path}: no template found'); + continue; + } + final matcher = regExprFilename.firstMatch(file.path); + if (matcher == null) { + logger.error('cannot recognize page type: ${file.path}'); + continue; + } + final pageType = StringUtils.stringToEnum( + matcher.group(1), PageModelType.values); + modifyPage( + name, + pageType, + lines, + templateLines, + FileSync.joinPaths(baseDirectory, name, FileSync.nodeOf(file.path)), + false, + pathSafe); + } + } + } + + void modifyPage( + String module, + PageModelType type, + List lines, + List templateLines, + String filename, + bool customizeConstructors, + String pathSafe) { + final moduleCapital = StringHelper.capitalize(module); + FileSync.ensureDirectory(FileSync.parentOf(filename, trailingSlash: false)); + final buffer = StringBuffer(); + var countTemplate = 0; + final replacements = { + 'role': module, + 'Role': moduleCapital + }; + var countOrigin = 0; + int ix; + if (!customizeConstructors) { + if (StringHelper.listIndexOf(lines, string: 'EndOfGeneratedCode') != null) { + countOrigin = copyToBuffer(lines, buffer, + end: 'BeginOfGeneratedCode', includeEnd: false); + } else { + countOrigin = copyToBuffer(templateLines, buffer, + end: 'BeginOfGeneratedCode', + includeEnd: false, + replacements: replacements); + } + countTemplate = copyToBuffer(templateLines, buffer, + start: 'BeginOfGeneratedCode', + end: 'EndOfGeneratedCode', + replacements: replacements); + countOrigin = copyToBuffer(lines, buffer, + start: 'EndOfGeneratedCode', includeStart: false); + ix = StringHelper.listIndexOf(lines, string: 'EndOfGeneratedCode'); + // -3: possible empty lines at the end + if (ix == null || ix > lines.length - 3) { + countTemplate += copyToBuffer(templateLines, buffer, + start: 'EndOfGeneratedCode', + includeStart: false, + replacements: replacements); + } + } else { + // + } + FileSync.ensureDirectory(pathSafe); + final fnSafe = FileSync.joinPaths(pathSafe, FileSync.nodeOf(filename)); + logger.log('saving to $fnSafe'); + FileSync.toFile(fnSafe, lines.join('\n')); + logger.log('writing $filename lines: $countOrigin + $countTemplate'); + FileSync.toFile(filename, buffer.toString()); + } + + void run(List args) { + final mode = args[0]; + final options = []; + args = StringHelper.splitArgv(args.sublist(1), options); + switch (mode) { + case 'export-sql': + exportSql(args, options); + break; + case 'modify-module': + modifyModule(args, options); + break; + default: + logger.error('unknown mode: $mode'); + break; + } + } + + void usage(String error) { + print('''usage: main [] +: + create-sql [ [...] [] + Generates the DDL ("create table...") statements and the yaml files + describing the insert... SQL statements. + : 'role', 'user' ... + : + -d or --directory=: + the base directory used for the exported files. + help + Display this usage messages. + modify-module [ [...] + Modifies the files of the given modules to renew the generated code. +Examples: +main create-sql role user -d/tmp +main create-sql --directory=/opt/sql-data +main modify-pages role +main modify-pages +'''); + } +} diff --git a/model_tool/lib/src/page b/model_tool/lib/src/page new file mode 120000 index 0000000..6203f10 --- /dev/null +++ b/model_tool/lib/src/page @@ -0,0 +1 @@ +../../../lib/src/page/ \ No newline at end of file diff --git a/model_tool/pubspec.yaml b/model_tool/pubspec.yaml index 09ffb06..25684ba 100644 --- a/model_tool/pubspec.yaml +++ b/model_tool/pubspec.yaml @@ -21,7 +21,7 @@ environment: sdk: ">=2.11.0-234.0.dev <3.0.0" dependencies: - dart_bones: "^0.4.6" + dart_bones: "^0.4.7" # The following adds the Cupertino Icons font to your application. diff --git a/pubspec.yaml b/pubspec.yaml index 6cb3154..fd62faa 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,8 +25,10 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - dart_bones: "^0.4.5" + dart_bones: "^0.4.7" crypto: ^2.1.5 + flutter_markdown: ^0.5.0 + url_launcher: ^5.7.10 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/test/helpers/string_helper_test.dart b/test/helpers/string_helper_test.dart index 32f0766..e33d284 100644 --- a/test/helpers/string_helper_test.dart +++ b/test/helpers/string_helper_test.dart @@ -142,4 +142,25 @@ void main() { expect(options, equals([])); }); }); + group('StringList', (){ + test('listIndexOf-string', (){ + final list = ['a', 'bab', 'cAC']; + expect(StringHelper.listIndexOf(list, string: 'b'), equals(1)); + expect(StringHelper.listIndexOf(list, string: 'a'), equals(0)); + expect(StringHelper.listIndexOf(list, string: 'A'), equals(2)); + expect(StringHelper.listIndexOf(list, string: 'x'), isNull); + expect(StringHelper.listIndexOf(null, string: 'x'), isNull); + }); + test('listIndexOf-regEx', (){ + final list = ['a', 'bab', 'cAC']; + expect(StringHelper.listIndexOf(list, pattern: r'...'), equals(1)); + expect(StringHelper.listIndexOf(list, pattern: r'C$'), equals(2)); + expect(StringHelper.listIndexOf(list, pattern: 'x'), isNull); + expect(StringHelper.listIndexOf(null, pattern: 'x'), isNull); + + expect(StringHelper.listIndexOf(list, regExp: RegExp(r'a', caseSensitive: false)), equals(0)); + expect(StringHelper.listIndexOf(list, regExp: RegExp(r'd')), isNull); + expect(StringHelper.listIndexOf(null, regExp: RegExp(r'd')), isNull); + }); + }); } diff --git a/test/model/model_test.dart b/test/model/model_test.dart index 755193d..2d630ec 100644 --- a/test/model/model_test.dart +++ b/test/model/model_test.dart @@ -103,7 +103,7 @@ void main() { final module = ModuleModel(map, logger); module.parse(); final page = module.pageByName('list'); - page.addButton(ButtonModel.direct( + page.addModel(ButtonModel.direct( null, page, 'a', @@ -111,7 +111,7 @@ void main() { ButtonModelType.store, [], logger)); - page.addButton(ButtonModel.direct( + page.addModel(ButtonModel.direct( null, page, 'a', @@ -120,7 +120,7 @@ void main() { [], logger)); page.buttonByName('unknown'); - page.addField(TextFieldModel.direct( + page.addModel(TextFieldModel.direct( null, page, 'n', @@ -130,7 +130,7 @@ void main() { [], 33, logger)); - page.addField(TextFieldModel.direct( + page.addModel(TextFieldModel.direct( null, page, 'n', @@ -425,7 +425,7 @@ void main() { expect(errors.length, equals(0)); final page = module.pageByName('change'); expect(page, isNotNull); - expect(page.fields.length, equals(3)); + expect(page.models.values.length, equals(3)); expect(page.hasField('user_id'), isTrue); expect(page.hasField('user_name'), isTrue); expect(page.hasField('user_role'), isTrue); diff --git a/test/page/application_test.dart b/test/page/application_test.dart index 02bdac1..1a216f1 100644 --- a/test/page/application_test.dart +++ b/test/page/application_test.dart @@ -23,7 +23,7 @@ void main() async { pageControllerBones = PageControllerBones( null, null, UserModel(logger), 'list', null, applicationData); applicationData = - ApplicationData(configuration, null, null, persistence, logger); + ApplicationData(configuration, null, null, null, persistence, logger); }); group('Basics', () { test('basic', () async { diff --git a/test/tool/tool_test.dart b/test/tool/tool_test.dart index 42c4295..881d0d3 100644 --- a/test/tool/tool_test.dart +++ b/test/tool/tool_test.dart @@ -1,5 +1,6 @@ import 'package:dart_bones/dart_bones.dart'; import 'package:flutter_bones/flutter_bones.dart'; +import 'package:flutter_bones/src/model/model_helper.dart'; import 'package:test/test.dart'; void main() { @@ -66,10 +67,11 @@ modules: ''')); }); test('standard_modules', () { + ModelHelper helper = ModelHelper(); logger.clear(); final dir = FileSync.tempDirectory('data', subDirs: 'unittest'); - for (var name in standardModules()) { - final module = standardModule(name, logger); + for (var name in helper.moduleNames()) { + final module = helper.moduleByName(name, logger); module.parse(); expect(logger.errors.isEmpty, isTrue); final content = module.exportSqlBackend(); @@ -78,7 +80,8 @@ modules: }); test('standard_modules-errors', () { logger.clear(); - final module = standardModule('not-exists', logger); + final helper = ModelHelper(); + final module = helper.moduleByName('not-exists', logger); expect(module, isNull); expect(logger.contains('unknown standard module: not-exists'), isTrue); }); diff --git a/test/widget/widget_test.dart b/test/widget/widget_test.dart index cf09564..2814ea7 100644 --- a/test/widget/widget_test.dart +++ b/test/widget/widget_test.dart @@ -41,7 +41,7 @@ void main() { group('ModuleController', () { test('basic', () { ApplicationData appData = ApplicationData(BaseConfiguration({}, logger), - (title) => null, (context) => null, persistence, logger); + (title) => null, (context) => null, () => null, persistence, logger); final role = RoleCreatePage(appData); if (appData.lastModuleState == null) { role.createState(); diff --git a/test/widget/widget_validators_test.dart b/test/widget/widget_validators_test.dart index 11d6b01..ef43f2d 100644 --- a/test/widget/widget_validators_test.dart +++ b/test/widget/widget_validators_test.dart @@ -192,7 +192,7 @@ void main() { expect(table, isNotNull); var model = table.columnByName('test'); final page = PageModel(module, logger); - page.addField(model); + page.addModel(model); model.page = page; expect(model, isNotNull); model.parseFinish(); @@ -213,7 +213,7 @@ void main() { 'Unzulässige Eingabe "5" in str'); model = table.columnByName('test2'); expect(model, isNotNull); - page.addField(model); + page.addModel(model); model.page = page; model.parseFinish(); prepareModel(model);