accrete 0.0.104__tar.gz → 0.0.105__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.
- {accrete-0.0.104 → accrete-0.0.105}/PKG-INFO +3 -2
- accrete-0.0.105/accrete/contrib/ui/__init__.py +10 -0
- accrete-0.0.105/accrete/contrib/ui/context.py +86 -0
- accrete-0.0.105/accrete/contrib/ui/filter.py +352 -0
- accrete-0.0.105/accrete/contrib/ui/middleware.py +44 -0
- accrete-0.0.105/accrete/contrib/ui/models.py +3 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/README.md +4 -2
- {accrete-0.0.104/accrete/contrib/ui/static/bulma/css → accrete-0.0.105/accrete/contrib/ui/static/bulma}/bulma.css +1988 -2874
- accrete-0.0.105/accrete/contrib/ui/static/bulma/bulma.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/bulma.scss +4 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/bulma.css +21551 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/bulma.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/bulma.min.css +3 -0
- accrete-0.0.104/accrete/contrib/ui/static/css/accrete.css → accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css +2151 -3556
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css +11136 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css +11136 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css +21551 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.min.css +3 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/package.json +12 -11
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/animations.css +15 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/animations.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/generic.css +196 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/generic.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/minireset.css +82 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/minireset.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/skeleton.css +113 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/base/skeleton.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/base/skeleton.scss +0 -12
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css +108 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/breadcrumb.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/card.css +130 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/card.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/dropdown.css +119 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/dropdown.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/menu.css +119 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/menu.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/message.css +191 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/message.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/modal.css +194 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/modal.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/navbar.css +768 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/navbar.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/navbar.scss +41 -30
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/pagination.css +302 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/pagination.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/panel.css +224 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/panel.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/panel.scss +2 -2
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/tabs.css +192 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/components/tabs.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/block.css +17 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/block.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/box.css +43 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/box.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/button.css +685 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/button.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/button.scss +9 -2
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/content.css +208 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/content.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/content.scss +8 -2
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/delete.css +60 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/delete.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/icon.css +51 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/icon.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/image.css +253 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/image.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/loader.css +14 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/loader.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/notification.css +213 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/notification.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/progress.css +119 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/progress.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/table.css +294 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/table.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/tag.css +252 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/tag.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/title.css +131 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/elements/title.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css +72 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/checkbox-radio.scss +7 -3
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/file.css +374 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/file.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/input-textarea.css +284 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/input-textarea.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/input-textarea.scss +0 -10
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/select.css +347 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/select.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/select.scss +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/shared.css +48 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/shared.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/shared.scss +5 -1
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/tools.css +356 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/form/tools.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/tools.scss +23 -12
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css +1635 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/grid/columns-v2.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/grid/columns.css +1652 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/grid/columns.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/grid/columns.scss +109 -25
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/grid/grid.css +3011 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/grid/grid.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/grid/grid.scss +3 -3
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css +61 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/border.css +17 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/border.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/color.css +5582 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/color.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/color.scss +344 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css +217 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/flexbox.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/float.css +37 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/float.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/gap.css +209 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/gap.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/other.css +34 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/other.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/overflow.css +65 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/overflow.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/position.css +45 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/position.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/spacing.css +489 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/spacing.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/typography.css +423 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/typography.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/visibility.css +485 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/helpers/visibility.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/container.scss +16 -8
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/footer.css +9 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/footer.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/hero.css +534 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/hero.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/level.css +102 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/level.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/media.css +90 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/media.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/section.css +23 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/layout/section.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/section.scss +4 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/themes/dark.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/themes/dark.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/themes/light.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/themes/light.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/themes/light.scss +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/themes/setup.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/themes/setup.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/controls.css +13 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/controls.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/css-variables.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/css-variables.scss +3 -2
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/extends.css +13 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/extends.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/functions.scss +2 -2
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/initial-variables.scss +4 -4
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/mixins.css +3 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/sass/utilities/mixins.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/mixins.scss +1 -1
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css +19648 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/versions/bulma-no-dark-mode.scss +2 -1
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css +11136 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers-prefixed.scss +1 -1
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css +11136 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/versions/bulma-no-helpers.scss +1 -1
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css +21551 -0
- accrete-0.0.105/accrete/contrib/ui/static/bulma/versions/bulma-prefixed.css.map +1 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/versions/bulma-prefixed.scss +1 -1
- accrete-0.0.105/accrete/contrib/ui/static/css/accrete.css +21813 -0
- accrete-0.0.105/accrete/contrib/ui/static/css/accrete.css.map +1 -0
- accrete-0.0.105/accrete/contrib/ui/static/css/accrete.scss +281 -0
- accrete-0.0.105/accrete/contrib/ui/static/js/filter.js +129 -0
- accrete-0.0.105/accrete/contrib/ui/static/js/htmx.min.js +1 -0
- accrete-0.0.105/accrete/contrib/ui/templates/django/forms/widgets/date.html +5 -0
- accrete-0.0.105/accrete/contrib/ui/templates/django/forms/widgets/select.html +7 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/content_right.html +7 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/filter/filter.html +27 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/filter/query_input.html +31 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/filter/query_operator.html +11 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/filter/query_params.html +106 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/filter/query_tags.html +26 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/layout.html +195 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/list.html +46 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/list_update.html +3 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/message.html +13 -0
- {accrete-0.0.104/accrete/contrib/ui/templates/ui/partials → accrete-0.0.105/accrete/contrib/ui/templates/ui}/modal.html +9 -5
- accrete-0.0.105/accrete/contrib/ui/templates/ui/oob.html +3 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/table.html +77 -0
- accrete-0.0.105/accrete/contrib/ui/templates/ui/table_row_update.html +14 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/ui/widgets/model_search_select.html +2 -2
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/ui/widgets/model_search_select_multi.html +24 -13
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/ui/widgets/model_search_select_options.html +1 -1
- accrete-0.0.104/accrete/contrib/ui/templatetags/accrete_ui.py → accrete-0.0.105/accrete/contrib/ui/templatetags/ui.py +67 -56
- accrete-0.0.105/accrete/contrib/ui/urls.py +11 -0
- accrete-0.0.105/accrete/contrib/ui/views.py +35 -0
- accrete-0.0.105/accrete/contrib/ui/widgets/__init__.py +1 -0
- accrete-0.0.104/accrete/contrib/ui/forms/widgets.py → accrete-0.0.105/accrete/contrib/ui/widgets/search_select.py +7 -2
- accrete-0.0.105/accrete/contrib/user/templates/user/login.html +82 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/forms.py +0 -2
- {accrete-0.0.104 → accrete-0.0.105}/accrete/managers.py +4 -4
- accrete-0.0.105/accrete/middleware.py +69 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/models.py +7 -1
- {accrete-0.0.104 → accrete-0.0.105}/accrete/storage.py +4 -1
- {accrete-0.0.104 → accrete-0.0.105}/accrete/tenant.py +9 -4
- {accrete-0.0.104 → accrete-0.0.105}/accrete/utils/__init__.py +2 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/utils/models.py +9 -1
- {accrete-0.0.104 → accrete-0.0.105}/accrete/utils/views.py +36 -20
- {accrete-0.0.104 → accrete-0.0.105}/accrete/views.py +9 -5
- {accrete-0.0.104 → accrete-0.0.105}/pyproject.toml +1 -1
- accrete-0.0.104/accrete/contrib/ui/__init__.py +0 -33
- accrete-0.0.104/accrete/contrib/ui/components/__init__.py +0 -1
- accrete-0.0.104/accrete/contrib/ui/components/search_select.py +0 -18
- accrete-0.0.104/accrete/contrib/ui/context.py +0 -357
- accrete-0.0.104/accrete/contrib/ui/elements.py +0 -95
- accrete-0.0.104/accrete/contrib/ui/filter.py +0 -360
- accrete-0.0.104/accrete/contrib/ui/static/bulma/bulma.scss +0 -4
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/bulma.css.map +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/bulma.min.css +0 -3
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css +0 -3
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-no-dark-mode.min.css.map +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css +0 -3
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers-prefixed.min.css.map +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css +0 -3
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-no-helpers.min.css.map +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css +0 -3
- accrete-0.0.104/accrete/contrib/ui/static/bulma/css/versions/bulma-prefixed.min.css.map +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/bulma/sass/grid/columns-v2.scss +0 -957
- accrete-0.0.104/accrete/contrib/ui/static/bulma/sass/helpers/color.scss +0 -364
- accrete-0.0.104/accrete/contrib/ui/static/css/accrete.css.map +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/css/accrete.scss +0 -558
- accrete-0.0.104/accrete/contrib/ui/static/js/filter.js +0 -711
- accrete-0.0.104/accrete/contrib/ui/static/js/htmx.min.js +0 -1
- accrete-0.0.104/accrete/contrib/ui/static/js/ui.js +0 -30
- accrete-0.0.104/accrete/contrib/ui/templates/django/forms/widgets/date.html +0 -9
- accrete-0.0.104/accrete/contrib/ui/templates/django/forms/widgets/select.html +0 -5
- accrete-0.0.104/accrete/contrib/ui/templates/ui/dashboard.html +0 -7
- accrete-0.0.104/accrete/contrib/ui/templates/ui/detail.html +0 -19
- accrete-0.0.104/accrete/contrib/ui/templates/ui/form.html +0 -21
- accrete-0.0.104/accrete/contrib/ui/templates/ui/layout.html +0 -266
- accrete-0.0.104/accrete/contrib/ui/templates/ui/list.html +0 -35
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/filter.html +0 -146
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/form_errors.html +0 -34
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/header.html +0 -123
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/modal_form.html +0 -46
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/onchange_form.html +0 -1
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/pagination_detail.html +0 -23
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/pagination_list.html +0 -28
- accrete-0.0.104/accrete/contrib/ui/templates/ui/partials/table_field_tags.html +0 -17
- accrete-0.0.104/accrete/contrib/ui/templates/ui/table.html +0 -81
- accrete-0.0.104/accrete/contrib/ui/templates/ui/widgets/model_search_select_multi_selected_options.html +0 -3
- accrete-0.0.104/accrete/contrib/ui/templates/ui/widgets/model_search_select_multi_tags.html +0 -6
- accrete-0.0.104/accrete/contrib/ui/urls.py +0 -9
- accrete-0.0.104/accrete/contrib/ui/views.py +0 -5
- accrete-0.0.104/accrete/contrib/user/templates/user/login.html +0 -34
- accrete-0.0.104/accrete/middleware.py +0 -92
- accrete-0.0.104/accrete/migrations/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/.gitignore +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/LICENSE +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/README.md +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/admin.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/annotation.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/apps.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/config.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/admin.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/apps.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/forms.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/migrations/0001_initial.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/migrations/0002_alter_sequence_name.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/migrations/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/models.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/queries.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/tests.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/sequence/views.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/admin.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/apps.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/forms.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/migrations/0001_initial.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/migrations/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/models.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/tasks.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/tests.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/system_mail/views.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/admin.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/apps.py +0 -0
- {accrete-0.0.104/accrete/contrib/ui/forms → accrete-0.0.105/accrete/contrib/ui/migrations}/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/LICENSE +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/base/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/base/animations.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/base/generic.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/base/minireset.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/breadcrumb.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/card.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/dropdown.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/menu.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/message.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/modal.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/pagination.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/components/tabs.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/block.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/box.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/delete.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/icon.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/image.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/loader.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/notification.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/progress.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/table.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/tag.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/elements/title.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/form/file.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/grid/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/aspect-ratio.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/border.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/flexbox.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/float.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/gap.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/other.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/overflow.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/position.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/spacing.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/typography.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/helpers/visibility.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/footer.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/hero.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/level.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/layout/media.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/themes/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/themes/dark.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/themes/setup.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/_index.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/controls.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/derived-variables.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/bulma/sass/utilities/extends.scss +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/css/fa.css +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/css/icons.css +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/icons/Logo.svg +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/icons/accrete.svg +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/js/alpine-sort3.14.1.js +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/js/alpine3.14.1.js +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-brands-400.ttf +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-brands-400.woff2 +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-regular-400.ttf +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-regular-400.woff2 +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-solid-900.ttf +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-solid-900.woff2 +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-v4compatibility.ttf +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/static/webfonts/fa-v4compatibility.woff2 +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/django/forms/widgets/attrs.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/django/forms/widgets/email.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/django/forms/widgets/file.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/django/forms/widgets/input.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/django/forms/widgets/text.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/templates/django/forms/widgets/textarea.html +0 -0
- {accrete-0.0.104/accrete/contrib/ui/migrations → accrete-0.0.105/accrete/contrib/ui/templatetags}/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/ui/tests.py +0 -0
- {accrete-0.0.104/accrete/contrib/ui/templatetags → accrete-0.0.105/accrete/contrib/user}/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/admin.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/apps.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/forms.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/locale/de/LC_MESSAGES/django.mo +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/locale/de/LC_MESSAGES/django.po +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/middleware.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/migrations/0001_initial.py +0 -0
- {accrete-0.0.104/accrete/contrib/user → accrete-0.0.105/accrete/contrib/user/migrations}/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/models.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/templates/user/accrete_navbar_end_dropdown.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/templates/user/change_email.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/templates/user/change_password.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/templates/user/user_detail.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/templates/user/user_form.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/tests.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/urls.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user/views.py +0 -0
- {accrete-0.0.104/accrete/contrib/user/migrations → accrete-0.0.105/accrete/contrib/user_registration}/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/admin.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/apps.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/config.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/forms.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/migrations/0001_initial.py +0 -0
- {accrete-0.0.104/accrete/contrib/user_registration → accrete-0.0.105/accrete/contrib/user_registration/migrations}/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/models.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/templates/user_registration/mail_templates/confirmation_mail.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/templates/user_registration/registration.html +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/tests.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/urls.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/contrib/user_registration/views.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/migrations/0001_initial.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/migrations/0002_initial.py +0 -0
- {accrete-0.0.104/accrete/contrib/user_registration → accrete-0.0.105/accrete}/migrations/__init__.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/tests.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/urls.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/utils/dates.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/utils/forms.py +0 -0
- {accrete-0.0.104 → accrete-0.0.105}/accrete/utils/log.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: accrete
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.105
|
4
4
|
Summary: Django Shared Schema Multi Tenant
|
5
5
|
Author-email: Benedikt Jilek <benedikt.jilek@pm.me>
|
6
6
|
License: Copyright (c) 2023 Benedikt Jilek
|
@@ -22,6 +22,7 @@ License: Copyright (c) 2023 Benedikt Jilek
|
|
22
22
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
23
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
24
24
|
SOFTWARE.
|
25
|
+
License-File: LICENSE
|
25
26
|
Classifier: Environment :: Web Environment
|
26
27
|
Classifier: Framework :: Django
|
27
28
|
Classifier: Intended Audience :: Developers
|
@@ -0,0 +1,86 @@
|
|
1
|
+
import logging
|
2
|
+
from dataclasses import dataclass, field
|
3
|
+
from django.core import paginator
|
4
|
+
from django.db.models import QuerySet, Model
|
5
|
+
from .filter import Filter
|
6
|
+
|
7
|
+
_logger = logging.getLogger(__name__)
|
8
|
+
|
9
|
+
|
10
|
+
@dataclass(kw_only=True)
|
11
|
+
class BaseContext:
|
12
|
+
|
13
|
+
extra: dict = field(default_factory=dict)
|
14
|
+
|
15
|
+
def __post_init__(self):
|
16
|
+
for key, value in self.extra.items():
|
17
|
+
setattr(self, key, value)
|
18
|
+
|
19
|
+
def dict(self):
|
20
|
+
return {
|
21
|
+
attr: getattr(self, attr, None) for attr
|
22
|
+
in filter(lambda x: not x.startswith('_'), self.__dict__)
|
23
|
+
}
|
24
|
+
|
25
|
+
|
26
|
+
@dataclass(kw_only=True)
|
27
|
+
class Context(BaseContext):
|
28
|
+
|
29
|
+
title: str = ''
|
30
|
+
|
31
|
+
|
32
|
+
@dataclass
|
33
|
+
class ListContext(Context):
|
34
|
+
|
35
|
+
page: paginator.Page
|
36
|
+
queryset: QuerySet
|
37
|
+
endless_scroll: bool = True
|
38
|
+
detail_enabled: bool = True
|
39
|
+
filter: Filter = None
|
40
|
+
column_count: int = 1
|
41
|
+
column_height: int = 150
|
42
|
+
column_height_unit: str = 'px'
|
43
|
+
|
44
|
+
def __post_init__(self):
|
45
|
+
super().__post_init__()
|
46
|
+
if self.column_count not in range(1, 13):
|
47
|
+
_logger.warning(
|
48
|
+
'ListContext parameter column_count should be in range 1 - 12'
|
49
|
+
)
|
50
|
+
|
51
|
+
|
52
|
+
@dataclass
|
53
|
+
class ListUpdateContext(BaseContext):
|
54
|
+
|
55
|
+
object: Model
|
56
|
+
template: str
|
57
|
+
|
58
|
+
|
59
|
+
@dataclass
|
60
|
+
class TableContext(Context):
|
61
|
+
|
62
|
+
object_label: str
|
63
|
+
fields: list[str]
|
64
|
+
page: paginator.Page
|
65
|
+
queryset: QuerySet
|
66
|
+
footer: dict = field(default_factory=dict)
|
67
|
+
endless_scroll: bool = True
|
68
|
+
detail_enabled: bool = True
|
69
|
+
filter: Filter = None
|
70
|
+
|
71
|
+
|
72
|
+
@dataclass
|
73
|
+
class TableRowContext(BaseContext):
|
74
|
+
|
75
|
+
object: Model
|
76
|
+
fields: list[str]
|
77
|
+
queryset: QuerySet
|
78
|
+
footer: dict = field(default_factory=dict)
|
79
|
+
|
80
|
+
|
81
|
+
@dataclass
|
82
|
+
class ModalContext(BaseContext):
|
83
|
+
|
84
|
+
title: str
|
85
|
+
modal_id: str
|
86
|
+
blocking: bool = False
|
@@ -0,0 +1,352 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import datetime
|
4
|
+
from decimal import Decimal
|
5
|
+
|
6
|
+
from django.db.models import QuerySet
|
7
|
+
from django.http.request import QueryDict
|
8
|
+
from django.db.models.fields import Field
|
9
|
+
from django.template.loader import render_to_string
|
10
|
+
from django.utils.translation import gettext_lazy as _
|
11
|
+
from django.utils.safestring import mark_safe
|
12
|
+
from django.apps import apps
|
13
|
+
from django.core import paginator
|
14
|
+
from accrete.utils.models import get_related_model, get_related_field
|
15
|
+
from accrete.utils import page_from_querystring, filter_from_querystring
|
16
|
+
|
17
|
+
_logger = logging.getLogger(__name__)
|
18
|
+
|
19
|
+
|
20
|
+
class Filter:
|
21
|
+
|
22
|
+
LABEL_EXACT = _('Equals')
|
23
|
+
LABEL_EXACT_NOT = _('Equals Not')
|
24
|
+
LABEL_ICONTAINS = _('Contains')
|
25
|
+
LABEL_ICONTAINS_NOT = _('Contains Not')
|
26
|
+
LABEL_GTE = _('Greater or Equal')
|
27
|
+
LABEL_LTE = _('Less or Equal')
|
28
|
+
LABEL_TRUE = _('True')
|
29
|
+
LABEL_FALSE = _('False')
|
30
|
+
LABEL_SET = _('Is Set')
|
31
|
+
LABEL_NOT_SET = _('Is Not Set')
|
32
|
+
LABEL_AND = _('And')
|
33
|
+
LABEL_OR = _('Or')
|
34
|
+
LABEL_XOR = _('Not Or')
|
35
|
+
|
36
|
+
# EXCLUDE = ['tenant']
|
37
|
+
|
38
|
+
DATE_FORMAT = '%Y-%m-%d'
|
39
|
+
|
40
|
+
TYPES_INTEGER = [
|
41
|
+
'AutoField', 'BigAutoField', 'IntegerField', 'PositiveSmallIntegerField'
|
42
|
+
]
|
43
|
+
TYPES_NUMBER = ['DecimalField', 'FloatField']
|
44
|
+
TYPES_CHAR = ['CharField', 'TextField']
|
45
|
+
TYPES_BOOL = ['BooleanField']
|
46
|
+
TYPES_DATETIME = ['DateTimeField']
|
47
|
+
TYPES_DATE = ['DateField']
|
48
|
+
TYPES_TIME = ['TimeField']
|
49
|
+
|
50
|
+
def __init__(
|
51
|
+
self, model, query: QueryDict, default_lookup: str = None
|
52
|
+
):
|
53
|
+
self.model = model
|
54
|
+
self.query = query
|
55
|
+
self.model_name = f'{self.model._meta.app_label}.{self.model._meta.model_name}'
|
56
|
+
seen_models = query.get('models', '').split(',')
|
57
|
+
self.seen_models = [
|
58
|
+
model for model in seen_models
|
59
|
+
if model and model != self.model_name
|
60
|
+
] + [self.model_name]
|
61
|
+
self.default_lookup = default_lookup
|
62
|
+
self.exclude = []
|
63
|
+
if hasattr(self.model, 'exclude_from_filter'):
|
64
|
+
self.exclude.extend(self.model.exclude_from_filter())
|
65
|
+
|
66
|
+
def get_page(self, select_related: list = None, prefetch_related: list = None) -> paginator.Page:
|
67
|
+
return page_from_querystring(
|
68
|
+
self.model,
|
69
|
+
self.query,
|
70
|
+
select_related=select_related,
|
71
|
+
prefetch_related=prefetch_related
|
72
|
+
)
|
73
|
+
|
74
|
+
def get_queryset(self) -> QuerySet:
|
75
|
+
return filter_from_querystring(self.model, self.query)
|
76
|
+
|
77
|
+
def query_params(self):
|
78
|
+
fields = filter(
|
79
|
+
lambda x: x.name not in self.exclude,
|
80
|
+
self.model._meta.get_fields()
|
81
|
+
)
|
82
|
+
params = []
|
83
|
+
path = self.query.get('path', '')
|
84
|
+
for field in fields:
|
85
|
+
field_params = self._get_field_params(field)
|
86
|
+
if not field.is_relation or field_params['model_name'] not in self.seen_models:
|
87
|
+
params.append(self._get_field_params(field))
|
88
|
+
has_previous = len(self.seen_models) > 1
|
89
|
+
ctx = dict(
|
90
|
+
params=sorted(params, key=lambda x: x['label'].lower()),
|
91
|
+
model_name=self.model_name,
|
92
|
+
seen_models=','.join(self.seen_models),
|
93
|
+
verbose_model_name=self.model._meta.verbose_name,
|
94
|
+
has_previous=has_previous,
|
95
|
+
)
|
96
|
+
if has_previous:
|
97
|
+
previous_model_name = self.seen_models[-2]
|
98
|
+
previous_path = '__'.join(path.split('__')[:-1])
|
99
|
+
ctx.update(
|
100
|
+
previous_model_name=previous_model_name,
|
101
|
+
previous_seen_models=','.join(
|
102
|
+
self.seen_models[:-1] if has_previous else []
|
103
|
+
),
|
104
|
+
previous_verbose_model_name=apps.get_model(
|
105
|
+
*previous_model_name.split('.')
|
106
|
+
)._meta.verbose_name,
|
107
|
+
previous_path=previous_path
|
108
|
+
)
|
109
|
+
return render_to_string('ui/filter/query_params.html', ctx)
|
110
|
+
|
111
|
+
def query_input(self, lookup: str = None):
|
112
|
+
lookup = lookup or self.default_lookup
|
113
|
+
if not lookup:
|
114
|
+
ctx = {
|
115
|
+
'verbose_lookup': str(_('Select an attribute')),
|
116
|
+
'query_dict': self.query,
|
117
|
+
'model_name': self.model_name
|
118
|
+
}
|
119
|
+
return render_to_string('ui/filter/query_input.html', ctx)
|
120
|
+
prefix = lookup.startswith('~') and '~' or ''
|
121
|
+
lookup = lookup.removeprefix('~')
|
122
|
+
lookup_parts = lookup.split('__')
|
123
|
+
lookup_operator = lookup_parts[-1]
|
124
|
+
rel_path = '__'.join(lookup_parts[:-2])
|
125
|
+
model, names = get_related_model(self.model, rel_path)
|
126
|
+
field = model._meta.get_field(lookup_parts[-2])
|
127
|
+
input_params = self._get_input_params(field, lookup_operator)
|
128
|
+
ctx = {
|
129
|
+
'verbose_lookup': ' > '.join(self._get_query_tag_lhs(prefix + lookup)),
|
130
|
+
'field': field,
|
131
|
+
'lookup': prefix + lookup,
|
132
|
+
'input': input_params,
|
133
|
+
'lookup_operator': lookup_operator,
|
134
|
+
'query_dict': self.query,
|
135
|
+
'model_name': self.model_name
|
136
|
+
}
|
137
|
+
return render_to_string('ui/filter/query_input.html', ctx)
|
138
|
+
|
139
|
+
def query_tags(self, query: list | dict = None, operator: str = None):
|
140
|
+
if not query:
|
141
|
+
query = json.loads(self.query.get('q', '[]'))
|
142
|
+
if isinstance(query, dict):
|
143
|
+
query = [query]
|
144
|
+
operator = operator or '&'
|
145
|
+
html = '<div class="query-group-container">'
|
146
|
+
html += render_to_string(
|
147
|
+
'ui/filter/query_operator.html', {'operator': operator}
|
148
|
+
)
|
149
|
+
html += (
|
150
|
+
'<div class="query-group" '
|
151
|
+
'x-sort="applyQuery();" x-sort:group="query" '
|
152
|
+
'x-sort:config="{preventOnFilter: false}">'
|
153
|
+
)
|
154
|
+
for idx, item in enumerate(query):
|
155
|
+
if isinstance(item, str):
|
156
|
+
continue
|
157
|
+
operator = '&'
|
158
|
+
if idx > 0 and isinstance(query[idx - 1], str):
|
159
|
+
operator = query[idx - 1]
|
160
|
+
if isinstance(item, list):
|
161
|
+
html += self.query_tags(item, operator)
|
162
|
+
if isinstance(item, dict):
|
163
|
+
item_ctx = self._get_query_tag_context(item, operator)
|
164
|
+
html += render_to_string('ui/filter/query_tags.html', item_ctx)
|
165
|
+
html += '</div></div>'
|
166
|
+
return mark_safe(html)
|
167
|
+
|
168
|
+
def _get_input_params(self, field: Field, lookup_operator: str):
|
169
|
+
field_type = field.get_internal_type()
|
170
|
+
params = {
|
171
|
+
'field_type': field_type,
|
172
|
+
'data_type': self._internal_type_to_data_type(field_type, lookup_operator)
|
173
|
+
}
|
174
|
+
if lookup_operator == 'isnull':
|
175
|
+
params.update(
|
176
|
+
input_type='select',
|
177
|
+
choices=[('false', str(_('True'))), ('true', str(_('False')))],
|
178
|
+
data_type='bool'
|
179
|
+
)
|
180
|
+
return params
|
181
|
+
if field_type in self.TYPES_BOOL:
|
182
|
+
params.update(
|
183
|
+
input_type='select',
|
184
|
+
choices=[('true', str(_('True'))), ('false', str(_('False')))],
|
185
|
+
data_type='bool'
|
186
|
+
)
|
187
|
+
return params
|
188
|
+
elif field_type in self.TYPES_INTEGER:
|
189
|
+
if field.choices:
|
190
|
+
params.update(input_type='select', choices=field.choices)
|
191
|
+
else:
|
192
|
+
params.update(input_type='number', step=1)
|
193
|
+
elif field_type in self.TYPES_NUMBER:
|
194
|
+
step = (
|
195
|
+
hasattr(field, 'decimal_places')
|
196
|
+
and self._cast_decimal_places_to_step(field.decimal_places)
|
197
|
+
or 1
|
198
|
+
)
|
199
|
+
params.update(input_type='number', step=step)
|
200
|
+
elif field_type in self.TYPES_CHAR:
|
201
|
+
if field.choices:
|
202
|
+
params.update(input_type='select', choices=field.choices)
|
203
|
+
else:
|
204
|
+
params.update(input_type='text')
|
205
|
+
elif field_type in self.TYPES_DATETIME:
|
206
|
+
params.update(input_type='datetime-local', format=self.DATE_FORMAT)
|
207
|
+
elif field_type in self.TYPES_DATE:
|
208
|
+
params.update(input_type='date', format=self.DATE_FORMAT)
|
209
|
+
elif field_type in self.TYPES_TIME:
|
210
|
+
params.update(input_type='time')
|
211
|
+
return params
|
212
|
+
|
213
|
+
def _internal_type_to_data_type(self, internal_type, lookup: str):
|
214
|
+
if lookup == 'isnull' or internal_type in self.TYPES_BOOL:
|
215
|
+
return 'bool'
|
216
|
+
if internal_type in self.TYPES_INTEGER + self.TYPES_NUMBER:
|
217
|
+
return 'number'
|
218
|
+
return 'text'
|
219
|
+
|
220
|
+
def _get_query_tag_context(self, data: dict, operator: str):
|
221
|
+
ctx = {'tags': []}
|
222
|
+
first_operator = operator
|
223
|
+
operator = '&'
|
224
|
+
for key, value in data.items():
|
225
|
+
|
226
|
+
field_path = key.split('__')
|
227
|
+
field = get_related_field(
|
228
|
+
self.model, '__'.join(field_path[:-1]).removeprefix('~')
|
229
|
+
)
|
230
|
+
lookup = field_path[-1]
|
231
|
+
internal_type = field.get_internal_type()
|
232
|
+
data_type = self._internal_type_to_data_type(internal_type, lookup)
|
233
|
+
ctx['tags'].append({
|
234
|
+
'lhs': self._get_query_tag_lhs(key),
|
235
|
+
'rhs': self._get_query_tag_rhs(value, internal_type, lookup),
|
236
|
+
'lookup': key,
|
237
|
+
'value': value,
|
238
|
+
'operator': operator,
|
239
|
+
'data_type': data_type,
|
240
|
+
'model_name': self.model_name
|
241
|
+
})
|
242
|
+
if ctx['tags']:
|
243
|
+
ctx['tags'][0]['operator'] = first_operator
|
244
|
+
return ctx
|
245
|
+
|
246
|
+
def _get_query_tag_lhs(self, lookup: str):
|
247
|
+
prefix = lookup.startswith('~') and '~' or ''
|
248
|
+
lookup = lookup.removeprefix('~')
|
249
|
+
parts = lookup.split('__')
|
250
|
+
assert len(parts) >= 2
|
251
|
+
related_parts = parts[:-2]
|
252
|
+
rel_model, names = get_related_model(
|
253
|
+
self.model, '__'.join(related_parts)
|
254
|
+
)
|
255
|
+
try:
|
256
|
+
names.extend([
|
257
|
+
str(rel_model._meta.get_field(parts[-2]).verbose_name),
|
258
|
+
str(self._get_lookup_label(f'{prefix}{parts[-1]}'))
|
259
|
+
])
|
260
|
+
except AttributeError:
|
261
|
+
names.extend([
|
262
|
+
str(rel_model._meta.get_field(parts[-2]).field.verbose_name),
|
263
|
+
str(self._get_lookup_label(f'{prefix}{parts[-1]}'))
|
264
|
+
])
|
265
|
+
return names[1:]
|
266
|
+
|
267
|
+
def _get_query_tag_rhs(self, value, internal_type, lookup):
|
268
|
+
if lookup == 'isnull':
|
269
|
+
return not value
|
270
|
+
if internal_type in self.TYPES_DATE:
|
271
|
+
return datetime.date.fromisoformat(value)
|
272
|
+
if internal_type in self.TYPES_DATETIME:
|
273
|
+
return datetime.datetime.fromisoformat(value)
|
274
|
+
if internal_type in self.TYPES_NUMBER:
|
275
|
+
return Decimal(value)
|
276
|
+
return value
|
277
|
+
|
278
|
+
def _get_lookup_label(self, lookup: str):
|
279
|
+
labels = {
|
280
|
+
'exact': self.LABEL_EXACT,
|
281
|
+
'~exact': self.LABEL_EXACT_NOT,
|
282
|
+
'icontains': self.LABEL_ICONTAINS,
|
283
|
+
'~icontains': self.LABEL_ICONTAINS_NOT,
|
284
|
+
'gte': self.LABEL_GTE,
|
285
|
+
'lte': self.LABEL_LTE,
|
286
|
+
'isnull': self.LABEL_SET,
|
287
|
+
'~isnull': self.LABEL_NOT_SET
|
288
|
+
}
|
289
|
+
return str(labels[lookup])
|
290
|
+
|
291
|
+
def _get_field_params(self, field):
|
292
|
+
path = self.query.get('path', '')
|
293
|
+
label = ''
|
294
|
+
name = field.name
|
295
|
+
if path:
|
296
|
+
field_path = f'{path}__{name}'
|
297
|
+
else:
|
298
|
+
field_path = name
|
299
|
+
field_type = field.get_internal_type()
|
300
|
+
if field.concrete or not field.is_relation:
|
301
|
+
label = str(field.verbose_name)
|
302
|
+
if field.is_relation:
|
303
|
+
choices = None
|
304
|
+
step = None
|
305
|
+
model = ''
|
306
|
+
if field_type in ['ForeignKey', 'OneToOneField']:
|
307
|
+
model = (
|
308
|
+
f'{field.related_model._meta.app_label}.'
|
309
|
+
f'{field.related_model._meta.model_name}'
|
310
|
+
)
|
311
|
+
if not field.concrete:
|
312
|
+
label = str(
|
313
|
+
field.related_model._meta.verbose_name_plural
|
314
|
+
)
|
315
|
+
elif field_type == 'ManyToManyField':
|
316
|
+
model = (
|
317
|
+
f'{field.remote_field.model._meta.app_label}.'
|
318
|
+
f'{field.remote_field.model._meta.model_name}'
|
319
|
+
)
|
320
|
+
if not field.concrete:
|
321
|
+
label = (
|
322
|
+
f'{field.remote_field.model._meta.verbose_name} / '
|
323
|
+
f'{field.remote_field.verbose_name}'
|
324
|
+
)
|
325
|
+
else:
|
326
|
+
step = (
|
327
|
+
hasattr(field, 'decimal_places')
|
328
|
+
and self._cast_decimal_places_to_step(field.decimal_places)
|
329
|
+
or 1
|
330
|
+
)
|
331
|
+
choices = field.choices or None
|
332
|
+
model = self.model_name
|
333
|
+
return {
|
334
|
+
'field': field,
|
335
|
+
'name': name,
|
336
|
+
'field_path': field_path,
|
337
|
+
'label': label,
|
338
|
+
'type': field_type,
|
339
|
+
'param_type': '',
|
340
|
+
'choices': choices,
|
341
|
+
'null': field.null,
|
342
|
+
'step': step,
|
343
|
+
'is_relation': field.is_relation,
|
344
|
+
'model_name': model,
|
345
|
+
}
|
346
|
+
|
347
|
+
@staticmethod
|
348
|
+
def _cast_decimal_places_to_step(decimal_places):
|
349
|
+
if not decimal_places or decimal_places < 1:
|
350
|
+
return '1'
|
351
|
+
zero_count = decimal_places - 1
|
352
|
+
return f'0.{"0" * zero_count}1'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import ast
|
4
|
+
|
5
|
+
from django.utils.deprecation import MiddlewareMixin
|
6
|
+
from django.http.response import HttpResponseRedirect, HttpResponsePermanentRedirect
|
7
|
+
|
8
|
+
from accrete.tenant import get_tenant
|
9
|
+
|
10
|
+
_logger = logging.getLogger(__name__)
|
11
|
+
|
12
|
+
|
13
|
+
class HtmxRedirectMiddleware(MiddlewareMixin):
|
14
|
+
|
15
|
+
@staticmethod
|
16
|
+
def process_response(request, response):
|
17
|
+
is_htmx = request.headers.get('HX-Request', 'false') == 'true'
|
18
|
+
if not is_htmx:
|
19
|
+
return response
|
20
|
+
is_redirect = isinstance(response, HttpResponseRedirect)
|
21
|
+
is_permanent_redirect = isinstance(response, HttpResponsePermanentRedirect)
|
22
|
+
if is_redirect or is_permanent_redirect:
|
23
|
+
response.status_code = 200
|
24
|
+
header = 'HX-Location' if is_redirect else 'HX-Redirect'
|
25
|
+
response[header] = response['Location']
|
26
|
+
|
27
|
+
tenant = get_tenant()
|
28
|
+
trigger = {'setTenant': tenant and tenant.id or 0}
|
29
|
+
res_trigger = response.get('HX-Trigger')
|
30
|
+
try:
|
31
|
+
res_trigger = res_trigger and ast.literal_eval(res_trigger) or None
|
32
|
+
except Exception as e:
|
33
|
+
_logger.warning(e)
|
34
|
+
res_trigger = None
|
35
|
+
if res_trigger:
|
36
|
+
if isinstance(res_trigger, dict):
|
37
|
+
trigger.update(res_trigger)
|
38
|
+
else:
|
39
|
+
_logger.warning(
|
40
|
+
'Response Header "HX-Trigger" '
|
41
|
+
'could not be evaluated to be a dict and is ignored!'
|
42
|
+
)
|
43
|
+
response['HX-Trigger'] = json.dumps(trigger)
|
44
|
+
return response
|
@@ -54,7 +54,7 @@ Feel free to raise an issue or submit a pull request.
|
|
54
54
|
|
55
55
|
Bulma is a **CSS** framework. As such, the sole output is a single CSS file: [bulma.css](https://github.com/jgthms/bulma/blob/master/css/bulma.css)
|
56
56
|
|
57
|
-
You can either use that file, "out of the box", or download the Sass source files to customize the [variables](https://bulma.io/documentation/
|
57
|
+
You can either use that file, "out of the box", or download the Sass source files to customize the [variables](https://bulma.io/documentation/customize/#docsNav).
|
58
58
|
|
59
59
|
There is **no** JavaScript included. People generally want to use their own JS implementation (and usually already have one). Bulma can be considered "environment agnostic": it's just the style layer on top of the logic.
|
60
60
|
|
@@ -74,7 +74,7 @@ Internet Explorer (10+) is only partially supported.
|
|
74
74
|
|
75
75
|
The documentation resides in the [docs](docs) directory, and is built with the Ruby-based [Jekyll](https://jekyllrb.com/) tool.
|
76
76
|
|
77
|
-
Browse the [online documentation here.](https://bulma.io/documentation/overview/
|
77
|
+
Browse the [online documentation here.](https://bulma.io/documentation/start/overview/)
|
78
78
|
|
79
79
|
## Related projects
|
80
80
|
|
@@ -134,6 +134,8 @@ Browse the [online documentation here.](https://bulma.io/documentation/overview/
|
|
134
134
|
| [CASE](https://case.app) | CASE is Lightweight Backend-as-a-Service with essential features: DB, Admin panel, API, JS SDK |
|
135
135
|
| [Reactive Bulma](https://github.com/NicolasOmar/reactive-bulma) | A component library based on React, Bulma, Typescript and Rollup |
|
136
136
|
|
137
|
+
<p>Browser testing via <a href="https://www.lambdatest.com/" target="_blank"><img src="https://www.lambdatest.com/resources/images/logo-white.svg" style="vertical-align: middle;margin-left:5px" width="147" height="26" /></a></p>
|
138
|
+
|
137
139
|
## Copyright and license 
|
138
140
|
|
139
141
|
Code copyright 2023 Jeremy Thomas. Code released under [the MIT license](https://github.com/jgthms/bulma/blob/master/LICENSE).
|