flask-appbuilder 3.2.1__py3-none-any.whl → 5.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. flask_appbuilder/__init__.py +2 -3
  2. flask_appbuilder/_compat.py +0 -1
  3. flask_appbuilder/actions.py +14 -14
  4. flask_appbuilder/api/__init__.py +741 -527
  5. flask_appbuilder/api/convert.py +104 -98
  6. flask_appbuilder/api/manager.py +14 -8
  7. flask_appbuilder/api/schemas.py +12 -1
  8. flask_appbuilder/babel/manager.py +12 -16
  9. flask_appbuilder/base.py +353 -280
  10. flask_appbuilder/basemanager.py +1 -1
  11. flask_appbuilder/baseviews.py +241 -164
  12. flask_appbuilder/charts/jsontools.py +10 -10
  13. flask_appbuilder/charts/views.py +56 -60
  14. flask_appbuilder/cli.py +115 -70
  15. flask_appbuilder/const.py +52 -52
  16. flask_appbuilder/exceptions.py +67 -5
  17. flask_appbuilder/fields.py +32 -23
  18. flask_appbuilder/fieldwidgets.py +34 -27
  19. flask_appbuilder/filemanager.py +33 -45
  20. flask_appbuilder/filters.py +11 -13
  21. flask_appbuilder/forms.py +31 -35
  22. flask_appbuilder/hooks.py +90 -0
  23. flask_appbuilder/menu.py +35 -10
  24. flask_appbuilder/models/base.py +47 -57
  25. flask_appbuilder/models/decorators.py +13 -13
  26. flask_appbuilder/models/filters.py +42 -38
  27. flask_appbuilder/models/generic/__init__.py +29 -29
  28. flask_appbuilder/models/generic/filters.py +11 -3
  29. flask_appbuilder/models/generic/interface.py +1 -3
  30. flask_appbuilder/models/group.py +37 -39
  31. flask_appbuilder/models/mixins.py +22 -18
  32. flask_appbuilder/models/sqla/__init__.py +19 -72
  33. flask_appbuilder/models/sqla/base.py +24 -0
  34. flask_appbuilder/models/sqla/base_legacy.py +132 -0
  35. flask_appbuilder/models/sqla/filters.py +132 -19
  36. flask_appbuilder/models/sqla/interface.py +390 -276
  37. flask_appbuilder/security/api.py +31 -35
  38. flask_appbuilder/security/decorators.py +181 -83
  39. flask_appbuilder/security/forms.py +20 -31
  40. flask_appbuilder/security/manager.py +715 -489
  41. flask_appbuilder/security/registerviews.py +29 -112
  42. flask_appbuilder/security/schemas.py +43 -0
  43. flask_appbuilder/security/sqla/apis/__init__.py +8 -0
  44. flask_appbuilder/security/sqla/apis/group/__init__.py +1 -0
  45. flask_appbuilder/security/sqla/apis/group/api.py +227 -0
  46. flask_appbuilder/security/sqla/apis/group/schema.py +73 -0
  47. flask_appbuilder/security/sqla/apis/permission/__init__.py +1 -0
  48. flask_appbuilder/security/sqla/apis/permission/api.py +19 -0
  49. flask_appbuilder/security/sqla/apis/permission_view_menu/__init__.py +1 -0
  50. flask_appbuilder/security/sqla/apis/permission_view_menu/api.py +16 -0
  51. flask_appbuilder/security/sqla/apis/role/__init__.py +1 -0
  52. flask_appbuilder/security/sqla/apis/role/api.py +306 -0
  53. flask_appbuilder/security/sqla/apis/role/schema.py +27 -0
  54. flask_appbuilder/security/sqla/apis/user/__init__.py +1 -0
  55. flask_appbuilder/security/sqla/apis/user/api.py +292 -0
  56. flask_appbuilder/security/sqla/apis/user/schema.py +97 -0
  57. flask_appbuilder/security/sqla/apis/user/validator.py +27 -0
  58. flask_appbuilder/security/sqla/apis/view_menu/__init__.py +1 -0
  59. flask_appbuilder/security/sqla/apis/view_menu/api.py +18 -0
  60. flask_appbuilder/security/sqla/manager.py +421 -203
  61. flask_appbuilder/security/sqla/models.py +192 -57
  62. flask_appbuilder/security/utils.py +9 -0
  63. flask_appbuilder/security/views.py +232 -229
  64. flask_appbuilder/static/.DS_Store +0 -0
  65. flask_appbuilder/static/appbuilder/css/ab.css +20 -12
  66. flask_appbuilder/static/appbuilder/css/bootstrap-datepicker/bootstrap-datepicker3.min.css +7 -0
  67. flask_appbuilder/static/appbuilder/css/bootstrap.min.css.map +1 -0
  68. flask_appbuilder/static/appbuilder/css/flags/flags16.css +249 -245
  69. flask_appbuilder/static/appbuilder/css/fontawesome/all.min.css +6 -0
  70. flask_appbuilder/static/appbuilder/css/fontawesome/brands.min.css +6 -0
  71. flask_appbuilder/static/appbuilder/css/fontawesome/fontawesome.min.css +6 -0
  72. flask_appbuilder/static/appbuilder/css/fontawesome/regular.min.css +6 -0
  73. flask_appbuilder/static/appbuilder/css/fontawesome/solid.min.css +6 -0
  74. flask_appbuilder/static/appbuilder/css/fontawesome/svg-with-js.min.css +6 -0
  75. flask_appbuilder/static/appbuilder/css/fontawesome/v4-font-face.min.css +6 -0
  76. flask_appbuilder/static/appbuilder/css/fontawesome/v4-shims.min.css +6 -0
  77. flask_appbuilder/static/appbuilder/css/fontawesome/v5-font-face.min.css +6 -0
  78. flask_appbuilder/static/appbuilder/css/images/flags16.png +0 -0
  79. flask_appbuilder/static/appbuilder/css/select2/select2-bootstrap.min.css +7 -0
  80. flask_appbuilder/static/appbuilder/css/select2/select2.min.css +1 -0
  81. flask_appbuilder/static/appbuilder/css/swagger/swagger-ui.css +3 -0
  82. flask_appbuilder/static/appbuilder/css/webfonts/fa-brands-400.ttf +0 -0
  83. flask_appbuilder/static/appbuilder/css/webfonts/fa-brands-400.woff2 +0 -0
  84. flask_appbuilder/static/appbuilder/css/webfonts/fa-regular-400.ttf +0 -0
  85. flask_appbuilder/static/appbuilder/css/webfonts/fa-regular-400.woff2 +0 -0
  86. flask_appbuilder/static/appbuilder/css/webfonts/fa-solid-900.ttf +0 -0
  87. flask_appbuilder/static/appbuilder/css/webfonts/fa-solid-900.woff2 +0 -0
  88. flask_appbuilder/static/appbuilder/css/webfonts/fa-v4compatibility.ttf +0 -0
  89. flask_appbuilder/static/appbuilder/css/webfonts/fa-v4compatibility.woff2 +0 -0
  90. flask_appbuilder/static/appbuilder/js/ab.js +33 -23
  91. flask_appbuilder/static/appbuilder/js/ab_filters.js +91 -84
  92. flask_appbuilder/static/appbuilder/js/bootstrap-datepicker/bootstrap-datepicker.min.js +8 -0
  93. flask_appbuilder/static/appbuilder/js/jquery-latest.js +2 -2
  94. flask_appbuilder/static/appbuilder/js/select2/select2.min.js +2 -0
  95. flask_appbuilder/static/appbuilder/js/swagger-ui-bundle.js +3 -0
  96. flask_appbuilder/templates/appbuilder/baselib.html +9 -3
  97. flask_appbuilder/templates/appbuilder/general/lib.html +60 -34
  98. flask_appbuilder/templates/appbuilder/general/model/edit.html +1 -1
  99. flask_appbuilder/templates/appbuilder/general/model/edit_cascade.html +1 -1
  100. flask_appbuilder/templates/appbuilder/general/model/search.html +3 -2
  101. flask_appbuilder/templates/appbuilder/general/model/show.html +1 -1
  102. flask_appbuilder/templates/appbuilder/general/model/show_cascade.html +1 -1
  103. flask_appbuilder/templates/appbuilder/general/security/login_db.html +7 -7
  104. flask_appbuilder/templates/appbuilder/general/security/login_ldap.html +5 -5
  105. flask_appbuilder/templates/appbuilder/general/security/login_oauth.html +24 -49
  106. flask_appbuilder/templates/appbuilder/general/widgets/base_list.html +2 -1
  107. flask_appbuilder/templates/appbuilder/general/widgets/chart.html +4 -2
  108. flask_appbuilder/templates/appbuilder/general/widgets/direct_chart.html +4 -3
  109. flask_appbuilder/templates/appbuilder/general/widgets/multiple_chart.html +3 -2
  110. flask_appbuilder/templates/appbuilder/general/widgets/search.html +11 -10
  111. flask_appbuilder/templates/appbuilder/init.html +37 -43
  112. flask_appbuilder/templates/appbuilder/navbar_menu.html +1 -1
  113. flask_appbuilder/templates/appbuilder/navbar_right.html +2 -2
  114. flask_appbuilder/templates/appbuilder/swagger/swagger.html +22 -19
  115. flask_appbuilder/translations/de/LC_MESSAGES/messages.mo +0 -0
  116. flask_appbuilder/translations/de/LC_MESSAGES/messages.po +305 -161
  117. flask_appbuilder/translations/fa/LC_MESSAGES/messages.mo +0 -0
  118. flask_appbuilder/translations/fa/LC_MESSAGES/messages.po +802 -0
  119. flask_appbuilder/translations/fr/LC_MESSAGES/messages.po +461 -319
  120. flask_appbuilder/translations/pt_BR/LC_MESSAGES/messages.po +650 -650
  121. flask_appbuilder/translations/ru/LC_MESSAGES/messages.po +1 -1
  122. flask_appbuilder/translations/sl/LC_MESSAGES/messages.mo +0 -0
  123. flask_appbuilder/translations/sl/LC_MESSAGES/messages.po +690 -0
  124. flask_appbuilder/translations/tr/LC_MESSAGES/messages.mo +0 -0
  125. flask_appbuilder/translations/tr/LC_MESSAGES/messages.po +1015 -0
  126. flask_appbuilder/upload.py +20 -22
  127. flask_appbuilder/urltools.py +39 -19
  128. flask_appbuilder/utils/base.py +76 -0
  129. flask_appbuilder/utils/legacy.py +33 -0
  130. flask_appbuilder/utils/limit.py +20 -0
  131. flask_appbuilder/validators.py +73 -14
  132. flask_appbuilder/views.py +75 -424
  133. flask_appbuilder/widgets.py +50 -51
  134. {Flask_AppBuilder-3.2.1.dist-info → flask_appbuilder-5.0.2.dist-info}/METADATA +36 -76
  135. flask_appbuilder-5.0.2.dist-info/RECORD +240 -0
  136. {Flask_AppBuilder-3.2.1.dist-info → flask_appbuilder-5.0.2.dist-info}/WHEEL +1 -1
  137. flask_appbuilder-5.0.2.dist-info/entry_points.txt +2 -0
  138. Flask_AppBuilder-3.2.1.dist-info/RECORD +0 -270
  139. Flask_AppBuilder-3.2.1.dist-info/entry_points.txt +0 -6
  140. flask_appbuilder/console.py +0 -426
  141. flask_appbuilder/models/mongoengine/__init__.py +0 -0
  142. flask_appbuilder/models/mongoengine/fields.py +0 -65
  143. flask_appbuilder/models/mongoengine/filters.py +0 -145
  144. flask_appbuilder/models/mongoengine/interface.py +0 -328
  145. flask_appbuilder/security/mongoengine/__init__.py +0 -0
  146. flask_appbuilder/security/mongoengine/manager.py +0 -402
  147. flask_appbuilder/security/mongoengine/models.py +0 -120
  148. flask_appbuilder/static/appbuilder/css/font-awesome.min.css +0 -4
  149. flask_appbuilder/static/appbuilder/datepicker/bootstrap-datepicker.css +0 -9
  150. flask_appbuilder/static/appbuilder/datepicker/bootstrap-datepicker.js +0 -28
  151. flask_appbuilder/static/appbuilder/fonts/FontAwesome.otf +0 -0
  152. flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.eot +0 -0
  153. flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.svg +0 -2671
  154. flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.ttf +0 -0
  155. flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.woff +0 -0
  156. flask_appbuilder/static/appbuilder/fonts/fontawesome-webfont.woff2 +0 -0
  157. flask_appbuilder/static/appbuilder/img/aol.png +0 -0
  158. flask_appbuilder/static/appbuilder/img/flags/flags16.png +0 -0
  159. flask_appbuilder/static/appbuilder/img/flickr.png +0 -0
  160. flask_appbuilder/static/appbuilder/img/google.png +0 -0
  161. flask_appbuilder/static/appbuilder/img/myopenid.png +0 -0
  162. flask_appbuilder/static/appbuilder/img/yahoo.png +0 -0
  163. flask_appbuilder/static/appbuilder/js/_google_charts.js +0 -39
  164. flask_appbuilder/static/appbuilder/js/html5shiv.js +0 -8
  165. flask_appbuilder/static/appbuilder/js/respond.min.js +0 -6
  166. flask_appbuilder/static/appbuilder/select2/select2-spinner.gif +0 -0
  167. flask_appbuilder/static/appbuilder/select2/select2.css +0 -1205
  168. flask_appbuilder/static/appbuilder/select2/select2.js +0 -23
  169. flask_appbuilder/static/appbuilder/select2/select2.png +0 -0
  170. flask_appbuilder/static/appbuilder/select2/select2x2.png +0 -0
  171. flask_appbuilder/templates/appbuilder/general/security/login_oid.html +0 -129
  172. flask_appbuilder/templates/appbuilder/general/security/resetpassword.html +0 -29
  173. flask_appbuilder/tests/__init__.py +0 -0
  174. flask_appbuilder/tests/__pycache__/__init__.cpython-36.pyc +0 -0
  175. flask_appbuilder/tests/__pycache__/__init__.cpython-37.pyc +0 -0
  176. flask_appbuilder/tests/__pycache__/_test_auth_ldap.cpython-37.pyc +0 -0
  177. flask_appbuilder/tests/__pycache__/_test_auth_oauth.cpython-37.pyc +0 -0
  178. flask_appbuilder/tests/__pycache__/_test_ldapsearch.cpython-36.pyc +0 -0
  179. flask_appbuilder/tests/__pycache__/_test_oauth_registration_role.cpython-36.pyc +0 -0
  180. flask_appbuilder/tests/__pycache__/base.cpython-36.pyc +0 -0
  181. flask_appbuilder/tests/__pycache__/base.cpython-37.pyc +0 -0
  182. flask_appbuilder/tests/__pycache__/config_api.cpython-36.pyc +0 -0
  183. flask_appbuilder/tests/__pycache__/config_api.cpython-37.pyc +0 -0
  184. flask_appbuilder/tests/__pycache__/const.cpython-36.pyc +0 -0
  185. flask_appbuilder/tests/__pycache__/const.cpython-37.pyc +0 -0
  186. flask_appbuilder/tests/__pycache__/test_0_fixture.cpython-36.pyc +0 -0
  187. flask_appbuilder/tests/__pycache__/test_0_fixture.cpython-37.pyc +0 -0
  188. flask_appbuilder/tests/__pycache__/test_api.cpython-36.pyc +0 -0
  189. flask_appbuilder/tests/__pycache__/test_api.cpython-37.pyc +0 -0
  190. flask_appbuilder/tests/__pycache__/test_fab_cli.cpython-36.pyc +0 -0
  191. flask_appbuilder/tests/__pycache__/test_fab_cli.cpython-37.pyc +0 -0
  192. flask_appbuilder/tests/__pycache__/test_menu.cpython-36.pyc +0 -0
  193. flask_appbuilder/tests/__pycache__/test_menu.cpython-37.pyc +0 -0
  194. flask_appbuilder/tests/__pycache__/test_mongoengine.cpython-36.pyc +0 -0
  195. flask_appbuilder/tests/__pycache__/test_mvc.cpython-36.pyc +0 -0
  196. flask_appbuilder/tests/__pycache__/test_mvc.cpython-37.pyc +0 -0
  197. flask_appbuilder/tests/__pycache__/test_sqlalchemy.cpython-36.pyc +0 -0
  198. flask_appbuilder/tests/__pycache__/test_sqlalchemy.cpython-37.pyc +0 -0
  199. flask_appbuilder/tests/_test_auth_ldap.py +0 -1045
  200. flask_appbuilder/tests/_test_auth_oauth.py +0 -419
  201. flask_appbuilder/tests/_test_ldapsearch.py +0 -135
  202. flask_appbuilder/tests/_test_oauth_registration_role.py +0 -59
  203. flask_appbuilder/tests/app.db +0 -0
  204. flask_appbuilder/tests/base.py +0 -90
  205. flask_appbuilder/tests/config_api.py +0 -21
  206. flask_appbuilder/tests/const.py +0 -9
  207. flask_appbuilder/tests/mongoengine/__init__.py +0 -0
  208. flask_appbuilder/tests/mongoengine/__pycache__/__init__.cpython-36.pyc +0 -0
  209. flask_appbuilder/tests/mongoengine/__pycache__/__init__.cpython-37.pyc +0 -0
  210. flask_appbuilder/tests/mongoengine/__pycache__/models.cpython-36.pyc +0 -0
  211. flask_appbuilder/tests/mongoengine/models.py +0 -41
  212. flask_appbuilder/tests/sqla/__init__.py +0 -0
  213. flask_appbuilder/tests/sqla/__pycache__/__init__.cpython-36.pyc +0 -0
  214. flask_appbuilder/tests/sqla/__pycache__/__init__.cpython-37.pyc +0 -0
  215. flask_appbuilder/tests/sqla/__pycache__/models.cpython-36.pyc +0 -0
  216. flask_appbuilder/tests/sqla/__pycache__/models.cpython-37.pyc +0 -0
  217. flask_appbuilder/tests/sqla/models.py +0 -340
  218. flask_appbuilder/tests/test_0_fixture.py +0 -39
  219. flask_appbuilder/tests/test_api.py +0 -2790
  220. flask_appbuilder/tests/test_fab_cli.py +0 -72
  221. flask_appbuilder/tests/test_menu.py +0 -122
  222. flask_appbuilder/tests/test_mongoengine.py +0 -572
  223. flask_appbuilder/tests/test_mvc.py +0 -1710
  224. flask_appbuilder/tests/test_sqlalchemy.py +0 -24
  225. flask_appbuilder/translations/__pycache__/__init__.cpython-36.pyc +0 -0
  226. flask_appbuilder/translations/es/LC_MESSAGES/messages.po~ +0 -582
  227. {Flask_AppBuilder-3.2.1.dist-info → flask_appbuilder-5.0.2.dist-info}/LICENSE +0 -0
  228. {Flask_AppBuilder-3.2.1.dist-info → flask_appbuilder-5.0.2.dist-info}/top_level.txt +0 -0
@@ -21,7 +21,7 @@
21
21
  {% if item1 | is_menu_visible %}
22
22
  {% if item1.childs %}
23
23
  <li class="dropdown">
24
- <a class="dropdown-toggle" data-toggle="dropdown" href="javascript:void(0)">
24
+ <a class="dropdown-toggle" data-toggle="dropdown" href="#">
25
25
  {% if item1.icon %}
26
26
  <i class="fa {{item1.icon}}"></i>&nbsp;
27
27
  {% endif %}
@@ -53,12 +53,12 @@
53
53
  {% endmacro %}
54
54
 
55
55
  {% macro locale_menu(languages) %}
56
- {% set locale = session['locale'] %}
56
+ {% set locale = session.get('locale') %}
57
57
  {% if not locale %}
58
58
  {% set locale = 'en' %}
59
59
  {% endif %}
60
60
  <li class="dropdown">
61
- <a class="dropdown-toggle" data-toggle="dropdown" href="javascript:void(0)">
61
+ <a class="dropdown-toggle" data-toggle="dropdown" href="#">
62
62
  <div class="f16"><i class="flag {{languages[locale].get('flag')}}"></i><b class="caret"></b>
63
63
  </div>
64
64
  </a>
@@ -126,3 +126,9 @@
126
126
  </div>
127
127
  </div>
128
128
  {% endmacro %}
129
+
130
+ {% macro get_nonce() -%}
131
+ {%- if csp_nonce is defined -%}
132
+ {{- csp_nonce() -}}
133
+ {%- endif %}
134
+ {%- endmacro %}
@@ -1,3 +1,5 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
2
+
1
3
  {% macro render_additional_links(additional_links, pk) %}
2
4
  {% if additional_links %}
3
5
  {% for item in additional_links %}
@@ -20,16 +22,27 @@
20
22
  {% endif %}
21
23
  <input type="hidden" id="action" name="action" />
22
24
  </form>
23
-
24
- <a href="javascript:void(0)" class="btn btn-sm btn-primary"
25
- {% if action.confirmation %}
26
- onclick="var a = new AdminActions(); return a.execute_single('{{path}}','{{action.confirmation}}');">
27
- {% else %}
28
- onclick="var a = new AdminActions(); return a.execute_single('{{path}}',false);">
29
- {% endif %}
25
+ <a
26
+ id="btn-action-{{ endpoint }}-{{ action.name }}"
27
+ href="#"
28
+ class="btn btn-sm btn-primary"
29
+ >
30
30
  <i class="fa {{action.icon}}"></i>
31
- {{_(action.text)}}
32
- </a>
31
+ {{_(action.text)}}
32
+ </a>
33
+
34
+ <script nonce="{{ baselib.get_nonce() }}">
35
+ document.getElementById("btn-action-{{ endpoint }}-{{ action.name }}")
36
+ .addEventListener("click", function () {
37
+ {% if action.confirmation %}
38
+ const adminAction = new AdminActions();
39
+ return adminAction.execute_single('{{path}}','{{action.confirmation}}');
40
+ {% else %}
41
+ const adminAction = new AdminActions();
42
+ return adminAction.execute_single('{{path}}',false);
43
+ {% endif %}
44
+ })
45
+ </script>
33
46
  {% endif %}
34
47
  {% endfor %}
35
48
  {% endmacro %}
@@ -66,7 +79,7 @@
66
79
  {% for action_key in actions %}
67
80
  {% set action = actions.get(action_key) %}
68
81
  <li>
69
- <a href="javascript:void(0)"
82
+ <a href="#"
70
83
  class="{{action.name}}_menu_item">
71
84
  <i class="fa {{action.icon}}"></i>
72
85
  {{ _(action.text) }}
@@ -74,7 +87,7 @@
74
87
  </li>
75
88
  {% endfor %}
76
89
  </ul>
77
- <script type="text/javascript">
90
+ <script nonce="{{ baselib.get_nonce() }}">
78
91
  $(document).ready(function() {
79
92
  {% for action_key in actions %}
80
93
  {% set action = actions.get(action_key) %}
@@ -176,7 +189,7 @@
176
189
  </li>
177
190
  {% else %}
178
191
  <li class="disabled">
179
- <a href="javascript:void(0)">&laquo;</a>
192
+ <a href="#">&laquo;</a>
180
193
  </li>
181
194
  {% endif %}
182
195
  {% if page > 0 %}
@@ -185,14 +198,14 @@
185
198
  </li>
186
199
  {% else %}
187
200
  <li class="disabled">
188
- <a href="javascript:void(0)">&lt;</a>
201
+ <a href="#">&lt;</a>
189
202
  </li>
190
203
  {% endif %}
191
204
 
192
205
  {% for p in range(min, max) %}
193
206
  {% if page == p %}
194
207
  <li class="active">
195
- <a href="javascript:void(0)">{{ (p + 1) }}</a>
208
+ <a href="#">{{ (p + 1) }}</a>
196
209
  </li>
197
210
  {% else %}
198
211
  <li>
@@ -207,7 +220,7 @@
207
220
  </li>
208
221
  {% else %}
209
222
  <li class="disabled">
210
- <a href="javascript:void(0)">&gt;</a>
223
+ <a href="#">&gt;</a>
211
224
  </li>
212
225
  {% endif %}
213
226
  {% if max < pages %}
@@ -216,7 +229,7 @@
216
229
  </li>
217
230
  {% else %}
218
231
  <li class="disabled">
219
- <a href="javascript:void(0)">&raquo;</a>
232
+ <a href="#">&raquo;</a>
220
233
  </li>
221
234
  {% endif %}
222
235
  </ul>
@@ -225,22 +238,18 @@
225
238
 
226
239
 
227
240
  {% macro render_field(field, begin_sep_label='', end_sep_label='', begin_sep_field='', end_sep_field='') %}
228
- {% if field.id != 'csrf_token' %}
229
- {% if field.type == 'HiddenField' %}
230
- {{ field}}
231
- {% else %}
232
- {{begin_sep_label|safe}}
233
- <label for="{{field.id}}" control-label>
234
- {{ field.label.text }}
235
- {% if field.flags.required %}
236
- <strong style="color: red">&#42;</strong>
237
- {% endif %}
238
- </label>
239
- {{end_sep_label|safe}}
240
- {{begin_sep_field|safe}}
241
- {{ field(**kwargs)|safe }}
242
- <span class="help-block">{{ field.description }}</span>
243
- {% endif %}
241
+ {% if (field.id != 'csrf_token') and (field.type != 'HiddenField') %}
242
+ {{begin_sep_label|safe}}
243
+ <label for="{{field.id}}" control-label>
244
+ {{ field.label.text }}
245
+ {% if field.flags.required %}
246
+ <strong style="color: red">&#42;</strong>
247
+ {% endif %}
248
+ </label>
249
+ {{end_sep_label|safe}}
250
+ {{begin_sep_field|safe}}
251
+ {{ field(**kwargs)|safe }}
252
+ <span class="help-block">{{ field.description }}</span>
244
253
  {% if field.errors %}
245
254
  <div class="alert alert-danger">
246
255
  {% for error in field.errors %}
@@ -362,6 +371,7 @@
362
371
  {% macro lnk_back() %}
363
372
  <a href="{{url_for('UtilView' + '.back')}}" class="btn btn-sm btn-default" data-toggle="tooltip" rel="tooltip"
364
373
  title="{{_('Back')}}">
374
+ <span class="sr-only">{{ _('Back') }}</span>
365
375
  <i class="fa fa-arrow-left"></i>
366
376
  </a>
367
377
  {% endmacro %}
@@ -370,6 +380,7 @@
370
380
  {% macro lnk_add(my_href) %}
371
381
  <a href="{{my_href}}" class="btn btn-sm btn-primary" data-toggle="tooltip" rel="tooltip"
372
382
  title="{{_('Add a new record')}}">
383
+ <span class="sr-only">{{ _('Add') }}</span>
373
384
  <i class="fa fa-plus"></i>
374
385
  </a>
375
386
  {% endmacro %}
@@ -377,6 +388,7 @@
377
388
  {% macro lnk_edit(my_href) %}
378
389
  <a href="{{my_href}}" class="btn btn-sm btn-default" data-toggle="tooltip" rel="tooltip"
379
390
  title="{{_('Edit record')}}">
391
+ <span class="sr-only">{{ _('Edit') }}</span>
380
392
  <i class="fa fa-edit"></i>
381
393
  </a>
382
394
  {% endmacro %}
@@ -384,13 +396,27 @@
384
396
  {% macro lnk_show(my_href) %}
385
397
  <a href="{{my_href}}" class="btn btn-sm btn-default" data-toggle="tooltip" rel="tooltip"
386
398
  title="{{_('Show record')}}">
399
+ <span class="sr-only">{{ _('Show') }}</span>
387
400
  <i class="fa fa-search"></i>
388
401
  </a>
389
402
  {% endmacro %}
390
403
 
391
404
  {% macro lnk_delete(my_href) %}
392
- <a href="javascript:void(0)" class="btn btn-sm btn-default confirm" rel="tooltip" title="{{_('Delete record')}}"
393
- onclick="var a = new AdminActions(); return a.execute_single_delete('{{my_href}}','{{ _('You sure you want to delete this item?') }}');">
405
+ <a
406
+ id="btn-delete-{{ my_href }}"
407
+ href="#"
408
+ class="btn btn-sm btn-default confirm"
409
+ rel="tooltip"
410
+ title="{{_('Delete record')}}"
411
+ >
412
+ <span class="sr-only">{{ _('Delete') }}</span>
394
413
  <i class="fa fa-trash"></i>
395
414
  </a>
415
+ <script nonce="{{ baselib.get_nonce() }}">
416
+ document.getElementById("btn-delete-{{ my_href }}")
417
+ .addEventListener("click", function () {
418
+ const adminAction = new AdminActions();
419
+ return adminAction.execute_single_delete('{{my_href}}','{{_('Are you sure you want to delete this item?')}}');
420
+ })
421
+ </script>
396
422
  {% endmacro %}
@@ -32,5 +32,5 @@
32
32
  {% endblock %}
33
33
 
34
34
  {% block add_tail_js %}
35
- <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}"></script>
35
+ <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}" nonce="{{ baselib.get_nonce() }}"></script>
36
36
  {% endblock %}
@@ -25,5 +25,5 @@
25
25
  {% endblock %}
26
26
 
27
27
  {% block add_tail_js %}
28
- <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}"></script>
28
+ <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}" nonce="{{ baselib.get_nonce() }}"></script>
29
29
  {% endblock %}
@@ -1,3 +1,5 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
2
+
1
3
  <form class="form-search" action="" method="post">
2
4
  <div class="table-responsive">
3
5
  <table class="table table-condensed"><tr>
@@ -11,7 +13,6 @@
11
13
  </table>
12
14
  </div>
13
15
  </form>
14
- <script>
16
+ <script nonce="{{ baselib.get_nonce() }}">
15
17
  $(".my_select2").prepend("<option value=''></option>");
16
18
  </script>
17
-
@@ -34,5 +34,5 @@
34
34
  {% endblock content %}
35
35
 
36
36
  {% block add_tail_js %}
37
- <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}"></script>
37
+ <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}" nonce="{{ baselib.get_nonce() }}"></script>
38
38
  {% endblock %}
@@ -24,5 +24,5 @@
24
24
  {% endblock %}
25
25
 
26
26
  {% block add_tail_js %}
27
- <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}"></script>
27
+ <script src="{{url_for('appbuilder.static',filename='js/ab_keep_tab.js')}}" nonce="{{ baselib.get_nonce() }}"></script>
28
28
  {% endblock %}
@@ -16,29 +16,29 @@
16
16
  <form class="form" action="" method="post" name="login">
17
17
  {{form.hidden_tag()}}
18
18
  <div class="help-block">{{_("Enter your login and password below")}}:</div>
19
- <div class="control-group{% if form.errors.openid is defined %} error{% endif %}">
20
- <label class="control-label" for="openid">{{_("Username")}}:</label>
19
+ <div class="control-group{% if form.errors.username is defined %} error{% endif %}">
20
+ <label class="control-label" for="username">{{_("Username")}}:</label>
21
21
 
22
22
  <div class="controls">
23
23
  <div class="input-group">
24
24
  <span class="input-group-addon"><i class="fa fa-user"></i></span>
25
25
  {{ form.username(size = 80, class = "form-control", autofocus = true) }}
26
26
  </div>
27
- {% for error in form.errors.get('openid', []) %}
27
+ {% for error in form.errors.get('username', []) %}
28
28
  <span class="help-inline">[{{error}}]</span><br>
29
29
  {% endfor %}
30
- <label class="control-label" for="openid">{{_("Password")}}:</label>
30
+ <label class="control-label" for="password">{{_("Password")}}:</label>
31
31
 
32
32
  <div class="input-group">
33
33
  <span class="input-group-addon"><i class="fa fa-key"></i></span>
34
34
  {{ form.password(size = 80, class = "form-control") }}
35
35
  </div>
36
- {% for error in form.errors.get('openid', []) %}
36
+ {% for error in form.errors.get('password', []) %}
37
37
  <span class="help-inline">[{{error}}]</span><br>
38
38
  {% endfor %}
39
39
  </div>
40
40
  </div>
41
-
41
+
42
42
  <div class="control-group">
43
43
  <div class="controls">
44
44
  <br>
@@ -54,7 +54,7 @@
54
54
  </div>
55
55
  </div>
56
56
  </form>
57
-
57
+
58
58
  </div>
59
59
  </div>
60
60
  </div>
@@ -14,22 +14,22 @@
14
14
  <form class="form" action="" method="post" name="login">
15
15
  {{form.hidden_tag()}}
16
16
  <div class="help-block">{{_("Enter your login and password below")}}:</div>
17
- <div class="control-group{% if form.errors.openid is defined %} error{% endif %}">
18
- <label class="control-label" for="openid">{{_("Username")}}:</label>
17
+ <div class="control-group{% if form.errors.username is defined %} error{% endif %}">
18
+ <label class="control-label" for="username">{{_("Username")}}:</label>
19
19
  <div class="controls">
20
20
  <div class="input-group">
21
21
  <span class="input-group-addon"><i class="fa fa-user"></i></span>
22
22
  {{ form.username(size = 80, class = "form-control", autofocus = true) }}
23
23
  </div>
24
- {% for error in form.errors.get('openid', []) %}
24
+ {% for error in form.errors.get('username', []) %}
25
25
  <span class="help-inline">[{{error}}]</span><br>
26
26
  {% endfor %}
27
- <label class="control-label" for="openid">{{_("Password")}}:</label>
27
+ <label class="control-label" for="password">{{_("Password")}}:</label>
28
28
  <div class="input-group">
29
29
  <span class="input-group-addon"><i class="fa fa-key"></i></span>
30
30
  {{ form.password(size = 80, class = "form-control") }}
31
31
  </div>
32
- {% for error in form.errors.get('openid', []) %}
32
+ {% for error in form.errors.get('password', []) %}
33
33
  <span class="help-inline">[{{error}}]</span><br>
34
34
  {% endfor %}
35
35
  </div>
@@ -3,36 +3,6 @@
3
3
 
4
4
  {% block content %}
5
5
 
6
- <script type="text/javascript">
7
-
8
- var baseLoginUrl = "{{appbuilder.get_url_for_login}}";
9
- var baseRegisterUrl = "{{appbuilder.get_url_for_login}}";
10
- var next = "?next={{request.args.get('next', '')}}"
11
-
12
- var currentSelection = "";
13
-
14
- function set_openid(pr) {
15
- $('.provider-select').removeClass('fa-black');
16
- $('#' + pr).addClass('fa-black');
17
- currentSelection = pr;
18
- }
19
-
20
-
21
- function signin() {
22
- if (currentSelection != "") {
23
- window.location.href = baseLoginUrl + currentSelection + next;
24
- }
25
- }
26
-
27
- function register() {
28
- if (currentSelection != "") {
29
- window.location.href = baseRegisterUrl + currentSelection + '/register' + next;
30
- }
31
- }
32
-
33
-
34
- </script>
35
-
36
6
  <div class="container">
37
7
  <div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
38
8
  <div class="panel panel-primary">
@@ -40,31 +10,36 @@
40
10
  <div class="panel-title">{{ title }}</div>
41
11
  </div>
42
12
  <div style="padding-top:30px" class="panel-body">
43
-
44
- <div class="help-block">{{_("Please choose one of the following providers:")}}</div>
45
- <div class="center-block btn-group btn-group-lg" role="group">
46
- <center>
47
- {% for pr in providers %}
48
- <a class="btn btn-primary" href="javascript:set_openid('{{pr.name}}');">
49
- <i id="{{pr.name}}" class="provider-select fa {{pr.icon}} fa-3x"></i>
50
- </a>
51
- {% endfor %}
52
- </center>
53
- </div>
54
13
  <div>
55
- <br></br>
56
- <a onclick="signin();" class="btn btn-primary btn-block" type="submit">{{_('Sign In')}}</a>
57
- {% if appbuilder.sm.auth_user_registration %}
58
- <a onclick="register();" class="btn btn-block btn-primary" data-toggle="tooltip" rel="tooltip"
59
- title="{{_('If you are not already a user, please register')}}">
60
- {{_('Register')}}
14
+ {% for provider in providers %}
15
+ <a
16
+ id="btn-signin-{{provider.name}}"
17
+ class="btn btn-primary btn-block"
18
+ type="submit"
19
+ >
20
+ {{_('Sign In with ')}}{{ provider.name }}
21
+ <i id="{{provider.name}}" class="provider-select fa {{provider.icon}} fa-1x"></i>
61
22
  </a>
62
- {% endif %}
23
+ {% endfor %}
63
24
  </div>
64
25
  </div>
65
26
  </div>
66
27
  </div>
67
28
  </div>
68
29
 
30
+ <script nonce="{{ baselib.get_nonce() }}">
31
+ var baseLoginUrl = "{{appbuilder.get_url_for_login}}";
32
+ var baseRegisterUrl = "{{appbuilder.get_url_for_login}}";
33
+ var next = "?next=" + "{{request.args.get('next', '') | urlencode}}";
34
+
35
+ function signin(provider) {
36
+ window.location.href = baseLoginUrl + provider + next;
37
+ }
69
38
 
70
- {% endblock %}
39
+ {% for provider in providers %}
40
+ document.getElementById("btn-signin-{{provider.name}}")
41
+ .addEventListener("click", function () { signin("{{provider.name}}") })
42
+ {% endfor %}
43
+
44
+ </script>
45
+ {% endblock %}
@@ -1,3 +1,4 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
1
2
  {% import 'appbuilder/general/lib.html' as lib %}
2
3
 
3
4
  {% set can_add = "can_add" | is_item_visible(modelview_name) %}
@@ -28,7 +29,7 @@
28
29
 
29
30
  {{ lib.action_form(actions, modelview_name) }}
30
31
 
31
- <script language="javascript">
32
+ <script nonce="{{ baselib.get_nonce() }}">
32
33
  $(document).ready(function() {
33
34
  window.modelActions = new AdminActions();
34
35
  });
@@ -1,8 +1,10 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
2
+
1
3
  <div id="chart" style="height: {{height}};">
2
4
  </div>
3
5
 
4
- <script type="text/javascript" src="{{url_for('appbuilder.static',filename='js/google_charts.js')}}"></script>
5
- <script type="text/javascript">
6
+ <script nonce="{{ baselib.get_nonce() }}" src="{{url_for('appbuilder.static',filename='js/google_charts.js')}}"></script>
7
+ <script nonce="{{ baselib.get_nonce() }}">
6
8
  //load the Google Visualization API and the chart
7
9
  google.load('visualization', '1', {'packages': ['corechart','gauge']});
8
10
 
@@ -1,7 +1,9 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
2
+
1
3
  <div id="{{ modelview_name }}" style="height: {{height}};">
2
4
  </div>
3
- <script type="text/javascript" src="{{url_for('appbuilder.static',filename='js/google_charts.js')}}"></script>
4
- <script type="text/javascript">
5
+ <script src="{{url_for('appbuilder.static',filename='js/google_charts.js')}}" nonce="{{ baselib.get_nonce() }}"></script>
6
+ <script nonce="{{ baselib.get_nonce() }}">
5
7
  //load the Google Visualization API and the chart
6
8
  google.load('visualization', '1', {'packages': ['corechart']});
7
9
 
@@ -11,7 +13,6 @@
11
13
 
12
14
  var jsonData{{ modelview_name }} = {{ value_columns | tojson }}
13
15
 
14
-
15
16
  //-----------------------------------
16
17
  // Attach listener for tab open event
17
18
  //-----------------------------------
@@ -1,6 +1,7 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
1
2
 
2
- <script type="text/javascript" src="{{url_for('appbuilder.static',filename='js/google_charts.js')}}"></script>
3
- <script type="text/javascript">
3
+ <script nonce="{{ baselib.get_nonce() }}" src="{{url_for('appbuilder.static',filename='js/google_charts.js')}}"></script>
4
+ <script nonce="{{ baselib.get_nonce() }}">
4
5
  //load the Google Visualization API and the chart
5
6
  google.load('visualization', '1', {'packages': ['corechart']});
6
7
 
@@ -1,3 +1,4 @@
1
+ {% import 'appbuilder/baselib.html' as baselib %}
1
2
  {% import 'appbuilder/general/lib.html' as lib %}
2
3
 
3
4
  <form id="filter_form" class="form-search" method="get">
@@ -9,7 +10,7 @@
9
10
  </button>
10
11
  <ul class="dropdown-menu">
11
12
  {% for col in include_cols %}
12
- <li><a href="javascript:void(0)" name="{{col}}" class="filter" onclick="return false;">
13
+ <li><a href="#" name="{{col}}" class="filter">
13
14
  {{ label_columns[col] }}</a>
14
15
  </li>
15
16
  {% endfor %}
@@ -25,15 +26,15 @@
25
26
  {{ lib.btn_search() }}
26
27
  </form>
27
28
 
28
- <script>
29
+ <script nonce="{{ baselib.get_nonce() }}">
29
30
  (function($) {
30
- var filter = new AdminFilters(
31
- '#filter_form',
32
- {{ label_columns | tojson }},
33
- {{ form_fields | tojson }},
34
- {{ search_filters | tojson }},
35
- {{ active_filters | tojson }}
36
- );
37
- })(jQuery);
31
+ const filter = new AdminFilters(
32
+ '#filter_form',
33
+ {{ label_columns | tojson }},
34
+ {{ form_fields | tojson }},
35
+ {{ search_filters | tojson }},
36
+ {{ active_filters | tojson }}
37
+ );
38
+ })(jQuery);
38
39
 
39
40
  </script>
@@ -1,8 +1,7 @@
1
1
  {% import 'appbuilder/baselib.html' as baselib with context %}
2
2
 
3
-
4
3
  {% if appbuilder %}
5
- {% set app_name = appbuilder.app_name %}
4
+ {% set app_name = appbuilder.app_name %}
6
5
  {% endif %}
7
6
 
8
7
  <!DOCTYPE html>
@@ -11,54 +10,49 @@
11
10
  <title>{% block page_title %}{{app_name}}{% endblock %}</title>
12
11
 
13
12
  {% block head_meta %}
14
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
15
- <meta name="description" content="">
16
- <meta name="author" content="">
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
+ <meta name="description" content="">
15
+ <meta name="author" content="">
17
16
  {% endblock %}
18
- {% block head_css %}
19
- <link href="{{url_for('appbuilder.static',filename='css/bootstrap.min.css')}}" rel="stylesheet">
20
- <link href="{{url_for('appbuilder.static',filename='css/font-awesome.min.css')}}" rel="stylesheet">
21
- {% if appbuilder.app_theme %}
22
- <link href="{{url_for('appbuilder.static',filename='css/themes/'+ appbuilder.app_theme )}}" rel="stylesheet">
23
- {% endif %}
24
17
 
25
- <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
26
- <!--[if lt IE 9]>
27
- <script src="{{url_for('appbuilder.static',filename='js/html5shiv.js')}}"></script>
28
- <script src="{{url_for('appbuilder.static',filename='js/respond.min.js')}}"></script>
29
- <![endif]-->
30
-
31
- <link href="{{url_for('appbuilder.static',filename='datepicker/bootstrap-datepicker.css')}}" rel="stylesheet">
32
- <link href="{{url_for('appbuilder.static',filename='select2/select2.css')}}" rel="stylesheet">
33
- <link href="{{url_for('appbuilder.static',filename='css/flags/flags16.css')}}" rel="stylesheet">
34
- <link href="{{url_for('appbuilder.static',filename='css/ab.css')}}" rel="stylesheet">
18
+ {% block head_css %}
19
+ <link href="{{url_for('appbuilder.static',filename='css/bootstrap.min.css')}}" rel="stylesheet">
20
+ <link href="{{url_for('appbuilder.static',filename='css/fontawesome/fontawesome.min.css')}}" rel="stylesheet">
21
+ <link href="{{url_for('appbuilder.static',filename='css/fontawesome/regular.min.css')}}" rel="stylesheet">
22
+ <link href="{{url_for('appbuilder.static',filename='css/fontawesome/solid.min.css')}}" rel="stylesheet">
23
+ <link href="{{url_for('appbuilder.static',filename='css/fontawesome/brands.min.css')}}" rel="stylesheet">
24
+ <link href="{{url_for('appbuilder.static',filename='css/fontawesome/v4-shims.min.css')}}" rel="stylesheet">
25
+ {% if appbuilder.app_theme %}
26
+ <link href="{{url_for('appbuilder.static',filename='css/themes/'+ appbuilder.app_theme )}}" rel="stylesheet">
27
+ {% endif %}
28
+ <link href="{{url_for('appbuilder.static',filename='css/bootstrap-datepicker/bootstrap-datepicker3.min.css')}}" rel="stylesheet">
29
+ <link href="{{url_for('appbuilder.static',filename='css/select2/select2.min.css')}}" rel="stylesheet">
30
+ <link href="{{url_for('appbuilder.static',filename='css/select2/select2-bootstrap.min.css')}}" rel="stylesheet">
31
+ <link href="{{url_for('appbuilder.static',filename='css/flags/flags16.css')}}" rel="stylesheet">
32
+ <link href="{{url_for('appbuilder.static',filename='css/ab.css')}}" rel="stylesheet">
35
33
  {% endblock %}
34
+
36
35
  {% block head_js %}
37
- <script src="{{url_for('appbuilder.static',filename='js/jquery-latest.js')}}"></script>
38
- <script src="{{url_for('appbuilder.static',filename='js/ab_filters.js')}}"></script>
39
- <script src="{{url_for('appbuilder.static',filename='js/ab_actions.js')}}"></script>
36
+ <script src="{{url_for('appbuilder.static',filename='js/jquery-latest.js')}}" nonce="{{baselib.get_nonce()}}"></script>
37
+ <script src="{{url_for('appbuilder.static',filename='js/ab_filters.js')}}" nonce="{{baselib.get_nonce()}}"></script>
38
+ <script src="{{url_for('appbuilder.static',filename='js/ab_actions.js')}}" nonce="{{baselib.get_nonce()}}"></script>
39
+ {% endblock %}
40
+ </head>
41
+ <body >
42
+ {% block body %}
40
43
  {% endblock %}
41
44
 
42
- </head>
43
-
44
- <body >
45
-
46
- {% block body %}
47
- {% endblock %}
48
-
49
-
50
- {% block tail_js %}
51
- <script src="{{url_for('appbuilder.static',filename='js/bootstrap.min.js')}}"></script>
52
- <script src="{{url_for('appbuilder.static',filename='datepicker/bootstrap-datepicker.js')}}"></script>
53
- <script src="{{url_for('appbuilder.static',filename='select2/select2.js')}}"></script>
54
- <script src="{{url_for('appbuilder.static',filename='js/ab.js')}}"></script>
55
- {% endblock %}
56
-
57
- {% block add_tail_js %}
58
- {% endblock %}
45
+ {% block tail_js %}
46
+ <script src="{{url_for('appbuilder.static',filename='js/bootstrap.min.js')}}" nonce="{{baselib.get_nonce()}}"></script>
47
+ <script src="{{url_for('appbuilder.static',filename='js/bootstrap-datepicker/bootstrap-datepicker.min.js')}}" nonce="{{baselib.get_nonce()}}"></script>
48
+ <script src="{{url_for('appbuilder.static',filename='js/select2/select2.min.js')}}" nonce="{{baselib.get_nonce()}}"></script>
49
+ <script src="{{url_for('appbuilder.static',filename='js/ab.js')}}" nonce="{{baselib.get_nonce()}}"></script>
50
+ {% endblock %}
59
51
 
60
- {% block tail %}
61
- {% endblock %}
52
+ {% block add_tail_js %}
53
+ {% endblock %}
62
54
 
55
+ {% block tail %}
56
+ {% endblock %}
63
57
  </body>
64
58
  </html>