plutonium 0.5.0
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/.standard.yml +4 -0
- data/.vscode/extensions.json +15 -0
- data/.vscode/launch.json +7 -0
- data/.vscode/settings.json +35 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README copy.md +84 -0
- data/README.md +67 -0
- data/Rakefile +8 -0
- data/app/views/layouts/resource.html.erb +43 -0
- data/app/views/resource/_color_modes.html.erb +55 -0
- data/app/views/resource/_details.html.erb +6 -0
- data/app/views/resource/_empty_card.html.erb +12 -0
- data/app/views/resource/_flash.html.erb +9 -0
- data/app/views/resource/_form.html.erb +32 -0
- data/app/views/resource/_header.html.erb +8 -0
- data/app/views/resource/_interactive_resource_action_form.html.erb +67 -0
- data/app/views/resource/_messages.html.erb +1 -0
- data/app/views/resource/_metric_card.html.erb +16 -0
- data/app/views/resource/_nav_user.html.erb +4 -0
- data/app/views/resource/_pagination.html.erb +6 -0
- data/app/views/resource/_pagy_pagination.html.erb +15 -0
- data/app/views/resource/_resource.html.erb +1 -0
- data/app/views/resource/_resource.rabl +5 -0
- data/app/views/resource/_sidebar.html.erb +11 -0
- data/app/views/resource/_sidebar_menu.html.erb +1 -0
- data/app/views/resource/_tab_menu.html.erb +13 -0
- data/app/views/resource/_table.html.erb +78 -0
- data/app/views/resource/_table_actions.html.erb +15 -0
- data/app/views/resource/_toast.html.erb +26 -0
- data/app/views/resource/_toolbar.html.erb +22 -0
- data/app/views/resource/_toolbar_actions.html.erb +16 -0
- data/app/views/resource/_toolbar_breadcrumbs.html.erb +32 -0
- data/app/views/resource/_toolbar_search_input.erb +27 -0
- data/app/views/resource/edit.html.erb +10 -0
- data/app/views/resource/errors.rabl +3 -0
- data/app/views/resource/index.html.erb +19 -0
- data/app/views/resource/index.rabl +3 -0
- data/app/views/resource/interactive_resource_collection_action.html.erb +11 -0
- data/app/views/resource/interactive_resource_record_action.html.erb +11 -0
- data/app/views/resource/interactive_resource_recordless_action.html.erb +11 -0
- data/app/views/resource/new.html.erb +11 -0
- data/app/views/resource/readme.md +16 -0
- data/app/views/resource/show.html.erb +14 -0
- data/app/views/resource/show.rabl +3 -0
- data/brakeman.ignore +51 -0
- data/lib/active_model/validations/array_validator.rb +74 -0
- data/lib/active_model/validations/attached_validator.rb +17 -0
- data/lib/active_model/validations/url_validator.rb +51 -0
- data/lib/generators/pu/core/install/install_generator.rb +43 -0
- data/lib/generators/pu/core/install/templates/.keep +0 -0
- data/lib/generators/pu/core/install/templates/app/controllers/resource_controller.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/interactions/resource_interaction.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/models/resource_record.rb.tt +5 -0
- data/lib/generators/pu/core/install/templates/app/policies/resource_policy.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/app/presenters/resource_presenter.rb.tt +2 -0
- data/lib/generators/pu/core/install/templates/config/initializers/plutonium.rb +2 -0
- data/lib/generators/pu/core/install/templates/config/packages.rb +3 -0
- data/lib/generators/pu/gem/pagy/pagy_generator.rb +25 -0
- data/lib/generators/pu/gem/pagy/templates/.keep +0 -0
- data/lib/generators/pu/gem/pagy/templates/config/initializers/pagy.rb +4 -0
- data/lib/generators/pu/gem/rabl/rabl_generator.rb +25 -0
- data/lib/generators/pu/gem/rabl/templates/.keep +0 -0
- data/lib/generators/pu/gem/rabl/templates/config/initializers/rabl.rb +60 -0
- data/lib/generators/pu/gem/simple_form/simple_form_generator.rb +25 -0
- data/lib/generators/pu/gem/simple_form/templates/.keep +0 -0
- data/lib/generators/pu/gen/pug/pug_generator.rb +43 -0
- data/lib/generators/pu/gen/pug/templates/pug.rb.tt +23 -0
- data/lib/generators/pu/pkg/app/app_generator.rb +60 -0
- data/lib/generators/pu/pkg/app/templates/app/controllers/resource_controller.rb.tt +26 -0
- data/lib/generators/pu/pkg/app/templates/app/interactions/resource_interaction.rb.tt +4 -0
- data/lib/generators/pu/pkg/app/templates/app/policies/resource_policy.rb.tt +4 -0
- data/lib/generators/pu/pkg/app/templates/app/presenters/resource_presenter.rb.tt +4 -0
- data/lib/generators/pu/pkg/app/templates/config/routes.rb.tt +17 -0
- data/lib/generators/pu/pkg/app/templates/lib/engine.rb.tt +14 -0
- data/lib/generators/pu/pkg/feature/feature_generator.rb +44 -0
- data/lib/generators/pu/pkg/feature/templates/.keep +0 -0
- data/lib/generators/pu/pkg/feature/templates/app/controllers/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/pkg/feature/templates/app/interactions/resource_interaction.rb.tt +4 -0
- data/lib/generators/pu/pkg/feature/templates/app/models/resource_record.rb.tt +5 -0
- data/lib/generators/pu/pkg/feature/templates/app/policies/resource_policy.rb.tt +4 -0
- data/lib/generators/pu/pkg/feature/templates/app/presenters/resource_presenter.rb.tt +4 -0
- data/lib/generators/pu/pkg/feature/templates/lib/engine.rb.tt +8 -0
- data/lib/generators/pu/resource/conn/conn_generator.rb +54 -0
- data/lib/generators/pu/resource/conn/templates/.keep +0 -0
- data/lib/generators/pu/resource/conn/templates/app/controllers/resource_controller.rb.tt +3 -0
- data/lib/generators/pu/resource/conn/templates/app/policies/resource_policy.rb.tt +3 -0
- data/lib/generators/pu/resource/conn/templates/app/presenters/resource_presenter.rb.tt +3 -0
- data/lib/generators/pu/resource/model/USAGE +113 -0
- data/lib/generators/pu/resource/model/model_generator.rb +163 -0
- data/lib/generators/pu/resource/model/templates/controller.rb.tt +5 -0
- data/lib/generators/pu/resource/model/templates/create_table_migration.rb.tt +26 -0
- data/lib/generators/pu/resource/model/templates/model.rb.tt +53 -0
- data/lib/generators/pu/resource/model/templates/module.rb.tt +7 -0
- data/lib/generators/pu/resource/model/templates/policy.rb.tt +4 -0
- data/lib/generators/pu/resource/model/templates/presenter.rb.tt +4 -0
- data/lib/generators/pu/resource/scaffold/scaffold_generator.rb +219 -0
- data/lib/generators/pu/resource/scaffold/templates/app/controllers/admin_resources/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/controllers/entity_resources/resource_controller.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/admin/resource_policy.rb.tt +22 -0
- data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/entity/resource_policy.rb.tt +22 -0
- data/lib/generators/pu/resource/scaffold/templates/app/policies/resources/resource_policy.rb.tt +13 -0
- data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/admin_presenter.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/entity_presenter.rb.tt +7 -0
- data/lib/generators/pu/resource/scaffold/templates/app/resources/resource/presenter.rb.tt +23 -0
- data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.html.erb.tt +3 -0
- data/lib/generators/pu/resource/scaffold/templates/app/views/resources/resource/_resource.rabl +7 -0
- data/lib/generators/pu/rodauth/account_generator.rb +120 -0
- data/lib/generators/pu/rodauth/concerns/account_selector.rb +22 -0
- data/lib/generators/pu/rodauth/concerns/configuration.rb +211 -0
- data/lib/generators/pu/rodauth/concerns/feature_selector.rb +125 -0
- data/lib/generators/pu/rodauth/install_generator.rb +69 -0
- data/lib/generators/pu/rodauth/migration/active_record/account_expiration.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/active_sessions.erb +7 -0
- data/lib/generators/pu/rodauth/migration/active_record/audit_logging.erb +16 -0
- data/lib/generators/pu/rodauth/migration/active_record/base.erb +22 -0
- data/lib/generators/pu/rodauth/migration/active_record/disallow_password_reuse.erb +5 -0
- data/lib/generators/pu/rodauth/migration/active_record/email_auth.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/jwt_refresh.erb +7 -0
- data/lib/generators/pu/rodauth/migration/active_record/lockout.erb +13 -0
- data/lib/generators/pu/rodauth/migration/active_record/otp.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/password_expiration.erb +6 -0
- data/lib/generators/pu/rodauth/migration/active_record/recovery_codes.erb +6 -0
- data/lib/generators/pu/rodauth/migration/active_record/remember.erb +7 -0
- data/lib/generators/pu/rodauth/migration/active_record/reset_password.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/separate_passwords.erb +5 -0
- data/lib/generators/pu/rodauth/migration/active_record/single_session.erb +6 -0
- data/lib/generators/pu/rodauth/migration/active_record/sms_codes.erb +9 -0
- data/lib/generators/pu/rodauth/migration/active_record/verify_account.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/verify_login_change.erb +8 -0
- data/lib/generators/pu/rodauth/migration/active_record/webauthn.erb +13 -0
- data/lib/generators/pu/rodauth/migration/sequel/account_expiration.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/active_sessions.erb +8 -0
- data/lib/generators/pu/rodauth/migration/sequel/audit_logging.erb +17 -0
- data/lib/generators/pu/rodauth/migration/sequel/base.erb +25 -0
- data/lib/generators/pu/rodauth/migration/sequel/disallow_password_reuse.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/email_auth.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/jwt_refresh.erb +8 -0
- data/lib/generators/pu/rodauth/migration/sequel/lockout.erb +11 -0
- data/lib/generators/pu/rodauth/migration/sequel/otp.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/password_expiration.erb +5 -0
- data/lib/generators/pu/rodauth/migration/sequel/recovery_codes.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/remember.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/reset_password.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/separate_passwords.erb +6 -0
- data/lib/generators/pu/rodauth/migration/sequel/single_session.erb +5 -0
- data/lib/generators/pu/rodauth/migration/sequel/sms_codes.erb +8 -0
- data/lib/generators/pu/rodauth/migration/sequel/verify_account.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/verify_login_change.erb +7 -0
- data/lib/generators/pu/rodauth/migration/sequel/webauthn.erb +13 -0
- data/lib/generators/pu/rodauth/migration_generator.rb +190 -0
- data/lib/generators/pu/rodauth/templates/INSTRUCTIONS +52 -0
- data/lib/generators/pu/rodauth/templates/app/controllers/plugin_controller.rb.tt +6 -0
- data/lib/generators/pu/rodauth/templates/app/controllers/rodauth_controller.rb.tt +3 -0
- data/lib/generators/pu/rodauth/templates/app/mailers/account_mailer.rb.tt +4 -0
- data/lib/generators/pu/rodauth/templates/app/mailers/rodauth_mailer.rb.tt +62 -0
- data/lib/generators/pu/rodauth/templates/app/misc/account_rodauth_plugin.rb.tt +255 -0
- data/lib/generators/pu/rodauth/templates/app/misc/rodauth_app.rb.tt +24 -0
- data/lib/generators/pu/rodauth/templates/app/misc/rodauth_plugin.rb.tt +234 -0
- data/lib/generators/pu/rodauth/templates/app/models/account.rb.tt +40 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/_email_auth_request_form.html.erb +7 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form.html.erb +26 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/_login_form_footer.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/add_recovery_codes.html.erb +6 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_login.html.erb +27 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/change_password.html.erb +27 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/close_account.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/confirm_password.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/create_account.html.erb +35 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/email_auth.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/login.html.erb +4 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/logout.html.erb +14 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/multi_phase_login.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_auth.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_disable.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/otp_setup.html.erb +41 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_auth.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/recovery_codes.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/remember.html.erb +22 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password.html.erb +19 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/reset_password_request.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_auth.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_confirm.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_disable.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_request.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/sms_setup.html.erb +23 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_email_auth_request_form.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form.html.erb +24 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/_login_form_footer.html.erb +7 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/add_recovery_codes.html.erb +16 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_login.html.erb +25 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/change_password.html.erb +25 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/close_account.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/confirm_password.html.erb +19 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/create_account.html.erb +33 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/email_auth.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/login.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/logout.html.erb +10 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/multi_phase_login.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_auth.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_disable.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/otp_setup.html.erb +32 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_auth.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/recovery_codes.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/remember.html.erb +18 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/reset_password_request.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_auth.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_confirm.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_disable.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_request.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/sms_setup.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_auth.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_disable.html.erb +11 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/two_factor_manage.html.erb +26 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/unlock_account_request.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account.html.erb +19 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_account_resend.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/verify_login_change.html.erb +3 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_auth.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_autofill.html.erb +10 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_remove.html.erb +21 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/tailwind/webauthn_setup.html.erb +21 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_auth.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_disable.html.erb +13 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/two_factor_manage.html.erb +22 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/unlock_account_request.html.erb +9 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account.html.erb +21 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_account_resend.html.erb +17 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/verify_login_change.html.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_auth.html.erb +15 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_autofill.html.erb +10 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_remove.html.erb +23 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth/webauthn_setup.html.erb +23 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/email_auth.text.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/password_changed.text.erb +2 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password.text.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/reset_password_notify.text.erb +2 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/unlock_account.text.erb +5 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_account.text.erb +4 -0
- data/lib/generators/pu/rodauth/templates/app/views/rodauth_mailer/verify_login_change.text.erb +10 -0
- data/lib/generators/pu/rodauth/templates/config/initializers/rodauth.rb.tt +3 -0
- data/lib/generators/pu/rodauth/templates/db/migrate/create_rodauth.rb.tt +13 -0
- data/lib/generators/pu/rodauth/views_generator.rb +125 -0
- data/lib/plutonium/auth/public_access.rb +17 -0
- data/lib/plutonium/auth/rodauth.rb +35 -0
- data/lib/plutonium/auth.rb +12 -0
- data/lib/plutonium/config.rb +11 -0
- data/lib/plutonium/core/.DS_Store +0 -0
- data/lib/plutonium/core/action.rb +46 -0
- data/lib/plutonium/core/actions/basic_action.rb +16 -0
- data/lib/plutonium/core/actions/collection.rb +33 -0
- data/lib/plutonium/core/actions/destroy_action.rb +21 -0
- data/lib/plutonium/core/actions/edit_action.rb +19 -0
- data/lib/plutonium/core/actions/interactive_action.rb +64 -0
- data/lib/plutonium/core/actions/new_action.rb +18 -0
- data/lib/plutonium/core/actions/show_action.rb +17 -0
- data/lib/plutonium/core/actions.rb +17 -0
- data/lib/plutonium/core/app_controller.rb +121 -0
- data/lib/plutonium/core/autodiscovery/discoverer.rb +15 -0
- data/lib/plutonium/core/autodiscovery/input_discoverer.rb +33 -0
- data/lib/plutonium/core/autodiscovery/renderer_discoverer.rb +33 -0
- data/lib/plutonium/core/autodiscovery.rb +13 -0
- data/lib/plutonium/core/controllers/authorizable.rb +56 -0
- data/lib/plutonium/core/controllers/bootable.rb +44 -0
- data/lib/plutonium/core/controllers/crud_actions.rb +128 -0
- data/lib/plutonium/core/controllers/entity_scoping.rb +69 -0
- data/lib/plutonium/core/controllers/interactive_actions.rb +210 -0
- data/lib/plutonium/core/controllers/presentable.rb +59 -0
- data/lib/plutonium/core/controllers.rb +16 -0
- data/lib/plutonium/core/definers/action_definer.rb +25 -0
- data/lib/plutonium/core/definers/field_definer.rb +19 -0
- data/lib/plutonium/core/definers/input_definer.rb +37 -0
- data/lib/plutonium/core/definers/renderer_definer.rb +35 -0
- data/lib/plutonium/core/definers.rb +14 -0
- data/lib/plutonium/core/fields/inputs/association_input.rb +26 -0
- data/lib/plutonium/core/fields/inputs/basic_input.rb +42 -0
- data/lib/plutonium/core/fields/inputs/belongs_to_input.rb +15 -0
- data/lib/plutonium/core/fields/inputs/factory.rb +58 -0
- data/lib/plutonium/core/fields/inputs/has_many_input.rb +15 -0
- data/lib/plutonium/core/fields/inputs/noop_input.rb +19 -0
- data/lib/plutonium/core/fields/inputs.rb +18 -0
- data/lib/plutonium/core/fields/renderers/association_renderer.rb +25 -0
- data/lib/plutonium/core/fields/renderers/basic_renderer.rb +27 -0
- data/lib/plutonium/core/fields/renderers/factory.rb +52 -0
- data/lib/plutonium/core/fields/renderers.rb +15 -0
- data/lib/plutonium/core/fields.rb +12 -0
- data/lib/plutonium/core/ui/collection.rb +14 -0
- data/lib/plutonium/core/ui/detail.rb +11 -0
- data/lib/plutonium/core/ui/form.rb +11 -0
- data/lib/plutonium/core/ui.rb +13 -0
- data/lib/plutonium/core.rb +16 -0
- data/lib/plutonium/helpers/action_buttons_helper.rb +32 -0
- data/lib/plutonium/helpers/application_helper.rb +22 -0
- data/lib/plutonium/helpers/attachment_helper.rb +62 -0
- data/lib/plutonium/helpers/content_helper.rb +66 -0
- data/lib/plutonium/helpers/display_helper.rb +83 -0
- data/lib/plutonium/helpers/form_helper.rb +24 -0
- data/lib/plutonium/helpers/menu_helper.rb +69 -0
- data/lib/plutonium/helpers/pagination_helper.rb +9 -0
- data/lib/plutonium/helpers/turbo_helper.rb +13 -0
- data/lib/plutonium/helpers/turbo_stream_actions_helper.rb +9 -0
- data/lib/plutonium/helpers.rb +31 -0
- data/lib/plutonium/initializers/TODO +2 -0
- data/lib/plutonium/initializers/pagy.rb +5 -0
- data/lib/plutonium/initializers/patches.rb +2 -0
- data/lib/plutonium/initializers/rabl.rb +60 -0
- data/lib/plutonium/initializers/simple_form.rb +405 -0
- data/lib/plutonium/lib/after_commit.rb +34 -0
- data/lib/plutonium/lib/bit_flags.rb +36 -0
- data/lib/plutonium/packaging/app.rb +125 -0
- data/lib/plutonium/packaging/feature.rb +18 -0
- data/lib/plutonium/packaging/package.rb +22 -0
- data/lib/plutonium/packaging.rb +9 -0
- data/lib/plutonium/policy/initializer.rb +22 -0
- data/lib/plutonium/policy/scope.rb +19 -0
- data/lib/plutonium/policy.rb +8 -0
- data/lib/plutonium/preserved__/field.rb +65 -0
- data/lib/plutonium/preserved__/input.rb +93 -0
- data/lib/plutonium/reactor/core.rb +61 -0
- data/lib/plutonium/reactor/resource_context.rb +15 -0
- data/lib/plutonium/reactor/resource_controller.rb +108 -0
- data/lib/plutonium/reactor/resource_interaction.rb +8 -0
- data/lib/plutonium/reactor/resource_policy.rb +105 -0
- data/lib/plutonium/reactor/resource_presenter.rb +42 -0
- data/lib/plutonium/reactor/resource_record.rb +123 -0
- data/lib/plutonium/reactor.rb +13 -0
- data/lib/plutonium/refinements/parameter_refinements.rb +26 -0
- data/lib/plutonium/simple_form_components/attachment_component.rb +77 -0
- data/lib/plutonium/simple_form_components/input_group_component.rb +14 -0
- data/lib/plutonium/version.rb +3 -0
- data/lib/plutonium.rb +31 -0
- data/plutonium.gemspec +47 -0
- data/public/.keep +0 -0
- data/public/plutonium-assets/application.css +24280 -0
- data/public/plutonium-assets/application.js +31420 -0
- data/public/plutonium-assets/fonts/bootstrap-icons.woff +0 -0
- data/public/plutonium-assets/fonts/bootstrap-icons.woff2 +0 -0
- data/public/plutonium-assets/logo.png +0 -0
- data/sig/plutonium.rbs +4 -0
- metadata +519 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
require "simple_form"
|
|
2
|
+
|
|
3
|
+
# Register components
|
|
4
|
+
Dir[Plutonium.lib_root.join("simple_form_components", "*.rb")].each { |component| require component }
|
|
5
|
+
|
|
6
|
+
# Use this setup block to configure all options available in SimpleForm.
|
|
7
|
+
SimpleForm.setup do |config|
|
|
8
|
+
# Tell browsers whether to use the native HTML5 validations (novalidate form option).
|
|
9
|
+
config.browser_validations = true
|
|
10
|
+
|
|
11
|
+
# Custom mappings for input types. This should be a hash containing a regexp
|
|
12
|
+
|
|
13
|
+
# Disable country select
|
|
14
|
+
config.input_mappings = {/country/ => :select}
|
|
15
|
+
|
|
16
|
+
# Default class for buttons
|
|
17
|
+
config.button_class = "btn"
|
|
18
|
+
|
|
19
|
+
# Define the default class of the input wrapper of the boolean input.
|
|
20
|
+
config.boolean_label_class = "form-check-label"
|
|
21
|
+
|
|
22
|
+
# How the label text should be generated altogether with the required text.
|
|
23
|
+
config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
|
|
24
|
+
|
|
25
|
+
# Define the way to render check boxes / radio buttons with labels.
|
|
26
|
+
config.boolean_style = :inline
|
|
27
|
+
|
|
28
|
+
# You can wrap each item in a collection of radio/check boxes with a tag
|
|
29
|
+
config.item_wrapper_tag = :div
|
|
30
|
+
|
|
31
|
+
# Defines if the default input wrapper class should be included in radio
|
|
32
|
+
# collection wrappers.
|
|
33
|
+
config.include_default_input_wrapper_class = false
|
|
34
|
+
|
|
35
|
+
# CSS class to add for error notification helper.
|
|
36
|
+
config.error_notification_class = "alert alert-danger"
|
|
37
|
+
|
|
38
|
+
# Method used to tidy up errors. Specify any Rails Array method.
|
|
39
|
+
# :first lists the first message for each field.
|
|
40
|
+
# :to_sentence to list all errors for each field.
|
|
41
|
+
config.error_method = :to_sentence
|
|
42
|
+
|
|
43
|
+
# add validation classes to `input_field`
|
|
44
|
+
config.input_field_error_class = "is-invalid"
|
|
45
|
+
config.input_field_valid_class = "is-valid"
|
|
46
|
+
|
|
47
|
+
# vertical forms
|
|
48
|
+
#
|
|
49
|
+
# vertical default_wrapper
|
|
50
|
+
config.wrappers :vertical_form, class: "mb-3" do |b|
|
|
51
|
+
b.use :html5
|
|
52
|
+
b.use :placeholder
|
|
53
|
+
b.use :maxlength
|
|
54
|
+
b.use :minlength
|
|
55
|
+
b.optional :pattern
|
|
56
|
+
b.use :min_max
|
|
57
|
+
b.optional :readonly
|
|
58
|
+
b.use :label, class: "form-label"
|
|
59
|
+
b.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
60
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
61
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# vertical input for boolean
|
|
65
|
+
config.wrappers :vertical_boolean, tag: "fieldset", class: "mb-3" do |b|
|
|
66
|
+
b.use :html5
|
|
67
|
+
b.optional :readonly
|
|
68
|
+
b.wrapper :form_check_wrapper, class: "form-check" do |bb|
|
|
69
|
+
bb.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
70
|
+
bb.use :label, class: "form-check-label"
|
|
71
|
+
bb.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
72
|
+
bb.use :hint, wrap_with: {class: "form-text"}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# vertical input for radio buttons and check boxes
|
|
77
|
+
config.wrappers :vertical_collection, item_wrapper_class: "form-check", item_label_class: "form-check-label",
|
|
78
|
+
tag: "fieldset", class: "mb-3" do |b|
|
|
79
|
+
b.use :html5
|
|
80
|
+
b.optional :readonly
|
|
81
|
+
b.use :label, class: "form-label"
|
|
82
|
+
b.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
83
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback d-block"}
|
|
84
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# vertical input for inline radio buttons and check boxes
|
|
88
|
+
config.wrappers :vertical_collection_inline, item_wrapper_class: "form-check form-check-inline",
|
|
89
|
+
item_label_class: "form-check-label", tag: "fieldset", class: "mb-3" do |b|
|
|
90
|
+
b.use :html5
|
|
91
|
+
b.optional :readonly
|
|
92
|
+
b.wrapper :legend_tag, tag: "legend", class: "col-form-label pt-0" do |ba|
|
|
93
|
+
ba.use :label_text
|
|
94
|
+
end
|
|
95
|
+
b.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
96
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback d-block"}
|
|
97
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# vertical file input
|
|
101
|
+
config.wrappers :vertical_file, class: "mb-3" do |b|
|
|
102
|
+
b.use :html5
|
|
103
|
+
b.use :placeholder
|
|
104
|
+
b.optional :maxlength
|
|
105
|
+
b.optional :minlength
|
|
106
|
+
b.optional :readonly
|
|
107
|
+
b.use :label, class: "form-label"
|
|
108
|
+
b.wrapper tag: "div", html: {style: "display: flex; flex-direction: column-reverse;"} do |ba|
|
|
109
|
+
ba.optional :attachment
|
|
110
|
+
ba.wrapper tag: "div" do |bc|
|
|
111
|
+
bc.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
112
|
+
bc.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
113
|
+
bc.use :hint, wrap_with: {class: "form-text"}
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# vertical select input
|
|
119
|
+
config.wrappers :vertical_select, class: "mb-3" do |b|
|
|
120
|
+
b.use :html5
|
|
121
|
+
b.optional :readonly
|
|
122
|
+
b.use :label, class: "form-label"
|
|
123
|
+
b.use :input, class: "form-select", error_class: "is-invalid", valid_class: "is-valid"
|
|
124
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
125
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# vertical multi select
|
|
129
|
+
config.wrappers :vertical_multi_select, class: "mb-3" do |b|
|
|
130
|
+
b.use :html5
|
|
131
|
+
b.optional :readonly
|
|
132
|
+
b.use :label, class: "form-label"
|
|
133
|
+
b.wrapper class: "d-flex flex-row justify-content-between align-items-center" do |ba|
|
|
134
|
+
ba.use :input, class: "form-select mx-1", error_class: "is-invalid", valid_class: "is-valid"
|
|
135
|
+
end
|
|
136
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback d-block"}
|
|
137
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# vertical range input
|
|
141
|
+
config.wrappers :vertical_range, class: "mb-3" do |b|
|
|
142
|
+
b.use :html5
|
|
143
|
+
b.use :placeholder
|
|
144
|
+
b.optional :readonly
|
|
145
|
+
b.optional :step
|
|
146
|
+
b.use :label, class: "form-label"
|
|
147
|
+
b.use :input, class: "form-range", error_class: "is-invalid", valid_class: "is-valid"
|
|
148
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
149
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# horizontal forms
|
|
153
|
+
#
|
|
154
|
+
# horizontal default_wrapper
|
|
155
|
+
config.wrappers :horizontal_form, class: "row mb-3" do |b|
|
|
156
|
+
b.use :html5
|
|
157
|
+
b.use :placeholder
|
|
158
|
+
b.use :maxlength
|
|
159
|
+
b.use :minlength
|
|
160
|
+
b.optional :pattern
|
|
161
|
+
b.use :min_max
|
|
162
|
+
b.optional :readonly
|
|
163
|
+
b.use :label, class: "col-sm-3 col-form-label"
|
|
164
|
+
b.wrapper :grid_wrapper, class: "col-sm-9" do |ba|
|
|
165
|
+
ba.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
166
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
167
|
+
ba.use :hint, wrap_with: {class: "form-text"}
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# horizontal input for boolean
|
|
172
|
+
config.wrappers :horizontal_boolean, class: "row mb-3" do |b|
|
|
173
|
+
b.use :html5
|
|
174
|
+
b.optional :readonly
|
|
175
|
+
b.wrapper :grid_wrapper, class: "col-sm-9 offset-sm-3" do |wr|
|
|
176
|
+
wr.wrapper :form_check_wrapper, class: "form-check" do |bb|
|
|
177
|
+
bb.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
178
|
+
bb.use :label, class: "form-check-label"
|
|
179
|
+
bb.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
180
|
+
bb.use :hint, wrap_with: {class: "form-text"}
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# horizontal input for radio buttons and check boxes
|
|
186
|
+
config.wrappers :horizontal_collection, item_wrapper_class: "form-check", item_label_class: "form-check-label",
|
|
187
|
+
class: "row mb-3" do |b|
|
|
188
|
+
b.use :html5
|
|
189
|
+
b.optional :readonly
|
|
190
|
+
b.use :label, class: "col-sm-3 col-form-label pt-0"
|
|
191
|
+
b.wrapper :grid_wrapper, class: "col-sm-9" do |ba|
|
|
192
|
+
ba.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
193
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback d-block"}
|
|
194
|
+
ba.use :hint, wrap_with: {class: "form-text"}
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# horizontal input for inline radio buttons and check boxes
|
|
199
|
+
config.wrappers :horizontal_collection_inline, item_wrapper_class: "form-check form-check-inline",
|
|
200
|
+
item_label_class: "form-check-label", class: "row mb-3" do |b|
|
|
201
|
+
b.use :html5
|
|
202
|
+
b.optional :readonly
|
|
203
|
+
b.use :label, class: "col-sm-3 col-form-label pt-0"
|
|
204
|
+
b.wrapper :grid_wrapper, class: "col-sm-9" do |ba|
|
|
205
|
+
ba.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
206
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback d-block"}
|
|
207
|
+
ba.use :hint, wrap_with: {class: "form-text"}
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# horizontal file input
|
|
212
|
+
config.wrappers :horizontal_file, class: "row mb-3" do |b|
|
|
213
|
+
b.use :html5
|
|
214
|
+
b.use :placeholder
|
|
215
|
+
b.optional :maxlength
|
|
216
|
+
b.optional :minlength
|
|
217
|
+
b.optional :readonly
|
|
218
|
+
b.use :label, class: "col-sm-3 col-form-label"
|
|
219
|
+
b.wrapper tag: "div", html: {style: "display: flex; flex-direction: column-reverse;"} do |ba|
|
|
220
|
+
ba.optional :attachment
|
|
221
|
+
ba.wrapper :grid_wrapper, class: "col-sm-9" do |bc|
|
|
222
|
+
bc.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
223
|
+
bc.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
224
|
+
bc.use :hint, wrap_with: {class: "form-text"}
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# horizontal select input
|
|
230
|
+
config.wrappers :horizontal_select, class: "row mb-3" do |b|
|
|
231
|
+
b.use :html5
|
|
232
|
+
b.optional :readonly
|
|
233
|
+
b.use :label, class: "col-sm-3 col-form-label"
|
|
234
|
+
b.wrapper :grid_wrapper, class: "col-sm-9" do |ba|
|
|
235
|
+
ba.use :input, class: "form-select", error_class: "is-invalid", valid_class: "is-valid"
|
|
236
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
237
|
+
ba.use :hint, wrap_with: {class: "form-text"}
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# horizontal multi select
|
|
242
|
+
config.wrappers :horizontal_multi_select, class: "row mb-3" do |b|
|
|
243
|
+
b.use :html5
|
|
244
|
+
b.optional :readonly
|
|
245
|
+
b.use :label, class: "col-sm-3 col-form-label"
|
|
246
|
+
b.wrapper :grid_wrapper, class: "col-sm-9" do |ba|
|
|
247
|
+
ba.wrapper class: "d-flex flex-row justify-content-between align-items-center" do |bb|
|
|
248
|
+
bb.use :input, class: "form-select mx-1", error_class: "is-invalid", valid_class: "is-valid"
|
|
249
|
+
end
|
|
250
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback d-block"}
|
|
251
|
+
ba.use :hint, wrap_with: {class: "form-text"}
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# horizontal range input
|
|
256
|
+
config.wrappers :horizontal_range, class: "row mb-3" do |b|
|
|
257
|
+
b.use :html5
|
|
258
|
+
b.use :placeholder
|
|
259
|
+
b.optional :readonly
|
|
260
|
+
b.optional :step
|
|
261
|
+
b.use :label, class: "col-sm-3 col-form-label pt-0"
|
|
262
|
+
b.wrapper :grid_wrapper, class: "col-sm-9" do |ba|
|
|
263
|
+
ba.use :input, class: "form-range", error_class: "is-invalid", valid_class: "is-valid"
|
|
264
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
265
|
+
ba.use :hint, wrap_with: {class: "form-text"}
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# inline forms
|
|
270
|
+
#
|
|
271
|
+
# inline default_wrapper
|
|
272
|
+
config.wrappers :inline_form, class: "col-12" do |b|
|
|
273
|
+
b.use :html5
|
|
274
|
+
b.use :placeholder
|
|
275
|
+
b.use :maxlength
|
|
276
|
+
b.use :minlength
|
|
277
|
+
b.optional :pattern
|
|
278
|
+
b.use :min_max
|
|
279
|
+
b.optional :readonly
|
|
280
|
+
b.use :label, class: "visually-hidden"
|
|
281
|
+
|
|
282
|
+
b.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
283
|
+
b.use :error, wrap_with: {class: "invalid-feedback"}
|
|
284
|
+
b.optional :hint, wrap_with: {class: "form-text"}
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# inline input for boolean
|
|
288
|
+
config.wrappers :inline_boolean, class: "col-12" do |b|
|
|
289
|
+
b.use :html5
|
|
290
|
+
b.optional :readonly
|
|
291
|
+
b.wrapper :form_check_wrapper, class: "form-check" do |bb|
|
|
292
|
+
bb.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
293
|
+
bb.use :label, class: "form-check-label"
|
|
294
|
+
bb.use :error, wrap_with: {class: "invalid-feedback"}
|
|
295
|
+
bb.optional :hint, wrap_with: {class: "form-text"}
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# bootstrap custom forms
|
|
300
|
+
#
|
|
301
|
+
# custom input switch for boolean
|
|
302
|
+
config.wrappers :custom_boolean_switch, class: "mb-3" do |b|
|
|
303
|
+
b.use :html5
|
|
304
|
+
b.optional :readonly
|
|
305
|
+
b.wrapper :form_check_wrapper, tag: "div", class: "form-check form-switch" do |bb|
|
|
306
|
+
bb.use :input, class: "form-check-input", error_class: "is-invalid", valid_class: "is-valid"
|
|
307
|
+
bb.use :label, class: "form-check-label"
|
|
308
|
+
bb.use :full_error, wrap_with: {tag: "div", class: "invalid-feedback"}
|
|
309
|
+
bb.use :hint, wrap_with: {class: "form-text"}
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# Input Group - custom component
|
|
314
|
+
# see example app and config at https://github.com/heartcombo/simple_form-bootstrap
|
|
315
|
+
config.wrappers :input_group, class: "mb-3" do |b|
|
|
316
|
+
b.use :html5
|
|
317
|
+
b.use :placeholder
|
|
318
|
+
b.use :maxlength
|
|
319
|
+
b.use :minlength
|
|
320
|
+
b.optional :pattern
|
|
321
|
+
b.use :min_max
|
|
322
|
+
b.optional :readonly
|
|
323
|
+
b.use :label, class: "form-label"
|
|
324
|
+
b.wrapper :input_group_tag, class: "input-group" do |ba|
|
|
325
|
+
ba.optional :prepend
|
|
326
|
+
ba.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
327
|
+
ba.optional :append
|
|
328
|
+
ba.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
329
|
+
end
|
|
330
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Floating Labels form
|
|
334
|
+
#
|
|
335
|
+
# floating labels default_wrapper
|
|
336
|
+
config.wrappers :floating_labels_form, class: "form-floating mb-3" do |b|
|
|
337
|
+
b.use :html5
|
|
338
|
+
b.use :placeholder
|
|
339
|
+
b.use :maxlength
|
|
340
|
+
b.use :minlength
|
|
341
|
+
b.optional :pattern
|
|
342
|
+
b.use :min_max
|
|
343
|
+
b.optional :readonly
|
|
344
|
+
b.use :input, class: "form-control", error_class: "is-invalid", valid_class: "is-valid"
|
|
345
|
+
b.use :label
|
|
346
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
347
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# custom multi select
|
|
351
|
+
config.wrappers :floating_labels_select, class: "form-floating mb-3" do |b|
|
|
352
|
+
b.use :html5
|
|
353
|
+
b.optional :readonly
|
|
354
|
+
b.use :input, class: "form-select", error_class: "is-invalid", valid_class: "is-valid"
|
|
355
|
+
b.use :label
|
|
356
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
357
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# slim-select
|
|
361
|
+
config.wrappers :slim_select, class: "mb-3" do |b|
|
|
362
|
+
b.optional :placeholder
|
|
363
|
+
b.optional :readonly
|
|
364
|
+
b.use :label, class: "form-label"
|
|
365
|
+
b.use :input, error_class: "is-invalid", valid_class: "is-valid", data: {controller: "slim-select"}
|
|
366
|
+
b.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
367
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# quill
|
|
371
|
+
config.wrappers :quill, class: "mb-3" do |b|
|
|
372
|
+
b.use :label, class: "form-label"
|
|
373
|
+
b.wrapper tag: :div, html: {data: {controller: "quill-editor"}} do |quill|
|
|
374
|
+
quill.wrapper(tag: :div,
|
|
375
|
+
html: {
|
|
376
|
+
data: {quill_editor_target: "editor"}
|
|
377
|
+
}) {}
|
|
378
|
+
quill.use :input, error_class: "is-invalid", valid_class: "is-valid", class: "d-none",
|
|
379
|
+
data: {quill_editor_target: "input"}
|
|
380
|
+
quill.use :full_error, wrap_with: {class: "invalid-feedback"}
|
|
381
|
+
end
|
|
382
|
+
b.use :hint, wrap_with: {class: "form-text"}
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# TODO: this will conflict with existing apps that use simple_form.
|
|
386
|
+
# A workaround would be to ensure their initializer loads after ours.
|
|
387
|
+
# Since this is for will deal with it when we get there
|
|
388
|
+
|
|
389
|
+
# The default wrapper to be used by the FormBuilder.
|
|
390
|
+
config.default_wrapper = :vertical_form
|
|
391
|
+
|
|
392
|
+
# Custom wrappers for input types. This should be a hash containing an input
|
|
393
|
+
# type as key and the wrapper that will be used for all inputs with specified type.
|
|
394
|
+
config.wrapper_mappings = {
|
|
395
|
+
boolean: :vertical_boolean,
|
|
396
|
+
check_boxes: :vertical_collection,
|
|
397
|
+
date: :vertical_multi_select,
|
|
398
|
+
datetime: :vertical_multi_select,
|
|
399
|
+
file: :vertical_file,
|
|
400
|
+
radio_buttons: :vertical_collection,
|
|
401
|
+
range: :vertical_range,
|
|
402
|
+
time: :vertical_multi_select,
|
|
403
|
+
select: :vertical_select
|
|
404
|
+
}
|
|
405
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plutonium
|
|
4
|
+
module Lib
|
|
5
|
+
class AfterCommit
|
|
6
|
+
def initialize(rolled_back: false, &block)
|
|
7
|
+
@rolled_back = rolled_back
|
|
8
|
+
@callback = block
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def committed!(*)
|
|
12
|
+
@callback.call
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def before_committed!(*)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def rolledback!(*)
|
|
19
|
+
@callback.call if @rolled_back
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def trigger_transactional_callbacks?
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class << self
|
|
27
|
+
def execute(rolled_back: false, connection: ActiveRecord::Base.connection, &block)
|
|
28
|
+
connection.transaction_open? ? connection.add_transaction_record(AfterCommit.new(rolled_back: rolled_back, &block)) : yield
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module Plutonium
|
|
2
|
+
module Lib
|
|
3
|
+
class BitFlags
|
|
4
|
+
delegate :sum, to: :indices
|
|
5
|
+
|
|
6
|
+
def initialize(*flags)
|
|
7
|
+
@map = flags.each_with_index.map { |flag, index| [flag, 2.pow(index)] }.to_h
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def set?(value, *flags)
|
|
11
|
+
check = bits(*flags)
|
|
12
|
+
value & check == check
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def extract(value)
|
|
16
|
+
@map.select { |_flag, bit| value & bit == bit }.keys
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def [](*flags)
|
|
20
|
+
bits(*flags)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def bits(*flags)
|
|
24
|
+
@map.slice(*flags).values.sum
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def flags
|
|
28
|
+
@flags ||= @map.keys
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def indices
|
|
32
|
+
@indices ||= @map.values
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
module Plutonium
|
|
2
|
+
module Packaging
|
|
3
|
+
module App
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
include Package
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
isolate_namespace to_s.deconstantize.constantize
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class_methods do
|
|
12
|
+
attr_reader :scoped_entity_class, :scoped_entity_param_key, :scoped_entity_strategy
|
|
13
|
+
|
|
14
|
+
def scope_to_entity(entity_class, param_key: nil, strategy: :path)
|
|
15
|
+
@scoped_entity_class = entity_class
|
|
16
|
+
@scoped_entity_strategy = strategy
|
|
17
|
+
@scoped_entity_param_key = param_key || entity_class.model_name.singular_route_key.to_sym
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def scoped_to_entity?
|
|
21
|
+
scoped_entity_class.present?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize_register!
|
|
25
|
+
# this exists solely to support hot reloads
|
|
26
|
+
# if the user has modified the register especially if they removed a registration, we have no way of telling
|
|
27
|
+
# so instead we start over
|
|
28
|
+
@resource_register = []
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def register_resource(resource)
|
|
32
|
+
@resource_register.append resource
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def resource_register
|
|
36
|
+
@resource_register || []
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def registered_resource_route_key_lookup
|
|
40
|
+
@registered_resource_route_key_lookup = resource_register.map { |resource|
|
|
41
|
+
[resource.model_name.singular_route_key.to_sym, resource]
|
|
42
|
+
}.to_h
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def draw_resource_routes
|
|
46
|
+
registered_resources = resource_register
|
|
47
|
+
scoped_entity_param_key = self.scoped_entity_param_key
|
|
48
|
+
routes.draw do
|
|
49
|
+
shared_resource_concerns = [:interactive_resource_actions] # TODO: make this a config parameter
|
|
50
|
+
concern :interactive_resource_actions do
|
|
51
|
+
# these concerns power the interactive actions feature
|
|
52
|
+
member do
|
|
53
|
+
get "record_actions/:interactive_action", action: :begin_interactive_resource_record_action,
|
|
54
|
+
as: :interactive_resource_record_action
|
|
55
|
+
post "record_actions/:interactive_action", action: :commit_interactive_resource_record_action
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
collection do
|
|
59
|
+
get "collection_actions/:interactive_action", action: :begin_interactive_resource_collection_action,
|
|
60
|
+
as: :interactive_resource_collection_action
|
|
61
|
+
post "collection_actions/:interactive_action", action: :commit_interactive_resource_collection_action
|
|
62
|
+
|
|
63
|
+
get "recordless_actions/:interactive_action", action: :begin_interactive_resource_recordless_action,
|
|
64
|
+
as: :interactive_resource_recordless_action
|
|
65
|
+
post "recordless_actions/:interactive_action", action: :commit_interactive_resource_recordless_action
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
resource_route_names = []
|
|
70
|
+
resource_route_opts_lookup = {}
|
|
71
|
+
# for each of our registered resources, we are registering the routes required
|
|
72
|
+
registered_resources.each do |resource|
|
|
73
|
+
resource_name = resource.to_s # Deeply::Namespaced::ResourceModel
|
|
74
|
+
resource_controller = resource_name.pluralize.underscore # deeply/namespaced/resource_models
|
|
75
|
+
resource_route = resource.model_name.plural # deeply_namespaced_resource_models
|
|
76
|
+
resource_route_name = :"#{resource_route}_routes" # deeply_namespaced_resource_models_routes
|
|
77
|
+
|
|
78
|
+
resource_route_opts = {}
|
|
79
|
+
# rails is not smart enough to infer Deeply::Namespaced::ResourceModelsController from deeply_namespaced_resource_models
|
|
80
|
+
# since we are heavy on namespaces, we choose to be explicit to guarantee there is no confusion
|
|
81
|
+
resource_route_opts[:controller] = resource_controller
|
|
82
|
+
# using collection for path is much nicer than the alternative
|
|
83
|
+
# e.g. deeply/namespaced/resource_models vs deeply_namespaced_resource_models
|
|
84
|
+
resource_route_opts[:path] = resource.model_name.collection
|
|
85
|
+
resource_route_opts_lookup[resource_route] = resource_route_opts
|
|
86
|
+
|
|
87
|
+
# defining our resources with concerns allows us to defer materializing till later,
|
|
88
|
+
# ensuring that resource_route_opts_lookup is populated
|
|
89
|
+
concern resource_route_name do
|
|
90
|
+
resources resource_route, **resource_route_opts, concerns: shared_resource_concerns do
|
|
91
|
+
nested_resources_route_opts = resource_route_opts_lookup.slice(*resource.has_many_association_routes)
|
|
92
|
+
nested_resources_route_opts.each do |nested_resource_route, nested_resource_route_opts|
|
|
93
|
+
resources nested_resource_route, **nested_resource_route_opts, concerns: shared_resource_concerns
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
resource_route_names << resource_route_name
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# materialize our routes using a scope
|
|
101
|
+
# if the app is scoped to an entity, ensure that the expected route param and url helper prefix are specified.
|
|
102
|
+
|
|
103
|
+
# path => /:entity/deeply/namespaced/resource_models/:deeply_namespaced_resource_model_id/
|
|
104
|
+
# helper => entity_deeply_namespaced_resource_models_path
|
|
105
|
+
scope_name = scoped_entity_param_key.present? ? ":#{scoped_entity_param_key}" : ""
|
|
106
|
+
|
|
107
|
+
# path => /deeply/namespaced/resource_models/:deeply_namespaced_resource_model_id/
|
|
108
|
+
# helper => deeply_namespaced_resource_models_path
|
|
109
|
+
scope_options = scoped_entity_param_key.present? ? {as: scoped_entity_param_key} : {}
|
|
110
|
+
|
|
111
|
+
scope scope_name, scope_options do
|
|
112
|
+
# we have to reverse sort our resource routes in order to prevent routing conflicts
|
|
113
|
+
# e.g. /blogs/1 and blogs/comments cause an issue if Blog is registered before Blogs::Comment
|
|
114
|
+
# attempting to load blogs/comments routes to blogs/:id which fails with a 404 since BlogsController
|
|
115
|
+
# essentially performs a Blog.find('comments')
|
|
116
|
+
# since the route names for these 2 will be 'blogs' and 'blog_comments',
|
|
117
|
+
# reverse sorting ensures that blog_comments is registered first, preventing the issue described above
|
|
118
|
+
concerns resource_route_names.sort.reverse
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Plutonium
|
|
2
|
+
module Packaging
|
|
3
|
+
module Feature
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
include Package
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
initializer :append_migrations do |app|
|
|
9
|
+
unless app.root.to_s.match root.to_s
|
|
10
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
|
11
|
+
app.config.paths["db/migrate"] << expanded_path
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Plutonium
|
|
2
|
+
module Packaging
|
|
3
|
+
module Package
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
# prevent this package from being added to the view lookup
|
|
8
|
+
# since we need finer control over how views are resolved.
|
|
9
|
+
# view lookup configuration is handled at the controller level
|
|
10
|
+
config.before_configuration do
|
|
11
|
+
# this touches the internals of rails, but I could not find a good way of doing this
|
|
12
|
+
# we get the initializer instance and set the block property to a noop
|
|
13
|
+
# There is no error handling, to ensure we know when it breaks.
|
|
14
|
+
add_view_paths_initializer = Rails.application.initializers.find do |a|
|
|
15
|
+
a.context_class == self && a.name.to_s == "add_view_paths"
|
|
16
|
+
end
|
|
17
|
+
add_view_paths_initializer.instance_variable_set(:@block, ->(app) {})
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "pundit"
|
|
2
|
+
|
|
3
|
+
module Plutonium
|
|
4
|
+
module Policy
|
|
5
|
+
module Initializer
|
|
6
|
+
def initialize(context, record)
|
|
7
|
+
authorize!(context)
|
|
8
|
+
|
|
9
|
+
@context = context
|
|
10
|
+
@record = record
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
attr_reader :context, :record
|
|
16
|
+
|
|
17
|
+
def authorize!(context)
|
|
18
|
+
raise Pundit::NotAuthorizedError, "must be logged in" unless context&.user
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|