WuttaWeb 0.9.0__tar.gz → 0.10.1__tar.gz

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 (147) hide show
  1. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/CHANGELOG.md +16 -0
  2. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/PKG-INFO +2 -1
  3. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/pyproject.toml +2 -1
  4. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/auth.py +9 -9
  5. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/forms/base.py +9 -0
  6. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/grids/__init__.py +3 -1
  7. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/grids/base.py +694 -44
  8. wuttaweb-0.10.1/src/wuttaweb/templates/grids/vue_template.mako +349 -0
  9. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/util.py +7 -8
  10. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/master.py +40 -3
  11. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/people.py +8 -7
  12. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/roles.py +1 -0
  13. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/settings.py +22 -8
  14. wuttaweb-0.10.1/tests/grids/test_base.py +995 -0
  15. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_master.py +5 -2
  16. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_settings.py +28 -5
  17. wuttaweb-0.9.0/src/wuttaweb/templates/grids/vue_template.mako +0 -215
  18. wuttaweb-0.9.0/tests/grids/test_base.py +0 -404
  19. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/.gitignore +0 -0
  20. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/COPYING.txt +0 -0
  21. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/README.md +0 -0
  22. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/Makefile +0 -0
  23. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/_static/.keepme +0 -0
  24. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/index.rst +0 -0
  25. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/app.rst +0 -0
  26. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/auth.rst +0 -0
  27. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/db.rst +0 -0
  28. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/forms.base.rst +0 -0
  29. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/forms.rst +0 -0
  30. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/forms.schema.rst +0 -0
  31. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/forms.widgets.rst +0 -0
  32. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/grids.base.rst +0 -0
  33. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/grids.rst +0 -0
  34. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/handler.rst +0 -0
  35. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/helpers.rst +0 -0
  36. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/index.rst +0 -0
  37. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/menus.rst +0 -0
  38. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/static.rst +0 -0
  39. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/subscribers.rst +0 -0
  40. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/util.rst +0 -0
  41. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.auth.rst +0 -0
  42. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.base.rst +0 -0
  43. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.common.rst +0 -0
  44. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.essential.rst +0 -0
  45. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.master.rst +0 -0
  46. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.people.rst +0 -0
  47. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.roles.rst +0 -0
  48. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.rst +0 -0
  49. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.settings.rst +0 -0
  50. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/api/wuttaweb/views.users.rst +0 -0
  51. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/conf.py +0 -0
  52. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/glossary.rst +0 -0
  53. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/index.rst +0 -0
  54. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/make.bat +0 -0
  55. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/docs/narr/index.rst +0 -0
  56. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/__init__.py +0 -0
  57. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/_version.py +0 -0
  58. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/app.py +0 -0
  59. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/db.py +0 -0
  60. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/forms/__init__.py +0 -0
  61. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/forms/schema.py +0 -0
  62. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/forms/widgets.py +0 -0
  63. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/handler.py +0 -0
  64. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/helpers.py +0 -0
  65. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/menus.py +0 -0
  66. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/static/__init__.py +0 -0
  67. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/static/img/favicon.ico +0 -0
  68. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/static/img/logo.png +0 -0
  69. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/static/img/testing.png +0 -0
  70. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/subscribers.py +0 -0
  71. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
  72. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/appinfo/index.mako +0 -0
  73. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/auth/change_password.mako +0 -0
  74. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/auth/login.mako +0 -0
  75. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/base.mako +0 -0
  76. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/base_meta.mako +0 -0
  77. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/configure.mako +0 -0
  78. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
  79. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
  80. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
  81. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/password.pt +0 -0
  82. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/permissions.pt +0 -0
  83. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
  84. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
  85. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
  86. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/select.pt +0 -0
  87. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/textarea.pt +0 -0
  88. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/deform/textinput.pt +0 -0
  89. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/forbidden.mako +0 -0
  90. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/form.mako +0 -0
  91. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
  92. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/home.mako +0 -0
  93. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/configure.mako +0 -0
  94. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/create.mako +0 -0
  95. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/delete.mako +0 -0
  96. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/edit.mako +0 -0
  97. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/form.mako +0 -0
  98. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/index.mako +0 -0
  99. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/master/view.mako +0 -0
  100. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/notfound.mako +0 -0
  101. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/page.mako +0 -0
  102. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/people/view_profile.mako +0 -0
  103. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/setup.mako +0 -0
  104. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/templates/wutta-components.mako +0 -0
  105. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/__init__.py +0 -0
  106. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/auth.py +0 -0
  107. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/base.py +0 -0
  108. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/common.py +0 -0
  109. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/essential.py +0 -0
  110. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/src/wuttaweb/views/users.py +0 -0
  111. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tasks.py +0 -0
  112. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/__init__.py +0 -0
  113. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/forms/__init__.py +0 -0
  114. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/forms/test_base.py +0 -0
  115. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/forms/test_schema.py +0 -0
  116. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/forms/test_widgets.py +0 -0
  117. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/grids/__init__.py +0 -0
  118. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
  119. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
  120. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_oruga.js +0 -0
  121. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_oruga_bulma.css +0 -0
  122. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_oruga_bulma.js +0 -0
  123. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_vue.js +0 -0
  124. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/bb_vue_fontawesome.js +0 -0
  125. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/buefy.css +0 -0
  126. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/buefy.js +0 -0
  127. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/fontawesome.js +0 -0
  128. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/vue.js +0 -0
  129. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/libcache/vue_resource.js +0 -0
  130. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_app.py +0 -0
  131. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_auth.py +0 -0
  132. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_handler.py +0 -0
  133. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_helpers.py +0 -0
  134. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_menus.py +0 -0
  135. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_static.py +0 -0
  136. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_subscribers.py +0 -0
  137. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/test_util.py +0 -0
  138. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/util.py +0 -0
  139. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/__init__.py +0 -0
  140. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test___init__.py +0 -0
  141. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_auth.py +0 -0
  142. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_base.py +0 -0
  143. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_common.py +0 -0
  144. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_people.py +0 -0
  145. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_roles.py +0 -0
  146. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tests/views/test_users.py +0 -0
  147. {wuttaweb-0.9.0 → wuttaweb-0.10.1}/tox.ini +0 -0
@@ -5,6 +5,22 @@ All notable changes to wuttaweb will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## v0.10.1 (2024-08-19)
9
+
10
+ ### Fix
11
+
12
+ - make `util.get_model_fields()` work with more model classes
13
+
14
+ ## v0.10.0 (2024-08-18)
15
+
16
+ ### Feat
17
+
18
+ - add multi-column sorting (frontend or backend) for grids
19
+
20
+ ### Fix
21
+
22
+ - improve grid display when data is empty
23
+
8
24
  ## v0.9.0 (2024-08-16)
9
25
 
10
26
  ### Feat
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: WuttaWeb
3
- Version: 0.9.0
3
+ Version: 0.10.1
4
4
  Summary: Web App for Wutta Framework
5
5
  Project-URL: Homepage, https://wuttaproject.org/
6
6
  Project-URL: Repository, https://forgejo.wuttaproject.org/wutta/wuttaweb
@@ -26,6 +26,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
26
  Requires-Python: >=3.8
27
27
  Requires-Dist: colanderalchemy
28
28
  Requires-Dist: paginate
29
+ Requires-Dist: paginate-sqlalchemy
29
30
  Requires-Dist: pyramid-beaker
30
31
  Requires-Dist: pyramid-deform
31
32
  Requires-Dist: pyramid-fanstatic
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "WuttaWeb"
9
- version = "0.9.0"
9
+ version = "0.10.1"
10
10
  description = "Web App for Wutta Framework"
11
11
  readme = "README.md"
12
12
  authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
@@ -32,6 +32,7 @@ requires-python = ">= 3.8"
32
32
  dependencies = [
33
33
  "ColanderAlchemy",
34
34
  "paginate",
35
+ "paginate_sqlalchemy",
35
36
  "pyramid>=2",
36
37
  "pyramid_beaker",
37
38
  "pyramid_deform",
@@ -150,7 +150,7 @@ class WuttaSecurityPolicy:
150
150
  return auth.has_permission(self.db_session, user, permission)
151
151
 
152
152
 
153
- def add_permission_group(pyramid_config, key, label=None, overwrite=True):
153
+ def add_permission_group(pyramid_config, groupkey, label=None, overwrite=True):
154
154
  """
155
155
  Pyramid directive to add a "permission group" to the app's
156
156
  awareness.
@@ -169,12 +169,12 @@ def add_permission_group(pyramid_config, key, label=None, overwrite=True):
169
169
 
170
170
  pyramid_config.add_permission_group('widgets', label="Widgets")
171
171
 
172
- :param key: Unique key for the permission group. In the context
173
- of a master view, this will be the same as
172
+ :param groupkey: Unique key for the permission group. In the
173
+ context of a master view, this will be the same as
174
174
  :attr:`~wuttaweb.views.master.MasterView.permission_prefix`.
175
175
 
176
176
  :param label: Optional label for the permission group. If not
177
- specified, it is derived from ``key``.
177
+ specified, it is derived from ``groupkey``.
178
178
 
179
179
  :param overwrite: If the permission group was already established,
180
180
  this flag controls whether the group's label should be
@@ -186,9 +186,9 @@ def add_permission_group(pyramid_config, key, label=None, overwrite=True):
186
186
  app = config.get_app()
187
187
  def action():
188
188
  perms = pyramid_config.get_settings().get('wutta_permissions', {})
189
- if overwrite or key not in perms:
190
- group = perms.setdefault(key, {'key': key})
191
- group['label'] = label or app.make_title(key)
189
+ if overwrite or groupkey not in perms:
190
+ group = perms.setdefault(groupkey, {'key': groupkey})
191
+ group['label'] = label or app.make_title(groupkey)
192
192
  pyramid_config.add_settings({'wutta_permissions': perms})
193
193
  pyramid_config.action(None, action)
194
194
 
@@ -215,8 +215,8 @@ def add_permission(pyramid_config, groupkey, key, label=None):
215
215
  pyramid_config.add_permission('widgets', 'widgets.polish',
216
216
  label="Polish all the widgets")
217
217
 
218
- :param key: Unique key for the permission group. In the context
219
- of a master view, this will be the same as
218
+ :param groupkey: Unique key for the permission group. In the
219
+ context of a master view, this will be the same as
220
220
  :attr:`~wuttaweb.views.master.MasterView.permission_prefix`.
221
221
 
222
222
  :param key: Unique key for the permission. This should be the
@@ -182,6 +182,8 @@ class Form:
182
182
  String name for Vue component tag. By default this is
183
183
  ``'wutta-form'``. See also :meth:`render_vue_tag()`.
184
184
 
185
+ See also :attr:`vue_component`.
186
+
185
187
  .. attribute:: align_buttons_right
186
188
 
187
189
  Flag indicating whether the buttons (submit, cancel etc.)
@@ -784,6 +786,13 @@ class Form:
784
786
  </form>
785
787
  </script>
786
788
 
789
+ <script>
790
+ WuttaFormData = {}
791
+ WuttaForm = {
792
+ template: 'wutta-form-template',
793
+ }
794
+ </script>
795
+
787
796
  .. todo::
788
797
 
789
798
  Why can't Sphinx render the above code block as 'html' ?
@@ -26,6 +26,8 @@ Grids Library
26
26
  The ``wuttaweb.grids`` namespace contains the following:
27
27
 
28
28
  * :class:`~wuttaweb.grids.base.Grid`
29
+ * :class:`~wuttaweb.grids.base.GridAction`
30
+ * :class:`~wuttaweb.grids.base.SortInfo`
29
31
  """
30
32
 
31
- from .base import Grid, GridAction
33
+ from .base import Grid, GridAction, SortInfo