|
|
|
from random import randint, choice
|
|
|
|
from string import ascii_lowercase
|
|
|
|
|
|
|
|
from models.Account import Account
|
|
|
|
from models.Payment import Payments
|
|
|
|
from models.User import User
|
|
|
|
from scripts.generate_flutter_model import build_class
|
|
|
|
|
|
|
|
|
|
|
|
def mainBuilder(classlist):
|
|
|
|
blist = []
|
|
|
|
for cls in classlist:
|
|
|
|
data = build_class(cls, blist)
|
|
|
|
blist = blist + data[1]
|
|
|
|
clstypeList = [i.__class__.__name__ for i in blist]
|
|
|
|
configlistNames = []
|
|
|
|
for classItem in data[0]:
|
|
|
|
saveAction = ""
|
|
|
|
|
|
|
|
imports = "import 'package:flutter/material.dart';\n"
|
|
|
|
imports += "import 'package:flutter/services.dart';\n"
|
|
|
|
imports += "import 'package:dio/dio.dart';\n"
|
|
|
|
imports += "import 'package:horde/widgets/HorusBox.dart';\n"
|
|
|
|
imports += "import 'package:dropdown_search/dropdown_search.dart';\n"
|
|
|
|
imports += "import '../Models.dart';\n"
|
|
|
|
controller = ""
|
|
|
|
controllerInit = ""
|
|
|
|
controllerDispose = ""
|
|
|
|
textFields = ""
|
|
|
|
for field in classItem.get('fields'):
|
|
|
|
if field.get('name') == "id":
|
|
|
|
continue
|
|
|
|
if field.get('autogen'):
|
|
|
|
continue
|
|
|
|
controller += "\tTextEditingController _{};\n".format(field.get('name'))
|
|
|
|
controllerInit += "\t\t_{} = new TextEditingController();\n".format(field.get('name'))
|
|
|
|
controllerDispose += "\t\t_{}.dispose();\n".format(field.get('name'))
|
|
|
|
req = ""
|
|
|
|
if field.get('required'):
|
|
|
|
req = """
|
|
|
|
validator: (value) {
|
|
|
|
if (value.isEmpty) {
|
|
|
|
return 'Please enter some text';
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
},
|
|
|
|
"""
|
|
|
|
if field.get("is_class"):
|
|
|
|
|
|
|
|
# imports += "import 'package:adunationfe/data/models/{}.dart';\n".format(field.get('class_name'))
|
|
|
|
if field.get('islist'):
|
|
|
|
if field.get('embeded') == False:
|
|
|
|
controller += "\t\tList<{classname}> item{name};\n".format(
|
|
|
|
classname=field.get('class_name'),
|
|
|
|
name=field.get('name'))
|
|
|
|
controllerInit += "\t\t\titem{name} = [];\n".format(name=field.get('name'))
|
|
|
|
saveAction += "\t\tnew{classname}.{name} = item{name};\n".format(name=field.get('name'),
|
|
|
|
classname=classItem.get(
|
|
|
|
'class'))
|
|
|
|
else:
|
|
|
|
imports += "import 'Form{}.dart';\n".format(
|
|
|
|
field.get('class_name'))
|
|
|
|
if field.get('class_name') not in configlistNames:
|
|
|
|
clsname = field.get('class_name')
|
|
|
|
configlistNames.append(field.get('class_name'))
|
|
|
|
else:
|
|
|
|
clsname = field.get('class_name') + ''.join(
|
|
|
|
[choice(ascii_lowercase) for i in range(randint(3, 6))])
|
|
|
|
while clsname in configlistNames:
|
|
|
|
clsname = field.get('class_name') + ''.join(
|
|
|
|
[choice(ascii_lowercase) for i in range(randint(3, 6))])
|
|
|
|
configlistNames.append(clsname)
|
|
|
|
saveAction += "\t\tnew{classname}.{name} = item{clist}List;\n".format(clist=clsname,
|
|
|
|
name=field.get(
|
|
|
|
'name'),
|
|
|
|
classname=classItem.get(
|
|
|
|
'class'))
|
|
|
|
controller += """
|
|
|
|
List<{originclass}> item{classname}List = [];
|
|
|
|
|
|
|
|
""".format(originclass=field.get("class_name"), classname=clsname)
|
|
|
|
textFields += """
|
|
|
|
Padding(padding: EdgeInsets.only(left:40,right: 40),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Text('{cname} list'),
|
|
|
|
Column(
|
|
|
|
children: List.generate(item{clsname}List.length, (index) {{
|
|
|
|
return HorusBox(
|
|
|
|
child:
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
Expanded(child: Text(item{clsname}List[index].name)),
|
|
|
|
GestureDetector(
|
|
|
|
onTap: () {{
|
|
|
|
item{clsname}List.removeAt(index);
|
|
|
|
setState(() {{
|
|
|
|
}});
|
|
|
|
}},
|
|
|
|
child: Icon(Icons.delete),
|
|
|
|
)
|
|
|
|
|
|
|
|
],
|
|
|
|
)
|
|
|
|
,
|
|
|
|
);
|
|
|
|
}}),
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
ElevatedButton(onPressed: ()
|
|
|
|
{{
|
|
|
|
_showMaterialDialog(SingleChildScrollView(child:Container(width:500,height:500,child:new Form{classname}(onSave: ({classname} item) {{
|
|
|
|
item{clsname}List.add(item);
|
|
|
|
Navigator.pop(context);
|
|
|
|
setState(() {{
|
|
|
|
}});
|
|
|
|
}}))),"Create {cname}");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}}, child: Text('Add {cname}')),
|
|
|
|
SizedBox(
|
|
|
|
height: 15,
|
|
|
|
),
|
|
|
|
|
|
|
|
""".format(classname=field.get('class_name'), cname=field.get('name'), clsname=clsname)
|
|
|
|
elif field.get("embeded") == False:
|
|
|
|
controller += "\t\t{classname} item{name};\n".format(classname=field.get('class_name'),
|
|
|
|
name=field.get('name'))
|
|
|
|
saveAction += "\t\tnew{classname}.{name} = item{name};\n".format(name=field.get('name'),
|
|
|
|
classname=classItem.get(
|
|
|
|
'class'))
|
|
|
|
|
|
|
|
controllerInit += "\t\t\titem{name} = {classname}();\n".format(
|
|
|
|
classname=field.get('class_name'),
|
|
|
|
name=field.get('name'))
|
|
|
|
|
|
|
|
controller += "\t\tList<{classname}> {cname}List = [];".format(
|
|
|
|
classname=field.get('class_name'), cname=field.get('name'))
|
|
|
|
|
|
|
|
controller += """
|
|
|
|
Future<List<{classname}>> getData{classname}(filter) async {{
|
|
|
|
print(filter);
|
|
|
|
var response = await Dio().get(
|
|
|
|
"${{apiurl}}/{cname}",
|
|
|
|
queryParameters: {{"{search}__contains": filter}},
|
|
|
|
);
|
|
|
|
List<{classname}> models = [];
|
|
|
|
response.data.forEach((element) {{
|
|
|
|
{classname} cn = {classname}();
|
|
|
|
cn.name = element['{search}'];
|
|
|
|
models.add(cn);
|
|
|
|
}});
|
|
|
|
|
|
|
|
return models;
|
|
|
|
}}
|
|
|
|
""".format(classname=field.get('class_name'), cname=field.get('name'),
|
|
|
|
search=field.get('search_field'))
|
|
|
|
textFields += """
|
|
|
|
DropdownSearch<{classname}>(
|
|
|
|
mode: Mode.BOTTOM_SHEET,
|
|
|
|
showSearchBox: true,
|
|
|
|
onFind: (String filter) => getData{classname}(filter),
|
|
|
|
items: [],
|
|
|
|
itemAsString: ({classname} u) => u.{search},
|
|
|
|
isFilteredOnline: true,
|
|
|
|
autoValidateMode: AutovalidateMode.onUserInteraction,
|
|
|
|
validator: ({classname} u) =>
|
|
|
|
u == null ? "field is required " : null,
|
|
|
|
hint: "{cname} in menu mode",
|
|
|
|
onChanged: ({classname} selected) {{
|
|
|
|
item{cname} = selected;
|
|
|
|
setState(() {{
|
|
|
|
}});
|
|
|
|
}}),
|
|
|
|
SizedBox(
|
|
|
|
height: 15,
|
|
|
|
),
|
|
|
|
""".format(classname=field.get('class_name'), cname=field.get('name'),
|
|
|
|
search=field.get('search_field'))
|
|
|
|
elif field.get("embeded"):
|
|
|
|
imports += "import 'Form{}.dart';\n".format(
|
|
|
|
field.get('class_name'))
|
|
|
|
saveAction += "\t\tif(!_key{classname}.currentState.build{classname}()) return false;\n".format(
|
|
|
|
classname=field.get('class_name'))
|
|
|
|
saveAction += "\t\tnew{cname}.{name} = _key{classname}.currentState.new{classname};\n".format(
|
|
|
|
classname=field.get('class_name'), name=field.get('name'), cname=classItem.get('class'))
|
|
|
|
|
|
|
|
textFields += "Form{classname}(key:_key{classname}),".format(classname=field.get('class_name'))
|
|
|
|
controller += "\tGlobalKey<Form{}State> _key{} = GlobalKey();\n".format(field.get('class_name'),
|
|
|
|
field.get('class_name'))
|
|
|
|
elif field.get('choices'):
|
|
|
|
saveAction += "\t\tnew{classname}.{name} = _{name}.text;\n".format(name=field.get('name'),
|
|
|
|
classname=classItem.get('class'))
|
|
|
|
|
|
|
|
imports += "import 'package:dropdown_search/dropdown_search.dart';\n"
|
|
|
|
textFields += """
|
|
|
|
DropdownSearch<String>(
|
|
|
|
mode: Mode.BOTTOM_SHEET,
|
|
|
|
showClearButton: true,
|
|
|
|
showSearchBox: true,
|
|
|
|
label: '{name}',
|
|
|
|
showSelectedItem: true,
|
|
|
|
items: ['{items}'],
|
|
|
|
hint: "country in menu mode",
|
|
|
|
onChanged: print,
|
|
|
|
selectedItem: "")
|
|
|
|
,
|
|
|
|
SizedBox(
|
|
|
|
height: 15,
|
|
|
|
),
|
|
|
|
""".format(items="','".join(field.get('choices')), name=field.get('name'))
|
|
|
|
elif field.get('type') == 'String':
|
|
|
|
saveAction += "\t\tnew{classname}.{name} = _{name}.text;\n".format(name=field.get('name'),
|
|
|
|
classname=classItem.get('class'))
|
|
|
|
|
|
|
|
textFields += """
|
|
|
|
new TextFormField(
|
|
|
|
decoration: new InputDecoration(labelText: "Enter your {name}"),
|
|
|
|
controller: _{name},
|
|
|
|
{req}
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
height: 15,
|
|
|
|
),
|
|
|
|
""".format(name=field.get('name'), req=req)
|
|
|
|
elif field.get('type') == 'int':
|
|
|
|
saveAction += "\t\tnew{classname}.{name} = int.tryParse(_{name}.text);\n".format(
|
|
|
|
name=field.get('name'),
|
|
|
|
classname=classItem.get('class'))
|
|
|
|
|
|
|
|
textFields += """
|
|
|
|
new TextFormField(
|
|
|
|
decoration: new InputDecoration(labelText: "Enter your {name}"),
|
|
|
|
controller: _{name},
|
|
|
|
keyboardType: TextInputType.number,
|
|
|
|
inputFormatters: < TextInputFormatter > [
|
|
|
|
FilteringTextInputFormatter.digitsOnly
|
|
|
|
],
|
|
|
|
{req}
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
height: 15,
|
|
|
|
),
|
|
|
|
""".format(name=field.get('name'), req=req)
|
|
|
|
# elif field.get('is_class'):
|
|
|
|
# print(field)
|
|
|
|
# # exit()
|
|
|
|
|
|
|
|
cls_text = """
|
|
|
|
{imports}
|
|
|
|
class Form{classname} extends StatefulWidget {{
|
|
|
|
final Function onSave;
|
|
|
|
|
|
|
|
|
|
|
|
const Form{classname}({{Key key, this.onSave}}) : super(key: key);
|
|
|
|
@override
|
|
|
|
Form{classname}State createState() => Form{classname}State();
|
|
|
|
}}
|
|
|
|
class Form{classname}State extends State<Form{classname}> {{
|
|
|
|
{controller}
|
|
|
|
var apiurl = "";
|
|
|
|
{classname} new{classname} = new {classname}();
|
|
|
|
|
|
|
|
bool build{classname}() {{
|
|
|
|
if (_{classname}.currentState.validate()) {{
|
|
|
|
{saveact}
|
|
|
|
widget.onSave(new{classname});
|
|
|
|
return true;
|
|
|
|
}}
|
|
|
|
return false;
|
|
|
|
}}
|
|
|
|
_showMaterialDialog(content, title) {{
|
|
|
|
showDialog(
|
|
|
|
context: context,
|
|
|
|
builder: (_) => new AlertDialog(
|
|
|
|
title: new Text(title),
|
|
|
|
content: content,
|
|
|
|
));
|
|
|
|
}}
|
|
|
|
|
|
|
|
final _{classname} = GlobalKey<FormState>();
|
|
|
|
@override
|
|
|
|
void initState() {{
|
|
|
|
{initdata}
|
|
|
|
super.initState();
|
|
|
|
}}
|
|
|
|
@override
|
|
|
|
void dispose() {{
|
|
|
|
{dispose}
|
|
|
|
super.dispose();
|
|
|
|
}}
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {{
|
|
|
|
return new Form(
|
|
|
|
key:_{classname},
|
|
|
|
child:new Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: <Widget>[
|
|
|
|
{textfield}
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
widget.onSave !=null ? ElevatedButton(
|
|
|
|
child: Text('Save'),
|
|
|
|
onPressed: () {{
|
|
|
|
build{classname}();
|
|
|
|
}},
|
|
|
|
): Center()
|
|
|
|
],
|
|
|
|
)
|
|
|
|
])
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
""".format(imports=imports, classname=classItem.get('class'), controller=controller,
|
|
|
|
initdata=controllerInit, dispose=controllerDispose, textfield=textFields, saveact=saveAction)
|
|
|
|
|
|
|
|
f = open("flutter_out/Form{}.dart".format(classItem.get('class')), "w+")
|
|
|
|
f.write(cls_text)
|
|
|
|
f.close()
|
|
|
|
import os
|
|
|
|
os.chdir('../')
|
|
|
|
print(os.getcwd())
|
|
|
|
mainBuilder([User, Payments, Account])
|
|
|
|
os.system("flutter format flutter_out/")
|