List<String> lines = [];
int currentLineNo = 0;
int currentIxLines = 0;
- late RegExp regExpExcluded;
+ RegExp regExpExcluded = RegExp('^(Never°DEFined)\$');
+
// ...........................1.............1.........2
final regExpModule =
RegExp(r'''(\w+) = (I18N\(\)|i18n)\.module\(["'](.*?)['"]\);''');
final regExpDelimiter = RegExp(r'''["']''');
+
// ..........1.............1..2..............................2
final regExpText = RegExp(r'(i18n|I18N\(\))\.(tr|ntr|trMulti|trArgs)\(');
final regExpStringConstant = RegExp(r'''^\s*(r?)(["'])(.*?)\2''');
String locale = 'de_DE';
String loadedLocale = '';
final regExpTag = RegExp(r'<#\d+>$');
+
factory I18N() {
+ if (instance == null) {
+ instance = I18N.internal(MemoryLogger());
+ }
return instance!;
}
+ /**
+ * Constructor for initializing the global instance.
+ *
+ * @param logger: the logger used for error messages.
+ */
I18N.internal(this.logger) {
instance = this;
}
+import 'package:dart_bones/dart_bones.dart';
+
import 'i18n.dart';
final i18n = I18N();
final _regExprEMailFormat = RegExp(r'^[^@]+@[^@]+\.[a-zA-Z]+$');
+final _regExprTime = RegExp(r'^(\d{1,2})(:(\d{1,2}))?$');
+
+final _regExprNat = RegExp(r'^\d+$');
+
/// Tests whether [input] is an correct email address.
///
/// Returns null on success, the error message otherwise.
String? isEmail(String? input) {
String? rc;
- if (input != null) {
+ if (input == null) {
+ rc = i18n.tr('null is not an email');
+ } else {
RegExpMatch? match = _regExprEMailChar.firstMatch(input);
- if (match != null) {
+ if (countChar(input, '@') > 1) {
+ rc = i18n.tr('too many "@" in email address: ') + input;
+ } else if (match != null) {
rc = i18n.trArgs('Illegal character "{0}" in email address', '!global',
[match.group(0)!]);
} else if (_regExprEMailFormat.firstMatch(input) == null) {
/// Tests whether the [input] is a not negative integer.
String? isInt(String? input) {
String? rc;
- if (input != null) {
+ if (input == null) {
+ rc = i18n.tr('null is not an integer');
+ } else {
final value = int.tryParse(input);
if (value == null) {
rc = i18n.trArgs('Not an integer: {0}', '!global', [input]);
/// Tests whether the [input] is a not negative integer.
String? isNat(String? input) {
String? rc;
- if (input != null) {
- final value = int.tryParse(input);
- if (value == null) {
- rc = i18n.trArgs('Not an integer: {0}', '!global', [input]);
- } else if (value < 0) {
+ if (input == null) {
+ rc = i18n.tr('null is not a not negative integer');
+ } else {
+ RegExpMatch? match = _regExprNat.firstMatch(input);
+ if (match == null) {
rc = i18n.trArgs(
'Not negative integer expected, not: {0}', '!global', [input]);
}
return rc;
}
+/// Tests whether the [input] is a time, e.g. "22:44".
+String? isTime(String? input, {bool mayBeEmpty = false}) {
+ String? rc;
+ RegExpMatch? match;
+ if (input == null || input.isEmpty) {
+ if (!mayBeEmpty) {
+ rc = i18n.tr('Nothing is not a time');
+ }
+ } else {
+ if ((match = _regExprTime.firstMatch(input)) == null) {
+ rc = i18n
+ .trArgs('Not a time: {0} Examples: 10 or 9:44 ', '!global', [input]);
+ } else if (int.parse(match!.group(1)!) >= 24) {
+ rc = i18n.trArgs('Wrong hour in: {0}: 0..23', '!global', [input]);
+ } else if (match.groupCount >= 3 &&
+ match.group(3) != null &&
+ int.parse(match.group(3)!) >= 60) {
+ rc = i18n
+ .trArgs('Wrong minutes in: {0} Expected 0..59', '!global', [input]);
+ }
+ }
+ return rc;
+}
+
/// Tests whether the input is not empty.
String? notEmpty(String? input) {
final rc = input == null || input.isEmpty ? i18n.tr('Please fill in.') : null;
--- /dev/null
+import 'package:dart_bones/dart_bones.dart';
+
+import '../base/defines.dart';
+
+typedef MetaMenuItemBuilder = List<dynamic> Function<T>(
+ PropertyMetaData propertyMetaData);
+
+/// Describes a button of a page.
+class ButtonMetaData extends WidgetMetaData {
+ ButtonMetaData(String name) : super(name, WidgetType.button) {
+ //@ToDo
+ }
+}
+
+class CopyDbFields extends FieldMetaData {
+ CopyDbFields(String name, {String options = ''})
+ : super(name, options, dataType: DataType.undefined);
+}
+
+/// Describes a field related to a database column.
+class DbFieldMetaData extends WidgetMetaData {
+ PropertyMetaData? reference;
+
+ DbFieldMetaData(String name, String reference)
+ : super(name, WidgetType.dbField) {
+ //@ToDo
+ }
+}
+
+enum DisplayType {
+ checkbox,
+ combobox,
+ custom,
+ switchWidget,
+ text,
+}
+
+/// Describes a field of the page.
+class FieldMetaData extends WidgetMetaData {
+ DataType dataType;
+ DisplayType displayType;
+ final String options;
+
+ FieldMetaData(String name, this.options,
+ {this.dataType = DataType.string, this.displayType = DisplayType.text})
+ : super(name, WidgetType.field);
+}
+
+/// Describes the list page, that displays an overview over all records of the
+/// related table.
+class ListPageMetaData extends PageMetaData {
+ final String tableHeaders;
+ final String tableColumns;
+ final String whereCondition;
+ final String orderBy;
+ final String selectItems;
+ final String joinItems;
+ final String widgetsBelowFilter;
+ final String toolTipAddButton;
+
+ /// Constructor.
+ ///
+ /// [name] is the page name. It must be unique over all pages in the module.
+ ///
+ /// [fields]: the field in the filter section.
+ ///
+ /// [tableColumns]: a semicolon delimited list of table columns used in the
+ /// table displaying the filtered records. Example: 'user_id;user_name;role'
+ ///
+ /// [tableHeaders]: an auto delimited list of headers for the table. Example:
+ /// ';Id;Name;Role'. Auto delimited: the first char defines the delimiter.
+ ///
+ /// [globalComboBoxes]: If there are filter combo boxes that can be constructed
+ /// by "global methods" the should be listed here.
+ /// Example: 'comboRoles;comboUsers'
+ ///
+ /// [whereCondition]: the filter condition in the SQL statement. Example:
+ /// '(:text IS NULL OR user_name like :text OR user_displayname like :text)'
+ ///
+ /// [orderBy]: the default order by clause. Example: 'changed desc,user_id'
+ ///
+ /// [selectItems]: additional select entries. Must end with ','. Example:
+ /// '''(SELECT count(*) FROM sessions WHERE sessions.user_id=t0.user_id) as count,
+ /// t1.role_created as roledate,'''
+ ///
+ /// [joinItems]: additional joins. Convention: use table ids different from
+ /// the created joins (t1, t2, ...), use j1, j2 ...
+ /// Example: '''JOIN sessions j1 ON j1.user_id=t0.user_id
+ /// JOIN logins j2 ON j2.user_id=t0.user_id'''
+ ///
+ /// [widgetsBelowFilter]: additional widget
+ ListPageMetaData(String label,
+ {String name = '',
+ required List<WidgetMetaData> fields,
+ required this.tableColumns,
+ required this.tableHeaders,
+ String globalComboBoxes = '',
+ this.whereCondition = '',
+ this.orderBy = '',
+ this.selectItems = '',
+ this.joinItems = '',
+ this.widgetsBelowFilter = '',
+ this.toolTipAddButton = ''})
+ : super(label, PageType.list,
+ name: name, fields: fields, globalComboBoxes: globalComboBoxes);
+}
+
+/// Describes a mapping page, that allows assignments of many table entries
+/// of the member table to one entry of a common table.
+///
+/// Example: Common table is roles, member table is starters. Than the page
+/// allows to assign some starters (menu items) to a role.
+class MappingPageMetaData extends PageMetaData {
+ ModuleMetaData? commonModule;
+ ModuleMetaData? memberModule;
+ PropertyMetaData? commonProperty;
+ PropertyMetaData? memberProperty;
+
+ /// Constructor.
+ ///
+ /// [name] is the page name. It must be unique over all pages in the module.
+ /// Default is a name derived from the page type.
+ ///
+ /// [commonModuleName]: the name of the module containing the common entries
+ /// of the relation.
+ ///
+ /// [memberModuleName]: the name of the module containing the member entries
+ /// that belongs to exactly one entry in the common module.
+ ///
+ /// [commonPropertyName]: the name of the property representing the common module.
+ ///
+ /// [memberPropertyName]: the name of the property representing the member module.
+ ///
+ /// Don't forget to initialize the [commonModule], [memberModule],
+ /// [commonProperty] and [memberProperty] in the overridden method [onInitialized].
+ MappingPageMetaData(String label, {String name = ''})
+ : super(label, PageType.mapping, name: name, fields: []);
+}
+
+class MetaException extends FormatException {}
+
+/// Stores the meta data of a module.
+class ModuleMetaData {
+ static final metaColumns = [
+ 'createdAt',
+ 'createdBy',
+ 'changedAt',
+ 'changedBy',
+ 'deletedAt',
+ 'deletedBy'
+ ];
+
+ /// The module name, e.g. users
+ String moduleName = '';
+
+ /// The singular version of the module name, e.g. 'user'
+ String moduleNameSingular = '';
+
+ /// The related database table.
+ String tableName = '';
+
+ final bool needsSqlAll;
+
+ /// If true the fields create, createdBy ... have the same ("short") column name
+ /// instead of prefix and name.
+ bool shortModifiedLabel = false;
+ List<PropertyMetaData> propertyList;
+ List<PageMetaData> pageList;
+ final Map<String, PropertyMetaData> properties = {};
+ String columnPrefix = '';
+
+ ModuleMetaData(this.moduleName, this.propertyList, this.pageList,
+ {String tableName = '',
+ String moduleNameSingular = '',
+ String columnPrefix = '',
+ this.shortModifiedLabel = false,
+ this.needsSqlAll = false}) {
+ this.tableName = tableName.isEmpty ? moduleName.toLowerCase() : tableName;
+ if (moduleNameSingular.isEmpty) {
+ if (!moduleName.endsWith('s')) {
+ moduleNameSingular = moduleName;
+ } else {
+ final length = moduleName.length - 1;
+ moduleNameSingular = moduleName.substring(0, length);
+ }
+ }
+ this.columnPrefix = columnPrefix.isNotEmpty
+ ? columnPrefix
+ : this.moduleNameSingular.toLowerCase();
+
+ for (var item in propertyList) {
+ item.module = this;
+ properties[item.name] = item;
+ if (item.columnName.isEmpty) {
+ final prefix = shortModifiedLabel && metaColumns.contains(item.name)
+ ? ''
+ : (this.columnPrefix + '_');
+ item.columnName = prefix + item.name.toLowerCase();
+ }
+ }
+ for (var item in pageList) {
+ item.module = this;
+ }
+ }
+
+ /// Returns a given [dataType] as string.
+ String dartType(DataType dataType) {
+ String rc;
+ switch (dataType) {
+ case DataType.bool:
+ rc = 'bool';
+ break;
+ case DataType.currency:
+ rc = 'int';
+ break;
+ case DataType.date:
+ case DataType.datetime:
+ rc = 'DateTime';
+ break;
+ case DataType.float:
+ rc = 'double';
+ break;
+ case DataType.int:
+ case DataType.nat:
+ case DataType.reference:
+ rc = 'int';
+ break;
+ case DataType.string:
+ rc = 'String';
+ break;
+ case DataType.undefined:
+ throw const FormatException('dartType(): data type is undefined');
+ }
+ return rc;
+ }
+
+ /// Calculates the column option of a column.
+ /// [property] specifies the meta data of the column.
+ String dbOptions(PropertyMetaData property) {
+ String rc = '';
+ String options = property.options;
+ if (options.contains(':notnull:') || options.contains('primary')) {
+ rc += ' NOT NULL';
+ }
+ if (options.contains('unique')) {
+ rc += ' UNIQUE';
+ }
+ if (property.dataType == DataType.date ||
+ property.dataType == DataType.datetime) {
+ rc += ' NULL';
+ }
+ if (options.contains('primary')) {
+ rc += ' AUTO_INCREMENT';
+ }
+ return rc.isEmpty ? '' : ' $rc';
+ }
+
+ /// Calculates the MySQL data type.
+ /// [dataType] specifies the data type.
+ /// [size] specifies the maximal size for a string type. Only relevant if
+ /// [dataType] == DataType.string.
+ String mySqlType(DataType dataType, int size) {
+ String rc;
+ switch (dataType) {
+ case DataType.bool:
+ rc = 'CHAR(1)';
+ break;
+ case DataType.date:
+ rc = 'DATE';
+ break;
+ case DataType.datetime:
+ rc = 'TIMESTAMP';
+ break;
+ case DataType.float:
+ rc = 'FLOAT';
+ break;
+ case DataType.currency:
+ rc = 'DECIMAL(12,2)';
+ break;
+ case DataType.int:
+ rc = 'INT(10)';
+ break;
+ case DataType.nat:
+ case DataType.reference:
+ rc = 'INT(10) UNSIGNED';
+ break;
+ case DataType.string:
+ size = size == 0 ? 255 : size;
+ if (size <= 255) {
+ rc = 'VARCHAR($size)';
+ } else if (size < 65535) {
+ rc = 'TEXT';
+ } else {
+ rc = 'LARGE TEXT';
+ }
+ break;
+ case DataType.undefined:
+ throw const FormatException('mySqlType(): data type is undefined');
+ }
+ return rc;
+ }
+
+ /// Will be called after the constructor.
+ ///
+ /// Override it if needed.
+ void onInitialized() {
+ for (var page in this.pageList) {
+ page.onInitialized();
+ }
+ }
+
+ /// Returns the meta data of a page given by its [name] or null if missing.
+ PageMetaData? pageByName(String name) {
+ PageMetaData? rc;
+ for (var item in pageList) {
+ if (item.name == name) {
+ rc = item;
+ break;
+ }
+ }
+ return rc;
+ }
+
+ /// Returns the list of pages with a given [pageType]. May be empty.
+ List<PageMetaData> pagesByType(PageType pageType) {
+ final rc = <PageMetaData>[];
+ for (var item in pageList) {
+ if (item.pageType == pageType) {
+ rc.add(item);
+ break;
+ }
+ }
+ return rc;
+ }
+
+ /// Returns the primary key of the relation.
+ PropertyMetaData? primaryOf() {
+ PropertyMetaData? rc;
+ for (var item in propertyList) {
+ if (item.options.contains('primary')) {
+ rc = item;
+ break;
+ }
+ }
+ return rc;
+ }
+
+ /// Returns a property given by the [columnName].
+ PropertyMetaData? propertyByColumnName(String columnName) {
+ PropertyMetaData? rc;
+ for (var field in propertyList) {
+ if (field.columnName == columnName) {
+ rc = field;
+ break;
+ }
+ }
+ return rc;
+ }
+
+ /// Returns the meta data of a property given by its [name] or null if missing.
+ PropertyMetaData? propertyByName(String name) {
+ final rc = propertyList.singleWhere((element) => element.name == name,
+ orElse: null);
+ return rc;
+ }
+
+ /// Returns the properties that are not in [metaColumns].
+ /// : if the name of the property is [included] the property is always part of
+ /// the result.
+ Iterable<PropertyMetaData> standardColumns([String included = '']) {
+ final rc = propertyList.where(
+ (item) => item.name == included || !metaColumns.contains(item.name));
+ return rc;
+ }
+}
+
+class PageMetaData {
+ String name = '';
+ final String label;
+ final PageType pageType;
+ late ModuleMetaData module;
+ final List<WidgetMetaData> fields;
+ final String globalComboBoxes;
+
+ PageMetaData(this.label, this.pageType,
+ {this.name = '', required this.fields, this.globalComboBoxes = ''}) {
+ if (name.isEmpty) {
+ name = enumToString(pageType);
+ }
+ }
+
+ /// Does things when the instance is inititialized.
+ ///
+ /// Must be called after the constructor.
+ void onInitialized() {
+ var newFields = <WidgetMetaData>[];
+ var toDelete = <WidgetMetaData>[];
+ for (var field in fields) {
+ if (field is CopyDbFields) {
+ String excluded = '';
+ final start = field.options.indexOf('excluded=');
+ if (start >= 0) {
+ var end = field.options.indexOf(':', start);
+ if (end < 0) {
+ end = field.options.length;
+ }
+ excluded = ' ' + field.options.substring(start, end) + ' ';
+ }
+ for (var property in module.propertyList) {
+ if (excluded.contains(" ${property.name} ")) {
+ continue;
+ }
+ if (!property.hasOption(':hidden:')) {
+ newFields.add(property);
+ }
+ }
+ toDelete.add(field);
+ }
+ }
+ for (var field in toDelete) {
+ fields.remove(field);
+ }
+ fields.addAll(newFields);
+ }
+}
+
+enum PageType { create, custom, delete, edit, list, mapping }
+
+/// Stores the meta data of a module property stored as column in a database.
+class PropertyMetaData extends WidgetMetaData {
+ late ModuleMetaData module;
+ final String label;
+
+ /// Relative width of the field in a 12 column form: 1 <= width <= 12
+ int weight = 6;
+
+ /// A colon delimited list of options, e.g. ':notnull:unique:'.
+ final String options;
+ final DisplayType displayType;
+ final DataType dataType;
+ MetaMenuItemBuilder? menuItemBuilder;
+
+ /// The size if dataType is DataType.string.
+ final int size;
+ String columnName;
+ var validators = <String>[];
+
+ /// The foreign key if dataType is DataType.reference, e.g. 'users.user_id'
+ String? foreignKey;
+
+ PropertyMetaData(String name, this.label, this.dataType, this.options,
+ {this.displayType = DisplayType.text,
+ this.columnName = '',
+ this.size = 0,
+ this.foreignKey,
+ int weight = 6,
+ List<String>? validators})
+ : super(name, WidgetType.property) {
+ this.weight = weight > 12 ? 12 : weight;
+ this.validators = validators ?? [];
+ }
+
+ /// Returns whether a given [option] is set.
+ ///
+ /// [option] is a word delimited by ':', e.g. ":notnull:"
+ ///
+ /// Returns true, if [option] is part of [options], false otherwise.
+ bool hasOption(String option) {
+ return options.contains(option);
+ }
+}
+
+class ReferenceProperty extends WidgetMetaData {
+ /// This attribute gets is real value after the construcctor of the module.
+ PropertyMetaData child = PropertyMetaData('dummy', '', DataType.bool, '');
+ final String nameChild;
+
+ ReferenceProperty({required this.nameChild})
+ : super(nameChild + 'Ref', WidgetType.referenceProperty);
+}
+
+/// Describes a widget used in the page.
+/// Base class of all other widgets.
+class WidgetMetaData {
+ final WidgetType widgetType;
+ final String name;
+
+ WidgetMetaData(this.name, this.widgetType);
+}
+
+enum WidgetType { button, field, dbField, property, referenceProperty }
class RandomData {
- static final verbs = const [
+ static const verbs = [
'go', 'read', 'eat', 'jump', 'write', 'say', 'talk', 'pray', 'love',
'hate', 'join', 'select', 'walk', 'hear', 'type', // 15
'cry', 'cook', 'fill', 'bide', 'paint'
];
- static final adjectives = const [
+ static const adjectives = [
'high', 'low', 'hot', 'cold', 'wide', 'small', 'pretty', 'dirty',
'simple', 'rich', 'poor', 'full', 'empty', 'happy', 'angry', // 15
'strong', 'wise', 'dirty', 'silly', ''
];
- static final animals = const [
+ static const animals = [
'dog', 'cat', 'mouse', 'cow', 'unicorn', 'lion', 'tiger', 'sheep', 'bull',
'bison', 'bug', 'turtle', 'camel', 'spider', 'swan', // 15
'bunny', 'deer', 'hare', 'fox', 'pig'
];
- static final things = const [
+ static const things = [
'door', 'chair', 'wood', 'ink', 'floor', 'bed', 'bag', 'coat',
'house', 'palace', 'street', 'way', 'city', 'table', 'wall', // 15
'tree', 'gras', 'sky', 'hell', 'garden'
];
- static final colors = const [
+ static const colors = [
'red',
'blue',
'white',
'orange',
'pink'
];
- static final firstnames = const [
+ static const firstnames = [
'Adam',
'Alice',
'Bill',
import 'benchmarks_meta.dart';
import 'roles_meta.dart';
import 'rolestarter_meta.dart';
+import 'scopes_meta.dart';
import 'starters_meta.dart';
-import 'structures_meta.dart';
import 'users_meta.dart';
-
/// Returns the meta data of the module given by [name].
/// Returns null if not found.
ModuleMetaData? moduleByName(String name) {
case 'Rolestarter':
rc = RoleStarterMeta();
break;
+ case 'Scopes':
+ rc = ScopesMeta();
+ break;
case 'Starters':
rc = StartersMeta();
break;
- case 'Structures':
- rc = StructuresMeta();
- break;
case 'Users':
rc = UsersMeta();
break;
}
return rc;
}
-
/// Returns the module names as string list.
List<String> moduleNames() {
return [
'Benchmarks',
'Roles',
'Rolestarter',
+ 'Scopes',
'Starters',
- 'Structures',
'Users',
];
}
--- /dev/null
+import '../base/defines.dart';
+import '../base/i18n.dart';
+import 'module_meta_data.dart';
+
+final i18n = I18N();
+final M = i18n.module("Scopes");
+
+class ScopesMeta extends ModuleMetaData {
+ static ScopesMeta instance = ScopesMeta.internal();
+
+ factory ScopesMeta() {
+ return instance;
+ }
+
+ ScopesMeta.internal()
+ : super('Scopes', [
+ PropertyMetaData('id', i18n.tr('Id'), DataType.reference, ':primary:',
+ displayType: DisplayType.combobox),
+ PropertyMetaData(
+ 'scope', i18n.tr('Scope'), DataType.string, ':notnull:',
+ size: 64),
+ PropertyMetaData(
+ 'name', i18n.tr('Name', M), DataType.string, ':notnull:',
+ size: 64),
+ PropertyMetaData(
+ 'value', i18n.tr('Value', M), DataType.string, ':notnull:',
+ size: 32),
+ PropertyMetaData(
+ 'position', i18n.tr('Position', M), DataType.int, ''),
+ PropertyMetaData('createdAt', i18n.tr('Created at'),
+ DataType.datetime, ':hidden:'),
+ PropertyMetaData(
+ 'createdBy', i18n.tr('Created by'), DataType.string, ':hidden:',
+ size: 32),
+ PropertyMetaData('changedAt', i18n.tr('Changed at'),
+ DataType.datetime, ':hidden:'),
+ PropertyMetaData(
+ 'changedBy', i18n.tr('Changed by'), DataType.string, ':hidden:',
+ size: 32),
+ ], [
+ PageMetaData('New Scope', PageType.create,
+ fields: [CopyDbFields('fields')]),
+ PageMetaData('Change Scope', PageType.edit,
+ fields: [CopyDbFields('fields')]),
+ PageMetaData('Delete Scope', PageType.delete,
+ fields: [CopyDbFields('fields')]),
+ ListPageMetaData(
+ 'Scopes Overview',
+ fields: [
+ PropertyMetaData('text', i18n.tr('Text'), DataType.string,
+ ':where=!text IS NONE OR scope_name like !text OR scope_value like !text:',
+ size: 64),
+ ],
+ toolTipAddButton: i18n.tr('Add a scope item'),
+ tableColumns:
+ 'scope_id;scope_scope;scope_name;scope_value;scope_position',
+ tableHeaders: i18n.tr(';Id;Scope;Name;Value;Position'),
+ ),
+ ]);
+ @override
+ void onInitialized() {
+ super.onInitialized();
+ }
+}
+++ /dev/null
-import '../base/defines.dart';
-import '../base/i18n.dart';
-import 'module_meta_data.dart';
-
-final i18n = I18N();
-final M = i18n.module("Structures");
-
-class StructuresMeta extends ModuleMetaData {
- static StructuresMeta instance = StructuresMeta.internal();
- factory StructuresMeta() {
- return instance;
- }
- StructuresMeta.internal()
- : super('Structures', [
- PropertyMetaData('id', i18n.tr('Id'), DataType.reference, ':primary:',
- displayType: DisplayType.combobox),
- PropertyMetaData(
- 'scope', i18n.tr('Scope'), DataType.string, ':notnull:',
- size: 64),
- PropertyMetaData(
- 'name', i18n.tr('Name', M), DataType.string, ':notnull:',
- size: 64),
- PropertyMetaData(
- 'value', i18n.tr('Value', M), DataType.string, ':notnull:',
- size: 32),
- PropertyMetaData(
- 'position', i18n.tr('Position', M), DataType.int, ''),
- PropertyMetaData('createdAt', i18n.tr('Created at'),
- DataType.datetime, ':hidden:'),
- PropertyMetaData(
- 'createdBy', i18n.tr('Created by'), DataType.string, ':hidden:',
- size: 32),
- PropertyMetaData('changedAt', i18n.tr('Changed at'),
- DataType.datetime, ':hidden:'),
- PropertyMetaData(
- 'changedBy', i18n.tr('Changed by'), DataType.string, ':hidden:',
- size: 32),
- ], [
- PageMetaData('New Structure', PageType.create,
- fields: [CopyDbFields('fields')]),
- PageMetaData('Change Structure', PageType.edit,
- fields: [CopyDbFields('fields')]),
- PageMetaData('Delete Structure', PageType.delete,
- fields: [CopyDbFields('fields')]),
- ListPageMetaData(
- 'Structures Overview',
- fields: [
- PropertyMetaData('text', i18n.tr('Text'), DataType.string,
- ':where=!text IS NONE OR structure_name like !text OR structure_value like !text:',
- size: 64),
- ],
- toolTipAddButton: i18n.tr('Add a structure item'),
- tableColumns:
- 'structure_id;structure_scope;structure_name;structure_value;structure_position',
- tableHeaders: i18n.tr(';Id;Scope;Name;Value;Position'),
- ),
- ]);
- @override
- void onInitialized() {
- super.onInitialized();
- }
-}
'role', i18n.tr('Role'), DataType.reference, ':notnull:',
displayType: DisplayType.combobox,
foreignKey: 'roles.role_id;role_name;role'),
+ PropertyMetaData(
+ 'status', i18n.tr('Status'), DataType.reference, ':notnull:',
+ displayType: DisplayType.combobox,
+ foreignKey: 'roles.role_id;role_name;role'),
PropertyMetaData('createdAt', i18n.tr('Created at'),
DataType.datetime, ':hidden:'),
PropertyMetaData(
import '../../base/defines.dart';
import '../../base/helper.dart';
import '../../persistence/data_record.dart';
-
class BenchmarkData extends DataRecord<int> {
int? id;
String? lastName;
String? createdBy;
DateTime? changedAt;
String? changedBy;
+
BenchmarkData(
{this.id,
this.lastName,
this.createdBy,
this.changedAt,
this.changedBy});
+
BenchmarkData.createFromMap(DataMap map) {
fromMap(map);
}
+
@override
void fromMap(DataMap map) {
id = map.containsKey('benchmark_id')
}
return rc;
}
-
@override
DataMap toMap({DataMap? map, bool clear = true}) {
map ??= DataMap();
class _CreateBenchmarkPageState extends CreateBenchmarkCustom {
_CreateBenchmarkPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _DeleteBenchmarkPageState extends DeleteBenchmarkCustom {
_DeleteBenchmarkPageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _EditBenchmarkPageState extends EditBenchmarkCustom {
_EditBenchmarkPageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _ListBenchmarkPageState extends ListBenchmarkCustom {
_ListBenchmarkPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
import 'roles/list_role_page.dart';
import 'rolestarter/mapping_rolestarter_page.dart';
import 'rolestarter/list_rolestarter_page.dart';
+import 'scopes/create_scope_page.dart';
+import 'scopes/edit_scope_page.dart';
+import 'scopes/delete_scope_page.dart';
+import 'scopes/list_scope_page.dart';
import 'starters/create_starter_page.dart';
import 'starters/edit_starter_page.dart';
import 'starters/delete_starter_page.dart';
import 'starters/list_starter_page.dart';
-import 'structures/create_structure_page.dart';
-import 'structures/edit_structure_page.dart';
-import 'structures/delete_structure_page.dart';
-import 'structures/list_structure_page.dart';
import 'users/create_user_page.dart';
import 'users/edit_user_page.dart';
import 'users/delete_user_page.dart';
case '/RoleStarter/list':
rc = ListRoleStarterPage();
break;
+ case '/Scopes/create':
+ rc = CreateScopePage();
+ break;
+ case '/Scopes/edit':
+ rc = EditScopePage(arg1);
+ break;
+ case '/Scopes/delete':
+ rc = DeleteScopePage(arg1);
+ break;
+ case '/Scopes/list':
+ rc = ListScopePage();
+ break;
case '/Starters/create':
rc = CreateStarterPage();
break;
case '/Starters/list':
rc = ListStarterPage();
break;
- case '/Structures/create':
- rc = CreateStructurePage();
- break;
- case '/Structures/edit':
- rc = EditStructurePage(arg1);
- break;
- case '/Structures/delete':
- rc = DeleteStructurePage(arg1);
- break;
- case '/Structures/list':
- rc = ListStructurePage();
- break;
case '/Users/create':
rc = CreateUserPage();
break;
class _CreateRolePageState extends CreateRoleCustom {
_CreateRolePageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _EditRolePageState extends EditRoleCustom {
_EditRolePageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _ListRolePageState extends ListRoleCustom {
_ListRolePageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
import '../../base/defines.dart';
import '../../base/helper.dart';
import '../../persistence/data_record.dart';
-
class RoleData extends DataRecord<int> {
int? id;
String? name;
String? createdBy;
DateTime? changedAt;
String? changedBy;
+
RoleData(
{this.id,
this.name,
this.createdBy,
this.changedAt,
this.changedBy});
+
RoleData.createFromMap(DataMap map) {
fromMap(map);
}
+
@override
void fromMap(DataMap map) {
id = map.containsKey('role_id')
}
return rc;
}
-
@override
DataMap toMap({DataMap? map, bool clear = true}) {
map ??= DataMap();
class _ListRoleStarterPageState extends ListRoleStarterCustom {
_ListRoleStarterPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _MappingRoleStarterPageState extends MappingRoleStarterCustom {
_MappingRoleStarterPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
import '../../base/defines.dart';
import '../../base/helper.dart';
import '../../persistence/data_record.dart';
-
class RoleStarterData extends DataRecord<int> {
int? id;
int? role;
String? createdBy;
DateTime? changedAt;
String? changedBy;
+
RoleStarterData(
{this.id,
this.role,
this.createdBy,
this.changedAt,
this.changedBy});
+
RoleStarterData.createFromMap(DataMap map) {
fromMap(map);
}
+
@override
void fromMap(DataMap map) {
id = map.containsKey('rolestarter_id')
}
return rc;
}
-
@override
DataMap toMap({DataMap? map, bool clear = true}) {
map ??= DataMap();
--- /dev/null
+// This file is created by the meta_tool. But it can be customized.
+// It will never overridden by the meta_tool.
+import 'package:flutter/material.dart';
+
+import '../../base/defines.dart';
+import '../../base/helper.dart';
+import '../../base/i18n.dart';
+import '../../base/validators.dart';
+import '../../services/global_widget.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import '../../widget/message_line.dart';
+import '../../widget/widget_form.dart';
+import 'create_scope_page.dart';
+
+final i18n = I18N();
+
+class CreateScopeCustom extends State<CreateScopePage> with MessageLine {
+ final globalData = GlobalData();
+ late AttendedPage attendedPage;
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'CreateScope');
+ final scopeController = TextEditingController();
+ final nameController = TextEditingController();
+ final valueController = TextEditingController();
+ final positionController = TextEditingController();
+
+ CreateScopeCustom();
+
+ @override
+ Widget build(BuildContext context) {
+ final rc = Scaffold(
+ appBar: globalData.appBarBuilder(i18n.tr('New Scope')),
+ drawer: globalData.drawerBuilder(context),
+ body: SafeArea(child: buildFrame()));
+ return rc;
+ }
+
+ Widget buildFrame() {
+ final padding = GlobalThemeData.padding;
+ scopeController.text = _fieldData.scope;
+ nameController.text = _fieldData.name;
+ valueController.text = _fieldData.value;
+ positionController.text = asString(_fieldData.position);
+ final formItems = <FormItem>[
+ FormItem(
+ TextFormField(
+ controller: scopeController,
+ decoration: InputDecoration(labelText: i18n.tr('Scope')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.scope = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: i18n.tr('Name')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.name = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: valueController,
+ decoration: InputDecoration(labelText: i18n.tr('Value')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.value = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: positionController,
+ decoration: InputDecoration(labelText: i18n.tr('Position')),
+ onSaved: (value) => _fieldData.position =
+ jsonToObject(value ?? '', dataType: DataType.int)),
+ weight: 6),
+ FormItem(
+ ElevatedButton(
+ onPressed: () => onVerifyAndStore(),
+ child: Text(i18n.tr('Save'))),
+ weight: 8,
+ gapAbove: 2 * padding),
+ FormItem(
+ ElevatedButton(
+ onPressed: () {
+ attendedPage.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/Scopes/list');
+ },
+ child: Text(i18n.tr('Cancel')),
+ ),
+ weight: 4)
+ ];
+ final rc = Form(
+ key: _formKey,
+ child: Card(
+ margin:
+ EdgeInsets.symmetric(vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage.pageStates.screenWidth,
+ padding: padding,
+ ))));
+ return rc;
+ }
+
+ @override
+ void dispose() {
+ helperDummyUsage(DataType.int);
+ globalWidgetDummyUsage();
+ scopeController.dispose();
+ nameController.dispose();
+ valueController.dispose();
+ positionController.dispose();
+ super.dispose();
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ void onStore() {
+ final parameters = <String, dynamic>{
+ 'module': 'Scopes',
+ 'sql': 'insert',
+ };
+ _fieldData.toMap(parameters);
+ globalData.restPersistence
+ .store(what: 'store', map: parameters)
+ .then((answer) {
+ if (answer.startsWith('id:')) {
+ final id = int.tryParse(answer.substring(3));
+ if (id == null || id == 0) {
+ setError(i18n.tr('Saving data failed: $answer'));
+ setState(() => 1);
+ } else {
+ attendedPage.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/Scopes/edit;$id');
+ }
+ }
+ });
+ }
+
+ void onVerifyAndStore() {
+ if (_formKey.currentState != null && _formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ onStore();
+ }
+ }
+}
+
+class _FieldData {
+ String scope = '';
+ String name = '';
+ String value = '';
+ int position = 0;
+
+ void toMap(Map<String, dynamic> map) {
+ map[':scope'] = scope;
+ map[':name'] = name;
+ map[':value'] = value;
+ map[':position'] = asString(position, dbFormat: true);
+ map[':createdBy'] = GlobalData.loginUserName;
+ }
+}
--- /dev/null
+// DO NOT CHANGE. This file is created by the meta_tool!
+import 'package:flutter/material.dart';
+
+import '../../meta/scopes_meta.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import 'create_scope_custom.dart';
+
+class CreateScopePage extends StatefulWidget {
+ final PageStates pageStates = PageStates();
+
+ CreateScopePage() : super();
+
+ @override
+ _CreateScopePageState createState() {
+ final rc = _CreateScopePageState();
+ rc.attendedPage = AttendedPage(
+ this,
+ rc,
+ GlobalData(),
+ ScopesMeta.instance.pageByName('create')!,
+ ScopesMeta.instance,
+ pageStates,
+ (afterReload, rebuild) =>
+ rc.reload(afterReload: afterReload, rebuild: rebuild));
+ pageStates.attendedPage = rc.attendedPage;
+ return rc;
+ }
+}
+
+class _CreateScopePageState extends CreateScopeCustom {
+ _CreateScopePageState() : super();
+
+ @override
+ void didChangeDependencies() {
+ final size = MediaQuery.of(context).size;
+ attendedPage.pageStates.screenWidth = size.width;
+ attendedPage.pageStates.screenHeight = size.height;
+ super.didChangeDependencies();
+ }
+
+ /// Renders the widget tree again.
+ ///
+ /// [afterReload] is a function used as parameter of setState().
+ ///
+ /// If [rebuild] is true the state has been changed and didChangeDependencies()
+ /// will be called.
+ void reload({Function? afterReload, bool rebuild = false}) {
+ if (afterReload == null) {
+ if (rebuild) {
+ setState(() => didChangeDependencies());
+ } else {
+ setState(() => 1);
+ }
+ } else {
+ setState(() {
+ afterReload();
+ if (rebuild) {
+ didChangeDependencies();
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// This file is created by the meta_tool. But it can be customized.
+// It will never overridden by the meta_tool.
+import 'package:flutter/material.dart';
+
+import '../../base/defines.dart';
+import '../../base/helper.dart';
+import '../../base/i18n.dart';
+import '../../base/validators.dart';
+import '../../persistence/persistence.dart';
+import '../../services/global_widget.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import '../../widget/message_line.dart';
+import '../../widget/widget_form.dart';
+import 'delete_scope_page.dart';
+
+final i18n = I18N();
+
+class DeleteScopeCustom extends State<DeleteScopePage> with MessageLine {
+ final int primaryKey;
+ final globalData = GlobalData();
+ late Future<DbData> _futureDbData;
+ late AttendedPage attendedPage;
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'DeleteScope');
+ final scopeController = TextEditingController();
+ final nameController = TextEditingController();
+ final valueController = TextEditingController();
+ final positionController = TextEditingController();
+
+ DeleteScopeCustom(this.primaryKey);
+
+ @override
+ Widget build(BuildContext context) {
+ final rc = Scaffold(
+ appBar: globalData.appBarBuilder(i18n.tr('Delete Scope')),
+ drawer: globalData.drawerBuilder(context),
+ body: SafeArea(
+ child: FutureBuilder<DbData>(
+ future: _futureDbData,
+ builder: (context, snapshot) {
+ final rc = attendedPage.loadRecord(snapshot, (record) {
+ _fieldData.fromMap(record);
+ return buildFrame();
+ });
+ return rc;
+ })));
+ return rc;
+ }
+
+ Widget buildFrame() {
+ final padding = GlobalThemeData.padding;
+ scopeController.text = _fieldData.scope;
+ nameController.text = _fieldData.name;
+ valueController.text = _fieldData.value;
+ positionController.text = asString(_fieldData.position);
+ final formItems = <FormItem>[
+ FormItem(
+ TextFormField(
+ controller: scopeController,
+ decoration: InputDecoration(labelText: i18n.tr('Scope')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.scope = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: i18n.tr('Name')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.name = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: valueController,
+ decoration: InputDecoration(labelText: i18n.tr('Value')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.value = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: positionController,
+ decoration: InputDecoration(labelText: i18n.tr('Position')),
+ onSaved: (value) => _fieldData.position =
+ jsonToObject(value ?? '', dataType: DataType.int)),
+ weight: 6),
+ FormItem(
+ ElevatedButton(
+ onPressed: () => onVerifyAndDelete(),
+ child: Text(i18n.tr('Delete'))),
+ weight: 8,
+ gapAbove: 2 * padding),
+ FormItem(
+ ElevatedButton(
+ onPressed: () {
+ attendedPage.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/Scopes/list');
+ },
+ child: Text(i18n.tr('Cancel')),
+ ),
+ weight: 4)
+ ];
+ final rc = Form(
+ key: _formKey,
+ child: Card(
+ margin:
+ EdgeInsets.symmetric(vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage.pageStates.screenWidth,
+ padding: padding,
+ ))));
+ return rc;
+ }
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ requestRecord();
+ }
+
+ @override
+ void dispose() {
+ helperDummyUsage(DataType.int);
+ globalWidgetDummyUsage();
+ scopeController.dispose();
+ nameController.dispose();
+ valueController.dispose();
+ positionController.dispose();
+ super.dispose();
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ void requestRecord() => _futureDbData = globalData.restPersistence.query(
+ what: 'query',
+ data: {'module': 'Scopes', 'sql': 'byId', ':id': primaryKey});
+
+ void onDelete() {
+ final parameters = <String, dynamic>{
+ 'module': 'Scopes',
+ 'sql': 'delete',
+ ':id': primaryKey
+ };
+ globalData.restPersistence
+ .store(what: 'store', map: parameters)
+ .then((answer) {
+ globalData.navigate(context, '/Scopes/list');
+ });
+ }
+
+ void onVerifyAndDelete() {
+ if (_formKey.currentState != null && _formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ onDelete();
+ }
+ }
+}
+
+class _FieldData {
+ String scope = '';
+ String name = '';
+ String value = '';
+ int position = 0;
+
+ void fromMap(Map<String, dynamic> map) {
+ scope = map['scope_scope'];
+ name = map['scope_name'];
+ value = map['scope_value'];
+ position = jsonToObject(map['scope_position'], dataType: DataType.int);
+ }
+}
--- /dev/null
+// DO NOT CHANGE. This file is created by the meta_tool!
+import 'package:flutter/material.dart';
+
+import '../../meta/scopes_meta.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import 'delete_scope_custom.dart';
+
+class DeleteScopePage extends StatefulWidget {
+ final int primaryKey;
+ final PageStates pageStates = PageStates();
+
+ DeleteScopePage(this.primaryKey) : super();
+
+ @override
+ _DeleteScopePageState createState() {
+ final rc = _DeleteScopePageState(this.primaryKey);
+ rc.attendedPage = AttendedPage(
+ this,
+ rc,
+ GlobalData(),
+ ScopesMeta.instance.pageByName('delete')!,
+ ScopesMeta.instance,
+ pageStates,
+ (afterReload, rebuild) =>
+ rc.reload(afterReload: afterReload, rebuild: rebuild));
+ pageStates.attendedPage = rc.attendedPage;
+ return rc;
+ }
+}
+
+class _DeleteScopePageState extends DeleteScopeCustom {
+ _DeleteScopePageState(int primaryKey) : super(primaryKey);
+
+ @override
+ void didChangeDependencies() {
+ final size = MediaQuery.of(context).size;
+ attendedPage.pageStates.screenWidth = size.width;
+ attendedPage.pageStates.screenHeight = size.height;
+ super.didChangeDependencies();
+ }
+
+ /// Renders the widget tree again.
+ ///
+ /// [afterReload] is a function used as parameter of setState().
+ ///
+ /// If [rebuild] is true the state has been changed and didChangeDependencies()
+ /// will be called.
+ void reload({Function? afterReload, bool rebuild = false}) {
+ if (afterReload == null) {
+ if (rebuild) {
+ setState(() => didChangeDependencies());
+ } else {
+ setState(() => 1);
+ }
+ } else {
+ setState(() {
+ afterReload();
+ if (rebuild) {
+ didChangeDependencies();
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// This file is created by the meta_tool. But it can be customized.
+// It will never overridden by the meta_tool.
+import 'package:flutter/material.dart';
+
+import '../../base/defines.dart';
+import '../../base/helper.dart';
+import '../../base/i18n.dart';
+import '../../base/validators.dart';
+import '../../persistence/persistence.dart';
+import '../../services/global_widget.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import '../../widget/message_line.dart';
+import '../../widget/widget_form.dart';
+import 'edit_scope_page.dart';
+
+final i18n = I18N();
+
+class EditScopeCustom extends State<EditScopePage> with MessageLine {
+ final int primaryKey;
+ final globalData = GlobalData();
+ late Future<DbData> _futureDbData;
+ late AttendedPage attendedPage;
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'EditScope');
+ final scopeController = TextEditingController();
+ final nameController = TextEditingController();
+ final valueController = TextEditingController();
+ final positionController = TextEditingController();
+
+ EditScopeCustom(this.primaryKey);
+
+ @override
+ Widget build(BuildContext context) {
+ final rc = Scaffold(
+ appBar: globalData.appBarBuilder(i18n.tr('Change Scope')),
+ drawer: globalData.drawerBuilder(context),
+ body: SafeArea(
+ child: FutureBuilder<DbData>(
+ future: _futureDbData,
+ builder: (context, snapshot) {
+ final rc = attendedPage.loadRecord(snapshot, (record) {
+ _fieldData.fromMap(record);
+ return buildFrame();
+ });
+ return rc;
+ })));
+ return rc;
+ }
+
+ Widget buildFrame() {
+ final padding = GlobalThemeData.padding;
+ scopeController.text = _fieldData.scope;
+ nameController.text = _fieldData.name;
+ valueController.text = _fieldData.value;
+ positionController.text = asString(_fieldData.position);
+ final formItems = <FormItem>[
+ FormItem(
+ TextFormField(
+ controller: scopeController,
+ decoration: InputDecoration(labelText: i18n.tr('Scope')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.scope = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: nameController,
+ decoration: InputDecoration(labelText: i18n.tr('Name')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.name = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: valueController,
+ decoration: InputDecoration(labelText: i18n.tr('Value')),
+ validator: (input) => notEmpty(input),
+ onSaved: (value) => _fieldData.value = value ?? ''),
+ weight: 6),
+ FormItem(
+ TextFormField(
+ controller: positionController,
+ decoration: InputDecoration(labelText: i18n.tr('Position')),
+ onSaved: (value) => _fieldData.position =
+ jsonToObject(value ?? '', dataType: DataType.int)),
+ weight: 6),
+ FormItem(
+ ElevatedButton(
+ onPressed: () => onVerifyAndStore(),
+ child: Text(i18n.tr('Save'))),
+ weight: 8,
+ gapAbove: 2 * padding),
+ FormItem(
+ ElevatedButton(
+ onPressed: () {
+ attendedPage.pageStates.dbDataState.clear();
+ globalData.navigate(context, '/Scopes/list');
+ },
+ child: Text(i18n.tr('Cancel')),
+ ),
+ weight: 4)
+ ];
+ final rc = Form(
+ key: _formKey,
+ child: Card(
+ margin:
+ EdgeInsets.symmetric(vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(
+ formItems,
+ screenWidth: attendedPage.pageStates.screenWidth,
+ padding: padding,
+ ))));
+ return rc;
+ }
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ requestRecord();
+ }
+
+ @override
+ void dispose() {
+ helperDummyUsage(DataType.int);
+ globalWidgetDummyUsage();
+ scopeController.dispose();
+ nameController.dispose();
+ valueController.dispose();
+ positionController.dispose();
+ super.dispose();
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ void requestRecord() => _futureDbData = globalData.restPersistence.query(
+ what: 'query',
+ data: {'module': 'Scopes', 'sql': 'byId', ':id': primaryKey});
+
+ void onStore() {
+ final parameters = <String, dynamic>{
+ 'module': 'Scopes',
+ 'sql': 'update',
+ ':id': primaryKey
+ };
+ _fieldData.toMap(parameters);
+ globalData.restPersistence
+ .store(what: 'store', map: parameters)
+ .then((answer) {
+ requestRecord();
+ attendedPage.pageStates.dbDataState.clear();
+ setState(() => 1);
+ });
+ }
+
+ void onVerifyAndStore() {
+ if (_formKey.currentState != null && _formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ onStore();
+ }
+ }
+}
+
+class _FieldData {
+ String scope = '';
+ String name = '';
+ String value = '';
+ int position = 0;
+
+ void fromMap(Map<String, dynamic> map) {
+ scope = map['scope_scope'];
+ name = map['scope_name'];
+ value = map['scope_value'];
+ position = jsonToObject(map['scope_position'], dataType: DataType.int);
+ }
+
+ void toMap(Map<String, dynamic> map) {
+ // please set outside: map[':id'] = primaryKey;
+ map[':scope'] = scope;
+ map[':name'] = name;
+ map[':value'] = value;
+ map[':position'] = asString(position, dbFormat: true);
+ map[':changedBy'] = GlobalData.loginUserName;
+ }
+}
--- /dev/null
+// DO NOT CHANGE. This file is created by the meta_tool!
+import 'package:flutter/material.dart';
+
+import '../../meta/scopes_meta.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import 'edit_scope_custom.dart';
+
+class EditScopePage extends StatefulWidget {
+ final int primaryKey;
+ final PageStates pageStates = PageStates();
+
+ EditScopePage(this.primaryKey) : super();
+
+ @override
+ _EditScopePageState createState() {
+ final rc = _EditScopePageState(this.primaryKey);
+ rc.attendedPage = AttendedPage(
+ this,
+ rc,
+ GlobalData(),
+ ScopesMeta.instance.pageByName('edit')!,
+ ScopesMeta.instance,
+ pageStates,
+ (afterReload, rebuild) =>
+ rc.reload(afterReload: afterReload, rebuild: rebuild));
+ pageStates.attendedPage = rc.attendedPage;
+ return rc;
+ }
+}
+
+class _EditScopePageState extends EditScopeCustom {
+ _EditScopePageState(int primaryKey) : super(primaryKey);
+
+ @override
+ void didChangeDependencies() {
+ final size = MediaQuery.of(context).size;
+ attendedPage.pageStates.screenWidth = size.width;
+ attendedPage.pageStates.screenHeight = size.height;
+ super.didChangeDependencies();
+ }
+
+ /// Renders the widget tree again.
+ ///
+ /// [afterReload] is a function used as parameter of setState().
+ ///
+ /// If [rebuild] is true the state has been changed and didChangeDependencies()
+ /// will be called.
+ void reload({Function? afterReload, bool rebuild = false}) {
+ if (afterReload == null) {
+ if (rebuild) {
+ setState(() => didChangeDependencies());
+ } else {
+ setState(() => 1);
+ }
+ } else {
+ setState(() {
+ afterReload();
+ if (rebuild) {
+ didChangeDependencies();
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// This file is created by the meta_tool. But it can be customized.
+// It will never overridden by the meta_tool.
+import 'package:flutter/material.dart';
+
+import '../../base/defines.dart';
+import '../../base/helper.dart';
+import '../../base/i18n.dart';
+import '../../services/global_widget.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import '../../widget/widget_form.dart';
+import '../../persistence/persistence.dart';
+import 'list_scope_page.dart';
+
+final i18n = I18N();
+
+class ListScopeCustom extends State<ListScopePage> {
+ final globalData = GlobalData();
+ late Future<DbData> _futureDbData;
+ late AttendedPage attendedPage;
+ final _fieldData = _FieldData();
+ final GlobalKey<FormState> _formKey =
+ GlobalKey<FormState>(debugLabel: 'CreateScope');
+ final textController = TextEditingController();
+
+ ListScopeCustom();
+
+ @override
+ Widget build(BuildContext context) {
+ final rc = Scaffold(
+ appBar: globalData.appBarBuilder(i18n.tr('Overview scopes')),
+ drawer: globalData.drawerBuilder(context),
+ floatingActionButton: FloatingActionButton(
+ onPressed: () {
+ globalData.navigate(context, '/Scopes/create');
+ },
+ child: const Icon(Icons.add),
+ tooltip: 'Add a scope item'),
+ body: SafeArea(
+ child: FutureBuilder<DbData>(
+ future: _futureDbData,
+ builder: (context, snapshot) {
+ Widget rc;
+ if (snapshot.connectionState != ConnectionState.done) {
+ rc = const CircularProgressIndicator();
+ } else {
+ if (snapshot.hasData) {
+ final rows = attendedPage.getRows(
+ dbData: snapshot.data!,
+ columnList:
+ 'scope_id;scope_scope;scope_name;scope_value;scope_position',
+ onDone: () => setState(() => 1),
+ routeEdit: '/Scopes/edit',
+ context: context);
+ rc = buildFrame(
+ totalCount: snapshot.data?.count ?? rows.length, rows: rows);
+ } else if (snapshot.hasError) {
+ rc = Text('Backend problem: ${snapshot.error}');
+ } else {
+ rc = const CircularProgressIndicator();
+ }
+ }
+ return rc;
+ },
+ )),
+ );
+ return rc;
+ }
+
+ Widget buildFrame({required JsonList rows, required int totalCount}) {
+ final padding = GlobalThemeData.padding;
+ final formItems = <FormItem>[
+ FormItem(
+ TextFormField(
+ controller: textController,
+ decoration: InputDecoration(labelText: i18n.tr('Text')),
+ onSaved: (value) => _fieldData.text = value ?? ''),
+ weight: 6),
+ FormItem(
+ ElevatedButton(
+ onPressed: () => search(), child: Text(i18n.tr('Search'))),
+ weight: 12,
+ gapAbove: padding),
+ ];
+ final form = Form(
+ key: _formKey,
+ child: Card(
+ color: GlobalThemeData.formBackgroundColor,
+ elevation: GlobalThemeData.formElevation,
+ margin:
+ EdgeInsets.symmetric(vertical: padding, horizontal: padding),
+ child: Padding(
+ padding: EdgeInsets.symmetric(
+ vertical: padding, horizontal: padding),
+ child: WidgetForm.flexibleGrid(formItems,
+ screenWidth: attendedPage.pageStates.screenWidth,
+ padding: padding))));
+ final table = DataTable(
+ columns: <DataColumn>[
+ DataColumn(
+ label: Text(i18n.tr('Id')),
+ ),
+ DataColumn(
+ label: Text(i18n.tr('Scope')),
+ ),
+ DataColumn(
+ label: Text(i18n.tr('Name')),
+ ),
+ DataColumn(
+ label: Text(i18n.tr('Value')),
+ ),
+ DataColumn(
+ label: Text(i18n.tr('Position')),
+ ),
+ ],
+ rows: rows as List<DataRow>,
+ );
+ Widget? tabBar = attendedPage.buildChipBar(
+ totalCount: totalCount,
+ offset: _fieldData.theOffset,
+ pageSize: _fieldData.thePageSize,
+ onTap: (offset) {
+ _fieldData.theOffset = offset;
+ requestRecords();
+ setState(() => 1);
+ });
+ final frameWidget = ListView(children: [
+ form,
+ if (tabBar != null) tabBar,
+ SizedBox(height: padding),
+ SizedBox(width: double.infinity, child: table),
+ ]);
+ return frameWidget;
+ }
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ requestRecords();
+ }
+
+ @override
+ void dispose() {
+ helperDummyUsage(DataType.string);
+ globalWidgetDummyUsage();
+ textController.dispose();
+ super.dispose();
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ void requestRecords() =>
+ _futureDbData = globalData.restPersistence.query(what: 'query', data: {
+ 'module': 'Scopes',
+ 'sql': 'list',
+ 'offset': _fieldData.theOffset,
+ 'size': _fieldData.thePageSize,
+ ':text': _fieldData.text,
+ });
+
+ void search() {
+ attendedPage.pageStates.dbDataState.clear();
+ if (_formKey.currentState != null && _formKey.currentState!.validate()) {
+ _formKey.currentState!.save();
+ requestRecords();
+ setState(() => 1);
+ }
+ }
+}
+
+class _FieldData {
+ int thePageSize = 10;
+ int theOffset = 0;
+ String text = '';
+}
--- /dev/null
+// DO NOT CHANGE. This file is created by the meta_tool!
+import 'package:flutter/material.dart';
+
+import '../../meta/scopes_meta.dart';
+import '../../setting/global_data.dart';
+import '../../widget/attended_page.dart';
+import 'list_scope_custom.dart';
+
+class ListScopePage extends StatefulWidget {
+ final PageStates pageStates = PageStates();
+
+ ListScopePage() : super();
+
+ @override
+ _ListScopePageState createState() {
+ final rc = _ListScopePageState();
+ rc.attendedPage = AttendedPage(
+ this,
+ rc,
+ GlobalData(),
+ ScopesMeta.instance.pageByName('list')!,
+ ScopesMeta.instance,
+ pageStates,
+ (afterReload, rebuild) =>
+ rc.reload(afterReload: afterReload, rebuild: rebuild));
+ pageStates.attendedPage = rc.attendedPage;
+ return rc;
+ }
+}
+
+class _ListScopePageState extends ListScopeCustom {
+ _ListScopePageState() : super();
+
+ @override
+ void didChangeDependencies() {
+ final size = MediaQuery.of(context).size;
+ attendedPage.pageStates.screenWidth = size.width;
+ attendedPage.pageStates.screenHeight = size.height;
+ super.didChangeDependencies();
+ }
+
+ /// Renders the widget tree again.
+ ///
+ /// [afterReload] is a function used as parameter of setState().
+ ///
+ /// If [rebuild] is true the state has been changed and didChangeDependencies()
+ /// will be called.
+ void reload({Function? afterReload, bool rebuild = false}) {
+ if (afterReload == null) {
+ if (rebuild) {
+ setState(() => didChangeDependencies());
+ } else {
+ setState(() => 1);
+ }
+ } else {
+ setState(() {
+ afterReload();
+ if (rebuild) {
+ didChangeDependencies();
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// DO NOT CHANGE. This file is created by the meta_tool
+import '../../base/defines.dart';
+import '../../base/helper.dart';
+import '../../persistence/data_record.dart';
+
+class ScopeData extends DataRecord<int> {
+ int? id;
+ String? scope;
+ String? name;
+ String? value;
+ int? position;
+ DateTime? createdAt;
+ String? createdBy;
+ DateTime? changedAt;
+ String? changedBy;
+
+ ScopeData(
+ {this.id,
+ this.scope,
+ this.name,
+ this.value,
+ this.position,
+ this.createdAt,
+ this.createdBy,
+ this.changedAt,
+ this.changedBy});
+
+ ScopeData.createFromMap(DataMap map) {
+ fromMap(map);
+ }
+
+ @override
+ void fromMap(DataMap map) {
+ id = map.containsKey('scope_id')
+ ? fromString(map['scope_id'], dataType: DataType.reference)
+ : null;
+ scope = map.containsKey('scope_scope')
+ ? fromString(map['scope_scope'], dataType: DataType.string)
+ : null;
+ name = map.containsKey('scope_name')
+ ? fromString(map['scope_name'], dataType: DataType.string)
+ : null;
+ value = map.containsKey('scope_value')
+ ? fromString(map['scope_value'], dataType: DataType.string)
+ : null;
+ position = map.containsKey('scope_position')
+ ? fromString(map['scope_position'], dataType: DataType.int)
+ : null;
+ createdAt = map.containsKey('scope_createdat')
+ ? fromString(map['scope_createdat'], dataType: DataType.datetime)
+ : null;
+ createdBy = map.containsKey('scope_createdby')
+ ? fromString(map['scope_createdby'], dataType: DataType.string)
+ : null;
+ changedAt = map.containsKey('scope_changedat')
+ ? fromString(map['scope_changedat'], dataType: DataType.datetime)
+ : null;
+ changedBy = map.containsKey('scope_changedby')
+ ? fromString(map['scope_changedby'], dataType: DataType.string)
+ : null;
+ }
+
+ @override
+ int keyOf() {
+ return id ?? 0;
+ }
+
+ @override
+ String nameOfKey() {
+ return 'scope_id';
+ }
+
+ static DataType? dataTypeOf(String name) {
+ DataType? rc;
+ switch (name) {
+ case 'id':
+ rc = DataType.reference;
+ break;
+ case 'scope':
+ rc = DataType.string;
+ break;
+ case 'name':
+ rc = DataType.string;
+ break;
+ case 'value':
+ rc = DataType.string;
+ break;
+ case 'position':
+ rc = DataType.int;
+ break;
+ case 'createdAt':
+ rc = DataType.datetime;
+ break;
+ case 'createdBy':
+ rc = DataType.string;
+ break;
+ case 'changedAt':
+ rc = DataType.datetime;
+ break;
+ case 'changedBy':
+ rc = DataType.string;
+ break;
+ default:
+ break;
+ }
+ return rc;
+ }
+
+ @override
+ DataMap toMap({DataMap? map, bool clear = true}) {
+ map ??= DataMap();
+ if (clear) {
+ map.clear();
+ }
+ map['scope_id'] = id;
+ map['scope_scope'] = scope;
+ map['scope_name'] = name;
+ map['scope_value'] = value;
+ map['scope_position'] = position;
+ map['scope_createdat'] = createdAt;
+ map['scope_createdby'] = createdBy;
+ map['scope_changedat'] = changedAt;
+ map['scope_changedby'] = changedBy;
+ return map;
+ }
+}
class _CreateStarterPageState extends CreateStarterCustom {
_CreateStarterPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _DeleteStarterPageState extends DeleteStarterCustom {
_DeleteStarterPageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _EditStarterPageState extends EditStarterCustom {
_EditStarterPageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _ListStarterPageState extends ListStarterCustom {
_ListStarterPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
import '../../base/defines.dart';
import '../../base/helper.dart';
import '../../persistence/data_record.dart';
-
class StarterData extends DataRecord<int> {
int? id;
String? name;
String? createdBy;
DateTime? changedAt;
String? changedBy;
+
StarterData(
{this.id,
this.name,
this.createdBy,
this.changedAt,
this.changedBy});
+
StarterData.createFromMap(DataMap map) {
fromMap(map);
}
+
@override
void fromMap(DataMap map) {
id = map.containsKey('starter_id')
}
return rc;
}
-
@override
DataMap toMap({DataMap? map, bool clear = true}) {
map ??= DataMap();
+++ /dev/null
-// This file is created by the meta_tool. But it can be customized.
-// It will never overridden by the meta_tool.
-import 'package:flutter/material.dart';
-
-import '../../base/defines.dart';
-import '../../base/helper.dart';
-import '../../base/i18n.dart';
-import '../../base/validators.dart';
-import '../../services/global_widget.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import '../../widget/message_line.dart';
-import '../../widget/widget_form.dart';
-import 'create_structure_page.dart';
-
-final i18n = I18N();
-
-class CreateStructureCustom extends State<CreateStructurePage>
- with MessageLine {
- final globalData = GlobalData();
- late AttendedPage attendedPage;
- final _fieldData = _FieldData();
- final GlobalKey<FormState> _formKey =
- GlobalKey<FormState>(debugLabel: 'CreateStructure');
- final scopeController = TextEditingController();
- final nameController = TextEditingController();
- final valueController = TextEditingController();
- final positionController = TextEditingController();
- CreateStructureCustom();
- @override
- Widget build(BuildContext context) {
- final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('New Structure')),
- drawer: globalData.drawerBuilder(context),
- body: SafeArea(child: buildFrame()));
- return rc;
- }
-
- Widget buildFrame() {
- final padding = GlobalThemeData.padding;
- scopeController.text = _fieldData.scope;
- nameController.text = _fieldData.name;
- valueController.text = _fieldData.value;
- positionController.text = asString(_fieldData.position);
- final formItems = <FormItem>[
- FormItem(
- TextFormField(
- controller: scopeController,
- decoration: InputDecoration(labelText: i18n.tr('Scope')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.scope = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: nameController,
- decoration: InputDecoration(labelText: i18n.tr('Name')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.name = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: valueController,
- decoration: InputDecoration(labelText: i18n.tr('Value')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.value = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: positionController,
- decoration: InputDecoration(labelText: i18n.tr('Position')),
- onSaved: (value) => _fieldData.position =
- jsonToObject(value ?? '', dataType: DataType.int)),
- weight: 6),
- FormItem(
- ElevatedButton(
- onPressed: () => onVerifyAndStore(),
- child: Text(i18n.tr('Save'))),
- weight: 8,
- gapAbove: 2 * padding),
- FormItem(
- ElevatedButton(
- onPressed: () {
- attendedPage.pageStates.dbDataState.clear();
- globalData.navigate(context, '/Structures/list');
- },
- child: Text(i18n.tr('Cancel')),
- ),
- weight: 4)
- ];
- final rc = Form(
- key: _formKey,
- child: Card(
- margin:
- EdgeInsets.symmetric(vertical: padding, horizontal: padding),
- child: Padding(
- padding: EdgeInsets.symmetric(
- vertical: padding, horizontal: padding),
- child: WidgetForm.flexibleGrid(
- formItems,
- screenWidth: attendedPage.pageStates.screenWidth,
- padding: padding,
- ))));
- return rc;
- }
-
- @override
- void dispose() {
- helperDummyUsage(DataType.int);
- globalWidgetDummyUsage();
- scopeController.dispose();
- nameController.dispose();
- valueController.dispose();
- positionController.dispose();
- super.dispose();
- }
-
- @override
- void initState() {
- super.initState();
- }
-
- void onStore() {
- final parameters = <String, dynamic>{
- 'module': 'Structures',
- 'sql': 'insert',
- };
- _fieldData.toMap(parameters);
- globalData.restPersistence
- .store(what: 'store', map: parameters)
- .then((answer) {
- if (answer.startsWith('id:')) {
- final id = int.tryParse(answer.substring(3));
- if (id == null || id == 0) {
- setError(i18n.tr('Saving data failed: $answer'));
- setState(() => 1);
- } else {
- attendedPage.pageStates.dbDataState.clear();
- globalData.navigate(context, '/Structures/edit;$id');
- }
- }
- });
- }
-
- void onVerifyAndStore() {
- if (_formKey.currentState != null && _formKey.currentState!.validate()) {
- _formKey.currentState!.save();
- onStore();
- }
- }
-}
-
-class _FieldData {
- String scope = '';
- String name = '';
- String value = '';
- int position = 0;
-
- void toMap(Map<String, dynamic> map) {
- map[':scope'] = scope;
- map[':name'] = name;
- map[':value'] = value;
- map[':position'] = asString(position, dbFormat: true);
- map[':createdBy'] = GlobalData.loginUserName;
- }
-}
+++ /dev/null
-// DO NOT CHANGE. This file is created by the meta_tool!
-import 'package:flutter/material.dart';
-
-import '../../meta/structures_meta.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import 'create_structure_custom.dart';
-
-class CreateStructurePage extends StatefulWidget {
- final PageStates pageStates = PageStates();
- CreateStructurePage() : super();
- @override
- _CreateStructurePageState createState() {
- final rc = _CreateStructurePageState();
- rc.attendedPage = AttendedPage(
- this,
- rc,
- GlobalData(),
- StructuresMeta.instance.pageByName('create')!,
- StructuresMeta.instance,
- pageStates,
- (afterReload, rebuild) =>
- rc.reload(afterReload: afterReload, rebuild: rebuild));
- pageStates.attendedPage = rc.attendedPage;
- return rc;
- }
-}
-
-class _CreateStructurePageState extends CreateStructureCustom {
- _CreateStructurePageState() : super();
- @override
- void didChangeDependencies() {
- final size = MediaQuery.of(context).size;
- attendedPage.pageStates.screenWidth = size.width;
- attendedPage.pageStates.screenHeight = size.height;
- super.didChangeDependencies();
- }
-
- /// Renders the widget tree again.
- ///
- /// [afterReload] is a function used as parameter of setState().
- ///
- /// If [rebuild] is true the state has been changed and didChangeDependencies()
- /// will be called.
- void reload({Function? afterReload, bool rebuild = false}) {
- if (afterReload == null) {
- if (rebuild) {
- setState(() => didChangeDependencies());
- } else {
- setState(() => 1);
- }
- } else {
- setState(() {
- afterReload();
- if (rebuild) {
- didChangeDependencies();
- }
- });
- }
- }
-}
+++ /dev/null
-// This file is created by the meta_tool. But it can be customized.
-// It will never overridden by the meta_tool.
-import 'package:flutter/material.dart';
-
-import '../../base/defines.dart';
-import '../../base/helper.dart';
-import '../../base/i18n.dart';
-import '../../base/validators.dart';
-import '../../persistence/persistence.dart';
-import '../../services/global_widget.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import '../../widget/message_line.dart';
-import '../../widget/widget_form.dart';
-import 'delete_structure_page.dart';
-
-final i18n = I18N();
-
-class DeleteStructureCustom extends State<DeleteStructurePage>
- with MessageLine {
- final int primaryKey;
- final globalData = GlobalData();
- late Future<DbData> _futureDbData;
- late AttendedPage attendedPage;
- final _fieldData = _FieldData();
- final GlobalKey<FormState> _formKey =
- GlobalKey<FormState>(debugLabel: 'DeleteStructure');
- final scopeController = TextEditingController();
- final nameController = TextEditingController();
- final valueController = TextEditingController();
- final positionController = TextEditingController();
- DeleteStructureCustom(this.primaryKey);
- @override
- Widget build(BuildContext context) {
- final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Delete Structure')),
- drawer: globalData.drawerBuilder(context),
- body: SafeArea(
- child: FutureBuilder<DbData>(
- future: _futureDbData,
- builder: (context, snapshot) {
- final rc = attendedPage.loadRecord(snapshot, (record) {
- _fieldData.fromMap(record);
- return buildFrame();
- });
- return rc;
- })));
- return rc;
- }
-
- Widget buildFrame() {
- final padding = GlobalThemeData.padding;
- scopeController.text = _fieldData.scope;
- nameController.text = _fieldData.name;
- valueController.text = _fieldData.value;
- positionController.text = asString(_fieldData.position);
- final formItems = <FormItem>[
- FormItem(
- TextFormField(
- controller: scopeController,
- decoration: InputDecoration(labelText: i18n.tr('Scope')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.scope = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: nameController,
- decoration: InputDecoration(labelText: i18n.tr('Name')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.name = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: valueController,
- decoration: InputDecoration(labelText: i18n.tr('Value')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.value = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: positionController,
- decoration: InputDecoration(labelText: i18n.tr('Position')),
- onSaved: (value) => _fieldData.position =
- jsonToObject(value ?? '', dataType: DataType.int)),
- weight: 6),
- FormItem(
- ElevatedButton(
- onPressed: () => onVerifyAndDelete(),
- child: Text(i18n.tr('Delete'))),
- weight: 8,
- gapAbove: 2 * padding),
- FormItem(
- ElevatedButton(
- onPressed: () {
- attendedPage.pageStates.dbDataState.clear();
- globalData.navigate(context, '/Structures/list');
- },
- child: Text(i18n.tr('Cancel')),
- ),
- weight: 4)
- ];
- final rc = Form(
- key: _formKey,
- child: Card(
- margin:
- EdgeInsets.symmetric(vertical: padding, horizontal: padding),
- child: Padding(
- padding: EdgeInsets.symmetric(
- vertical: padding, horizontal: padding),
- child: WidgetForm.flexibleGrid(
- formItems,
- screenWidth: attendedPage.pageStates.screenWidth,
- padding: padding,
- ))));
- return rc;
- }
-
- @override
- void didChangeDependencies() {
- super.didChangeDependencies();
- requestRecord();
- }
-
- @override
- void dispose() {
- helperDummyUsage(DataType.int);
- globalWidgetDummyUsage();
- scopeController.dispose();
- nameController.dispose();
- valueController.dispose();
- positionController.dispose();
- super.dispose();
- }
-
- @override
- void initState() {
- super.initState();
- }
-
- void requestRecord() => _futureDbData = globalData.restPersistence.query(
- what: 'query',
- data: {'module': 'Users', 'sql': 'byId', ':id': primaryKey});
-
- void onDelete() {
- final parameters = <String, dynamic>{
- 'module': 'Structures',
- 'sql': 'delete',
- ':id': primaryKey
- };
- globalData.restPersistence
- .store(what: 'store', map: parameters)
- .then((answer) {
- globalData.navigate(context, '/Structures/list');
- });
- }
-
- void onVerifyAndDelete() {
- if (_formKey.currentState != null && _formKey.currentState!.validate()) {
- _formKey.currentState!.save();
- onDelete();
- }
- }
-}
-
-class _FieldData {
- String scope = '';
- String name = '';
- String value = '';
- int position = 0;
-
- void fromMap(Map<String, dynamic> map) {
- scope = map['structure_scope'];
- name = map['structure_name'];
- value = map['structure_value'];
- position = jsonToObject(map['structure_position'], dataType: DataType.int);
- }
-}
+++ /dev/null
-// DO NOT CHANGE. This file is created by the meta_tool!
-import 'package:flutter/material.dart';
-
-import '../../meta/structures_meta.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import 'delete_structure_custom.dart';
-
-class DeleteStructurePage extends StatefulWidget {
- final int primaryKey;
- final PageStates pageStates = PageStates();
- DeleteStructurePage(this.primaryKey) : super();
- @override
- _DeleteStructurePageState createState() {
- final rc = _DeleteStructurePageState(this.primaryKey);
- rc.attendedPage = AttendedPage(
- this,
- rc,
- GlobalData(),
- StructuresMeta.instance.pageByName('delete')!,
- StructuresMeta.instance,
- pageStates,
- (afterReload, rebuild) =>
- rc.reload(afterReload: afterReload, rebuild: rebuild));
- pageStates.attendedPage = rc.attendedPage;
- return rc;
- }
-}
-
-class _DeleteStructurePageState extends DeleteStructureCustom {
- _DeleteStructurePageState(int primaryKey) : super(primaryKey);
- @override
- void didChangeDependencies() {
- final size = MediaQuery.of(context).size;
- attendedPage.pageStates.screenWidth = size.width;
- attendedPage.pageStates.screenHeight = size.height;
- super.didChangeDependencies();
- }
-
- /// Renders the widget tree again.
- ///
- /// [afterReload] is a function used as parameter of setState().
- ///
- /// If [rebuild] is true the state has been changed and didChangeDependencies()
- /// will be called.
- void reload({Function? afterReload, bool rebuild = false}) {
- if (afterReload == null) {
- if (rebuild) {
- setState(() => didChangeDependencies());
- } else {
- setState(() => 1);
- }
- } else {
- setState(() {
- afterReload();
- if (rebuild) {
- didChangeDependencies();
- }
- });
- }
- }
-}
+++ /dev/null
-// This file is created by the meta_tool. But it can be customized.
-// It will never overridden by the meta_tool.
-import 'package:flutter/material.dart';
-
-import '../../base/defines.dart';
-import '../../base/helper.dart';
-import '../../base/i18n.dart';
-import '../../base/validators.dart';
-import '../../persistence/persistence.dart';
-import '../../services/global_widget.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import '../../widget/message_line.dart';
-import '../../widget/widget_form.dart';
-import 'edit_structure_page.dart';
-
-final i18n = I18N();
-
-class EditStructureCustom extends State<EditStructurePage> with MessageLine {
- final int primaryKey;
- final globalData = GlobalData();
- late Future<DbData> _futureDbData;
- late AttendedPage attendedPage;
- final _fieldData = _FieldData();
- final GlobalKey<FormState> _formKey =
- GlobalKey<FormState>(debugLabel: 'EditStructure');
- final scopeController = TextEditingController();
- final nameController = TextEditingController();
- final valueController = TextEditingController();
- final positionController = TextEditingController();
- EditStructureCustom(this.primaryKey);
- @override
- Widget build(BuildContext context) {
- final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Change Structure')),
- drawer: globalData.drawerBuilder(context),
- body: SafeArea(
- child: FutureBuilder<DbData>(
- future: _futureDbData,
- builder: (context, snapshot) {
- final rc = attendedPage.loadRecord(snapshot, (record) {
- _fieldData.fromMap(record);
- return buildFrame();
- });
- return rc;
- })));
- return rc;
- }
-
- Widget buildFrame() {
- final padding = GlobalThemeData.padding;
- scopeController.text = _fieldData.scope;
- nameController.text = _fieldData.name;
- valueController.text = _fieldData.value;
- positionController.text = asString(_fieldData.position);
- final formItems = <FormItem>[
- FormItem(
- TextFormField(
- controller: scopeController,
- decoration: InputDecoration(labelText: i18n.tr('Scope')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.scope = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: nameController,
- decoration: InputDecoration(labelText: i18n.tr('Name')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.name = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: valueController,
- decoration: InputDecoration(labelText: i18n.tr('Value')),
- validator: (input) => notEmpty(input),
- onSaved: (value) => _fieldData.value = value ?? ''),
- weight: 6),
- FormItem(
- TextFormField(
- controller: positionController,
- decoration: InputDecoration(labelText: i18n.tr('Position')),
- onSaved: (value) => _fieldData.position =
- jsonToObject(value ?? '', dataType: DataType.int)),
- weight: 6),
- FormItem(
- ElevatedButton(
- onPressed: () => onVerifyAndStore(),
- child: Text(i18n.tr('Save'))),
- weight: 8,
- gapAbove: 2 * padding),
- FormItem(
- ElevatedButton(
- onPressed: () {
- attendedPage.pageStates.dbDataState.clear();
- globalData.navigate(context, '/Structures/list');
- },
- child: Text(i18n.tr('Cancel')),
- ),
- weight: 4)
- ];
- final rc = Form(
- key: _formKey,
- child: Card(
- margin:
- EdgeInsets.symmetric(vertical: padding, horizontal: padding),
- child: Padding(
- padding: EdgeInsets.symmetric(
- vertical: padding, horizontal: padding),
- child: WidgetForm.flexibleGrid(
- formItems,
- screenWidth: attendedPage.pageStates.screenWidth,
- padding: padding,
- ))));
- return rc;
- }
-
- @override
- void didChangeDependencies() {
- super.didChangeDependencies();
- requestRecord();
- }
-
- @override
- void dispose() {
- helperDummyUsage(DataType.int);
- globalWidgetDummyUsage();
- scopeController.dispose();
- nameController.dispose();
- valueController.dispose();
- positionController.dispose();
- super.dispose();
- }
-
- @override
- void initState() {
- super.initState();
- }
-
- void requestRecord() => _futureDbData = globalData.restPersistence.query(
- what: 'query',
- data: {'module': 'Users', 'sql': 'byId', ':id': primaryKey});
-
- void onStore() {
- final parameters = <String, dynamic>{
- 'module': 'Structures',
- 'sql': 'update',
- ':id': primaryKey
- };
- _fieldData.toMap(parameters);
- globalData.restPersistence
- .store(what: 'store', map: parameters)
- .then((answer) {
- requestRecord();
- attendedPage.pageStates.dbDataState.clear();
- setState(() => 1);
- });
- }
-
- void onVerifyAndStore() {
- if (_formKey.currentState != null && _formKey.currentState!.validate()) {
- _formKey.currentState!.save();
- onStore();
- }
- }
-}
-
-class _FieldData {
- String scope = '';
- String name = '';
- String value = '';
- int position = 0;
-
- void fromMap(Map<String, dynamic> map) {
- scope = map['structure_scope'];
- name = map['structure_name'];
- value = map['structure_value'];
- position = jsonToObject(map['structure_position'], dataType: DataType.int);
- }
-
- void toMap(Map<String, dynamic> map) {
- // please set outside: map[':id'] = primaryKey;
- map[':scope'] = scope;
- map[':name'] = name;
- map[':value'] = value;
- map[':position'] = asString(position, dbFormat: true);
- map[':changedBy'] = GlobalData.loginUserName;
- }
-}
+++ /dev/null
-// DO NOT CHANGE. This file is created by the meta_tool!
-import 'package:flutter/material.dart';
-
-import '../../meta/structures_meta.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import 'edit_structure_custom.dart';
-
-class EditStructurePage extends StatefulWidget {
- final int primaryKey;
- final PageStates pageStates = PageStates();
- EditStructurePage(this.primaryKey) : super();
- @override
- _EditStructurePageState createState() {
- final rc = _EditStructurePageState(this.primaryKey);
- rc.attendedPage = AttendedPage(
- this,
- rc,
- GlobalData(),
- StructuresMeta.instance.pageByName('edit')!,
- StructuresMeta.instance,
- pageStates,
- (afterReload, rebuild) =>
- rc.reload(afterReload: afterReload, rebuild: rebuild));
- pageStates.attendedPage = rc.attendedPage;
- return rc;
- }
-}
-
-class _EditStructurePageState extends EditStructureCustom {
- _EditStructurePageState(int primaryKey) : super(primaryKey);
- @override
- void didChangeDependencies() {
- final size = MediaQuery.of(context).size;
- attendedPage.pageStates.screenWidth = size.width;
- attendedPage.pageStates.screenHeight = size.height;
- super.didChangeDependencies();
- }
-
- /// Renders the widget tree again.
- ///
- /// [afterReload] is a function used as parameter of setState().
- ///
- /// If [rebuild] is true the state has been changed and didChangeDependencies()
- /// will be called.
- void reload({Function? afterReload, bool rebuild = false}) {
- if (afterReload == null) {
- if (rebuild) {
- setState(() => didChangeDependencies());
- } else {
- setState(() => 1);
- }
- } else {
- setState(() {
- afterReload();
- if (rebuild) {
- didChangeDependencies();
- }
- });
- }
- }
-}
+++ /dev/null
-// This file is created by the meta_tool. But it can be customized.
-// It will never overridden by the meta_tool.
-import 'package:flutter/material.dart';
-
-import '../../base/defines.dart';
-import '../../base/helper.dart';
-import '../../base/i18n.dart';
-import '../../services/global_widget.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import '../../widget/widget_form.dart';
-import '../../persistence/persistence.dart';
-import 'list_structure_page.dart';
-
-final i18n = I18N();
-
-class ListStructureCustom extends State<ListStructurePage> {
- final globalData = GlobalData();
- late Future<DbData> _futureDbData;
- late AttendedPage attendedPage;
- final _fieldData = _FieldData();
- final GlobalKey<FormState> _formKey =
- GlobalKey<FormState>(debugLabel: 'CreateStructure');
- final textController = TextEditingController();
- ListStructureCustom();
- @override
- Widget build(BuildContext context) {
- final rc = Scaffold(
- appBar: globalData.appBarBuilder(i18n.tr('Overview structures')),
- drawer: globalData.drawerBuilder(context),
- floatingActionButton: FloatingActionButton(
- onPressed: () {
- globalData.navigate(context, '/Structures/create');
- },
- child: const Icon(Icons.add),
- tooltip: 'Add a structure item'),
- body: SafeArea(
- child: FutureBuilder<DbData>(
- future: _futureDbData,
- builder: (context, snapshot) {
- Widget rc;
- if (snapshot.connectionState != ConnectionState.done) {
- rc = const CircularProgressIndicator();
- } else {
- if (snapshot.hasData) {
- final rows = attendedPage.getRows(
- dbData: snapshot.data!,
- columnList:
- 'structure_id;structure_scope;structure_name;structure_value;structure_position',
- onDone: () => setState(() => 1),
- routeEdit: '/Structures/edit',
- context: context);
- rc = buildFrame(
- totalCount: snapshot.data?.count ?? rows.length, rows: rows);
- } else if (snapshot.hasError) {
- rc = Text('Backend problem: ${snapshot.error}');
- } else {
- rc = const CircularProgressIndicator();
- }
- }
- return rc;
- },
- )),
- );
- return rc;
- }
-
- Widget buildFrame({required JsonList rows, required int totalCount}) {
- final padding = GlobalThemeData.padding;
- final formItems = <FormItem>[
- FormItem(
- TextFormField(
- controller: textController,
- decoration: InputDecoration(labelText: i18n.tr('Text')),
- onSaved: (value) => _fieldData.text = value ?? ''),
- weight: 6),
- FormItem(
- ElevatedButton(
- onPressed: () => search(), child: Text(i18n.tr('Search'))),
- weight: 12,
- gapAbove: padding),
- ];
- final form = Form(
- key: _formKey,
- child: Card(
- color: GlobalThemeData.formBackgroundColor,
- elevation: GlobalThemeData.formElevation,
- margin:
- EdgeInsets.symmetric(vertical: padding, horizontal: padding),
- child: Padding(
- padding: EdgeInsets.symmetric(
- vertical: padding, horizontal: padding),
- child: WidgetForm.flexibleGrid(formItems,
- screenWidth: attendedPage.pageStates.screenWidth,
- padding: padding))));
- final table = DataTable(
- columns: <DataColumn>[
- DataColumn(
- label: Text(i18n.tr('Id')),
- ),
- DataColumn(
- label: Text(i18n.tr('Scope')),
- ),
- DataColumn(
- label: Text(i18n.tr('Name')),
- ),
- DataColumn(
- label: Text(i18n.tr('Value')),
- ),
- DataColumn(
- label: Text(i18n.tr('Position')),
- ),
- ],
- rows: rows as List<DataRow>,
- );
- Widget? tabBar = attendedPage.buildChipBar(
- totalCount: totalCount,
- offset: _fieldData.theOffset,
- pageSize: _fieldData.thePageSize,
- onTap: (offset) {
- _fieldData.theOffset = offset;
- requestRecords();
- setState(() => 1);
- });
- final frameWidget = ListView(children: [
- form,
- if (tabBar != null) tabBar,
- SizedBox(height: padding),
- SizedBox(width: double.infinity, child: table),
- ]);
- return frameWidget;
- }
-
- @override
- void didChangeDependencies() {
- super.didChangeDependencies();
- requestRecords();
- }
-
- @override
- void dispose() {
- helperDummyUsage(DataType.string);
- globalWidgetDummyUsage();
- textController.dispose();
- super.dispose();
- }
-
- @override
- void initState() {
- super.initState();
- }
-
- void requestRecords() =>
- _futureDbData = globalData.restPersistence.query(what: 'query', data: {
- 'module': 'Structures',
- 'sql': 'list',
- 'offset': _fieldData.theOffset,
- 'size': _fieldData.thePageSize,
- ':text': _fieldData.text,
- });
-
- void search() {
- attendedPage.pageStates.dbDataState.clear();
- if (_formKey.currentState != null && _formKey.currentState!.validate()) {
- _formKey.currentState!.save();
- requestRecords();
- setState(() => 1);
- }
- }
-}
-
-class _FieldData {
- int thePageSize = 10;
- int theOffset = 0;
- String text = '';
-}
+++ /dev/null
-// DO NOT CHANGE. This file is created by the meta_tool!
-import 'package:flutter/material.dart';
-
-import '../../meta/structures_meta.dart';
-import '../../setting/global_data.dart';
-import '../../widget/attended_page.dart';
-import 'list_structure_custom.dart';
-
-class ListStructurePage extends StatefulWidget {
- final PageStates pageStates = PageStates();
- ListStructurePage() : super();
- @override
- _ListStructurePageState createState() {
- final rc = _ListStructurePageState();
- rc.attendedPage = AttendedPage(
- this,
- rc,
- GlobalData(),
- StructuresMeta.instance.pageByName('list')!,
- StructuresMeta.instance,
- pageStates,
- (afterReload, rebuild) =>
- rc.reload(afterReload: afterReload, rebuild: rebuild));
- pageStates.attendedPage = rc.attendedPage;
- return rc;
- }
-}
-
-class _ListStructurePageState extends ListStructureCustom {
- _ListStructurePageState() : super();
- @override
- void didChangeDependencies() {
- final size = MediaQuery.of(context).size;
- attendedPage.pageStates.screenWidth = size.width;
- attendedPage.pageStates.screenHeight = size.height;
- super.didChangeDependencies();
- }
-
- /// Renders the widget tree again.
- ///
- /// [afterReload] is a function used as parameter of setState().
- ///
- /// If [rebuild] is true the state has been changed and didChangeDependencies()
- /// will be called.
- void reload({Function? afterReload, bool rebuild = false}) {
- if (afterReload == null) {
- if (rebuild) {
- setState(() => didChangeDependencies());
- } else {
- setState(() => 1);
- }
- } else {
- setState(() {
- afterReload();
- if (rebuild) {
- didChangeDependencies();
- }
- });
- }
- }
-}
+++ /dev/null
-// DO NOT CHANGE. This file is created by the meta_tool
-import '../../base/defines.dart';
-import '../../base/helper.dart';
-import '../../persistence/data_record.dart';
-
-class StructureData extends DataRecord<int> {
- int? id;
- String? scope;
- String? name;
- String? value;
- int? position;
- DateTime? createdAt;
- String? createdBy;
- DateTime? changedAt;
- String? changedBy;
- StructureData(
- {this.id,
- this.scope,
- this.name,
- this.value,
- this.position,
- this.createdAt,
- this.createdBy,
- this.changedAt,
- this.changedBy});
- StructureData.createFromMap(DataMap map) {
- fromMap(map);
- }
- @override
- void fromMap(DataMap map) {
- id = map.containsKey('structure_id')
- ? fromString(map['structure_id'], dataType: DataType.reference)
- : null;
- scope = map.containsKey('structure_scope')
- ? fromString(map['structure_scope'], dataType: DataType.string)
- : null;
- name = map.containsKey('structure_name')
- ? fromString(map['structure_name'], dataType: DataType.string)
- : null;
- value = map.containsKey('structure_value')
- ? fromString(map['structure_value'], dataType: DataType.string)
- : null;
- position = map.containsKey('structure_position')
- ? fromString(map['structure_position'], dataType: DataType.int)
- : null;
- createdAt = map.containsKey('structure_createdat')
- ? fromString(map['structure_createdat'], dataType: DataType.datetime)
- : null;
- createdBy = map.containsKey('structure_createdby')
- ? fromString(map['structure_createdby'], dataType: DataType.string)
- : null;
- changedAt = map.containsKey('structure_changedat')
- ? fromString(map['structure_changedat'], dataType: DataType.datetime)
- : null;
- changedBy = map.containsKey('structure_changedby')
- ? fromString(map['structure_changedby'], dataType: DataType.string)
- : null;
- }
-
- @override
- int keyOf() {
- return id ?? 0;
- }
-
- @override
- String nameOfKey() {
- return 'structure_id';
- }
-
- static DataType? dataTypeOf(String name) {
- DataType? rc;
- switch (name) {
- case 'id':
- rc = DataType.reference;
- break;
- case 'scope':
- rc = DataType.string;
- break;
- case 'name':
- rc = DataType.string;
- break;
- case 'value':
- rc = DataType.string;
- break;
- case 'position':
- rc = DataType.int;
- break;
- case 'createdAt':
- rc = DataType.datetime;
- break;
- case 'createdBy':
- rc = DataType.string;
- break;
- case 'changedAt':
- rc = DataType.datetime;
- break;
- case 'changedBy':
- rc = DataType.string;
- break;
- default:
- break;
- }
- return rc;
- }
-
- @override
- DataMap toMap({DataMap? map, bool clear = true}) {
- map ??= DataMap();
- if (clear) {
- map.clear();
- }
- map['structure_id'] = id;
- map['structure_scope'] = scope;
- map['structure_name'] = name;
- map['structure_value'] = value;
- map['structure_position'] = position;
- map['structure_createdat'] = createdAt;
- map['structure_createdby'] = createdBy;
- map['structure_changedat'] = changedAt;
- map['structure_changedby'] = changedBy;
- return map;
- }
-}
class _CreateUserPageState extends CreateUserCustom {
_CreateUserPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _DeleteUserPageState extends DeleteUserCustom {
_DeleteUserPageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _EditUserPageState extends EditUserCustom {
_EditUserPageState(int primaryKey) : super(primaryKey);
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
class _ListUserPageState extends ListUserCustom {
_ListUserPageState() : super();
+
@override
void didChangeDependencies() {
final size = MediaQuery.of(context).size;
});
}
}
-}
+}
\ No newline at end of file
import '../../base/defines.dart';
import '../../base/helper.dart';
import '../../persistence/data_record.dart';
-
class UserData extends DataRecord<int> {
int? id;
String? name;
String? displayName;
String? email;
int? role;
+ int? status;
DateTime? createdAt;
String? createdBy;
DateTime? changedAt;
String? changedBy;
+
UserData(
{this.id,
this.name,
this.displayName,
this.email,
this.role,
+ this.status,
this.createdAt,
this.createdBy,
this.changedAt,
this.changedBy});
+
UserData.createFromMap(DataMap map) {
fromMap(map);
}
+
@override
void fromMap(DataMap map) {
id = map.containsKey('user_id')
role = map.containsKey('user_role')
? fromString(map['user_role'], dataType: DataType.reference)
: null;
+ status = map.containsKey('user_status')
+ ? fromString(map['user_status'], dataType: DataType.reference)
+ : null;
createdAt = map.containsKey('user_createdat')
? fromString(map['user_createdat'], dataType: DataType.datetime)
: null;
case 'role':
rc = DataType.reference;
break;
+ case 'status':
+ rc = DataType.reference;
+ break;
case 'createdAt':
rc = DataType.datetime;
break;
}
return rc;
}
-
@override
DataMap toMap({DataMap? map, bool clear = true}) {
map ??= DataMap();
map['user_displayname'] = displayName;
map['user_email'] = email;
map['user_role'] = role;
+ map['user_status'] = status;
map['user_createdat'] = createdAt;
map['user_createdby'] = createdBy;
map['user_changedat'] = changedAt;
{'module': 'global', 'sql': 'comboRoles'}, onDone);
}
+/// Returns the combobox items filled with data of the table users.
+///
+/// [textUndefined]: null: no additional entry. Otherwise: a additional entry is
+/// inserted at position 0 with this text and the value 0.
+///
+/// [attendedPage]: the context of the calling page.
+///
+/// Returns a list of combobox items selecting a user.
+List<DropdownMenuItem<int>>? comboUsers(
+ String textUndefined, AttendedPage attendedPage) {
+ final rc = _combo('comboUsers.global', 'user_id', 'user_displayname',
+ textUndefined, attendedPage);
+ return rc;
+}
+
+/// Requests the database data for combo boxes from the backend.
+///
+/// [dbDataState]: Stores the request and the answer of the request.
+///
+/// [onDone]: A method executed after arriving the response.
+void comboUsersFromBackend(
+ {required AttendedPage attendedPage, required Function() onDone}) {
+ _requestData('comboUsers.global', attendedPage,
+ {'module': 'global', 'sql': 'comboActiveUsers'}, onDone);
+}
+
/// This function is only used to avoid compiler warning "unused import"
/// for generated code.
void globalWidgetDummyUsage() {
#! /bin/bash
APP=meta_tool
OUT=$(dirname $(pwd))/tools
-/usr/bin/dart compile exe bin/$APP.dart -o $OUT/$APP
+dart compile exe bin/$APP.dart -o $OUT/$APP
content = fileSync.fileAsString(fn);
expect(content.replaceAll(RegExp(r'Date: 2[-+\w2: ]+'), 'Date: *'),
r'''# Texts of module Statistic, created by i18n_text_parser');
-# Copyright (C) 2021-2021 J. Hamatoma <cr@hamatoma.de>
+# Copyright (C) 2021-2022 J. Hamatoma <cr@hamatoma.de>
# License: CC0 1.0 Universal
-# J. Hamatoma <author@hamatoma.de>, 2021.
+# J. Hamatoma <author@hamatoma.de>, 2022.
#
#, fuzzy
msgid ""
final content = fileSync.fileAsString(fn);
expect(content.replaceAll(RegExp(r'Date: 2[-+\w2: ]+'), 'Date: *'),
r'''# Texts of module Statistic, created by i18n_text_parser');
-# Copyright (C) 2021-2021 J. Hamatoma <cr@hamatoma.de>
+# Copyright (C) 2021-2022 J. Hamatoma <cr@hamatoma.de>
# License: CC0 1.0 Universal
-# J. Hamatoma <author@hamatoma.de>, 2021.
+# J. Hamatoma <author@hamatoma.de>, 2022.
#
#, fuzzy
msgid ""
--- /dev/null
+import 'package:dart_bones/dart_bones.dart';
+import 'package:exhibition/base/i18n.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import '../lib/base/validators.dart';
+
+I18N i18n = I18N.internal(MemoryLogger());
+
+void main() {
+ final logger = MemoryLogger(LEVEL_FINE);
+ i18n = I18N.internal(logger);
+ test('isEmail', () {
+ expect(isEmail('info@hamatoma.de'), isNull);
+ expect(isEmail('/info@hamatoma.de'), matches(RegExp('"/"')));
+ expect(isEmail('info@hamatoma,de'), matches(RegExp('","')));
+ expect(isEmail('info@hamatoma'), isNotNull);
+ expect(isEmail('x@info@hamatoma'), isNotNull);
+ expect(isEmail('x@info@hamatoma.de'), matches(RegExp('"@"')));
+ });
+ test('isInt', () {
+ expect(isInt('1234'), isNull);
+ expect(isInt('0'), isNull);
+ expect(isInt('-330'), isNull);
+ expect(isInt('+330'), isNull);
+ expect(isInt('.123'), isNotNull);
+ expect(isInt('3D'), isNotNull);
+ expect(isInt(''), isNotNull);
+ expect(isInt(null), isNotNull);
+ });
+ test('isNat', () {
+ expect(isNat('1234'), isNull);
+ expect(isNat('0'), isNull);
+ expect(isNat('-330'), isNotNull);
+ expect(isNat('+330'), isNotNull);
+ expect(isNat('.123'), isNotNull);
+ expect(isNat('3D'), isNotNull);
+ expect(isNat(''), isNotNull);
+ expect(isNat(null), isNotNull);
+ });
+ test('isTime', () {
+ expect(isTime('0'), isNull);
+ expect(isTime('1'), isNull);
+ expect(isTime('23'), isNull);
+ expect(isTime('24'), matches('24'));
+ expect(isTime('00:00'), isNull);
+ expect(isTime('00:59'), isNull);
+ expect(isTime('0:3'), isNull);
+ expect(isTime('0:39'), isNull);
+ expect(isTime('23:59'), isNull);
+ expect(isTime('23:59'), isNull);
+ expect(isTime(''), isNotNull);
+ expect(isTime(null), isNotNull);
+ expect(isTime(null, mayBeEmpty: true), isNull);
+ expect(isTime('', mayBeEmpty: true), isNull);
+ });
+ test('notEmpty', () {
+ expect(notEmpty('0'), isNull);
+ expect(notEmpty('abc'), isNull);
+ expect(notEmpty(''), isNotNull);
+ expect(notEmpty(null), isNotNull);
+ });
+}