underworld 1.0.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/LICENSE +339 -0
- data/Rakefile +48 -0
- data/app/assets/fonts/DroidNaskh-Bold.ttf +0 -0
- data/app/assets/fonts/DroidNaskh-Regular.ttf +0 -0
- data/app/assets/fonts/OpenSans-Bold.ttf +0 -0
- data/app/assets/fonts/OpenSans-BoldItalic.ttf +0 -0
- data/app/assets/fonts/OpenSans-ExtraBold.ttf +0 -0
- data/app/assets/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
- data/app/assets/fonts/OpenSans-Italic.ttf +0 -0
- data/app/assets/fonts/OpenSans-Light.ttf +0 -0
- data/app/assets/fonts/OpenSans-LightItalic.ttf +0 -0
- data/app/assets/fonts/OpenSans-Regular.ttf +0 -0
- data/app/assets/fonts/OpenSans-Semibold.ttf +0 -0
- data/app/assets/fonts/OpenSans-SemiboldItalic.ttf +0 -0
- data/app/assets/images/underworld/select2-spinner.gif +0 -0
- data/app/assets/images/underworld/select2.png +0 -0
- data/app/assets/images/underworld/select2x2.png +0 -0
- data/app/assets/javascripts/underworld/application.js +16 -0
- data/app/assets/javascripts/underworld/dashboard/application.js.erb +30 -0
- data/app/assets/javascripts/underworld/dashboard/functions.js.erb +50 -0
- data/app/assets/javascripts/underworld/dashboard/init.js.coffee +33 -0
- data/app/assets/javascripts/underworld/dashboard/lib/actions.js +7 -0
- data/app/assets/javascripts/underworld/dashboard/lib/amd.js.coffee.erb +0 -0
- data/app/assets/javascripts/underworld/dashboard/lib/flash_message.js +71 -0
- data/app/assets/javascripts/underworld/dashboard/lib/locale.js +14 -0
- data/app/assets/javascripts/underworld/dashboard/lib/misc.js +5 -0
- data/app/assets/javascripts/underworld/dashboard/lib/string.js +3 -0
- data/app/assets/javascripts/underworld/dashboard/lib/ujs_patches.js.coffee +28 -0
- data/app/assets/javascripts/underworld/dashboard/manifest.js +5 -0
- data/app/assets/javascripts/underworld/dashboard/variables.js.erb +6 -0
- data/app/assets/javascripts/underworld/groups.js +2 -0
- data/app/assets/javascripts/underworld/home.js +2 -0
- data/app/assets/javascripts/underworld/i18n.js +13 -0
- data/app/assets/javascripts/underworld/simple.js +20 -0
- data/app/assets/javascripts/underworld/users.js +2 -0
- data/app/assets/stylesheets/underworld/dashboard/loadindicator.scss +17 -0
- data/app/assets/stylesheets/underworld/dashboard/ltr/application.css +38 -0
- data/app/assets/stylesheets/underworld/dashboard/ltr/base.css.scss +0 -0
- data/app/assets/stylesheets/underworld/dashboard/rtl/application.css +11 -0
- data/app/assets/stylesheets/underworld/dashboard/rtl/base.css.scss +0 -0
- data/app/assets/stylesheets/underworld/dashboard/share.scss +62 -0
- data/app/assets/stylesheets/underworld/dashboard/variables.scss +9 -0
- data/app/assets/stylesheets/underworld/ltr/application.css +0 -0
- data/app/assets/stylesheets/underworld/rtl/application.css +0 -0
- data/app/assets/stylesheets/underworld/simple/ltr/application.css +2 -0
- data/app/assets/stylesheets/underworld/simple/rtl/application.css +2 -0
- data/app/assets/stylesheets/underworld/simple/rtl/rtl.scss +16 -0
- data/app/assets/stylesheets/underworld/simple/share.scss +11 -0
- data/app/controllers/underworld/api_controller.rb +133 -0
- data/app/controllers/underworld/application_controller.rb +16 -0
- data/app/controllers/underworld/assets_controller.rb +6 -0
- data/app/controllers/underworld/dashboard/application_controller.rb +43 -0
- data/app/controllers/underworld/dashboard/groups_controller.rb +85 -0
- data/app/controllers/underworld/dashboard/profile_controller.rb +49 -0
- data/app/controllers/underworld/dashboard/user_messages_controller.rb +27 -0
- data/app/controllers/underworld/dashboard/users_controller.rb +116 -0
- data/app/controllers/underworld/dashboard_controller.rb +16 -0
- data/app/controllers/underworld/omniauth/callbacks_controller.rb +24 -0
- data/app/helpers/underworld/application_helper.rb +4 -0
- data/app/helpers/underworld/dashboard_helper.rb +107 -0
- data/app/helpers/underworld/groups_helper.rb +4 -0
- data/app/helpers/underworld/home_helper.rb +4 -0
- data/app/helpers/underworld/users_helper.rb +8 -0
- data/app/models/application_record.rb +3 -0
- data/app/models/underworld/concerns/assignment.rb +16 -0
- data/app/models/underworld/concerns/user/auth_definitions.rb +87 -0
- data/app/models/underworld/concerns/user/gravatar.rb +11 -0
- data/app/models/underworld/concerns/user/mongoid_fields.rb +81 -0
- data/app/models/underworld/concerns/user/permission.rb +47 -0
- data/app/models/underworld/concerns/user/user_roles.rb +24 -0
- data/app/models/underworld/group.rb +57 -0
- data/app/models/underworld/permission.rb +43 -0
- data/app/models/underworld/user.rb +81 -0
- data/app/models/underworld/user_message.rb +6 -0
- data/app/policies/underworld/admin_only_policy.rb +66 -0
- data/app/policies/underworld/application_policy.rb +55 -0
- data/app/policies/underworld/group_policy.rb +8 -0
- data/app/policies/underworld/user_message_policy.rb +9 -0
- data/app/policies/underworld/user_policy.rb +9 -0
- data/app/views/angular/auth/groups/details.html +2 -0
- data/app/views/angular/auth/groups/index.html +2 -0
- data/app/views/angular/auth/groups/new.html +2 -0
- data/app/views/angular/auth/index.html +30 -0
- data/app/views/angular/auth/profile/edit.html +54 -0
- data/app/views/angular/auth/users/details.html +28 -0
- data/app/views/angular/auth/users/index.html +6 -0
- data/app/views/angular/auth/users/new.html +57 -0
- data/app/views/angular/conversations/details.html +19 -0
- data/app/views/angular/conversations/index.html +13 -0
- data/app/views/angular/conversations/new.html +39 -0
- data/app/views/angular/conversations/show.html +6 -0
- data/app/views/angular/conversations/show_details.html +15 -0
- data/app/views/angular/fields/boolean/boolean.html +4 -0
- data/app/views/angular/fields/control-combo/control-list.html +19 -0
- data/app/views/angular/fields/datetime/datetime.html +10 -0
- data/app/views/angular/fields/datetime/time.html +25 -0
- data/app/views/angular/fields/file/file.html.slim +0 -0
- data/app/views/angular/fields/float/float.html +4 -0
- data/app/views/angular/fields/image/image.html +1 -0
- data/app/views/angular/fields/integer/integer.html +4 -0
- data/app/views/angular/fields/relation/relation.html +44 -0
- data/app/views/angular/fields/string/string.html +22 -0
- data/app/views/angular/fields/tag/tag.html +1 -0
- data/app/views/angular/fields/text/text.html +4 -0
- data/app/views/angular/filter/index.html +15 -0
- data/app/views/angular/index.html +3 -0
- data/app/views/angular/locale/fa.po +25 -0
- data/app/views/angular/locale/templates.pot +24 -0
- data/app/views/angular/logs/index.html +6 -0
- data/app/views/angular/modules.html +0 -0
- data/app/views/angular/nav.html.erb +39 -0
- data/app/views/angular/underworld/views/generic_add_view.html.slim +5 -0
- data/app/views/devise/registrations/edit.html.erb +29 -0
- data/app/views/devise/registrations/new.html.erb +38 -0
- data/app/views/devise/sessions/new.html.erb +37 -0
- data/app/views/devise/shared/_links.erb +19 -0
- data/app/views/devise/shared/_omni_link.erb +33 -0
- data/app/views/kaminari/_first_page.html.slim +3 -0
- data/app/views/kaminari/_gap.html.slim +2 -0
- data/app/views/kaminari/_last_page.html.slim +3 -0
- data/app/views/kaminari/_next_page.html.slim +3 -0
- data/app/views/kaminari/_page.html.slim +3 -0
- data/app/views/kaminari/_paginator.html.slim +13 -0
- data/app/views/kaminari/_prev_page.html.slim +3 -0
- data/app/views/layouts/underworld/application.html.erb +79 -0
- data/app/views/layouts/underworld/dashboard.html.erb +52 -0
- data/app/views/layouts/underworld/simple.html.erb +27 -0
- data/app/views/underworld/api/v1/conversations/create.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/conversations/destroy.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/conversations/index.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/conversations/reply.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/conversations/show.json.jbuilder +14 -0
- data/app/views/underworld/api/v1/conversations/trash.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/groups/create.json.jbuilder +4 -0
- data/app/views/underworld/api/v1/groups/destroy.html.erb +2 -0
- data/app/views/underworld/api/v1/groups/destroy.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/groups/edit.html.erb +2 -0
- data/app/views/underworld/api/v1/groups/index.html.erb +2 -0
- data/app/views/underworld/api/v1/groups/index.json.jbuilder +6 -0
- data/app/views/underworld/api/v1/groups/new.html.erb +2 -0
- data/app/views/underworld/api/v1/groups/show.html.erb +2 -0
- data/app/views/underworld/api/v1/groups/show.json.jbuilder +5 -0
- data/app/views/underworld/api/v1/groups/update.json.jbuilder +4 -0
- data/app/views/underworld/api/v1/logs/index.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/permissions/index.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/permissions/user_permissions.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/users/create.html.erb +2 -0
- data/app/views/underworld/api/v1/users/create.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/users/destroy.json.jbuilder +1 -0
- data/app/views/underworld/api/v1/users/distroy.html.erb +2 -0
- data/app/views/underworld/api/v1/users/edit.html.erb +2 -0
- data/app/views/underworld/api/v1/users/index.html.erb +2 -0
- data/app/views/underworld/api/v1/users/index.json.jbuilder +4 -0
- data/app/views/underworld/api/v1/users/show.html.erb +2 -0
- data/app/views/underworld/api/v1/users/show.json.jbuilder +2 -0
- data/app/views/underworld/api/v1/users/update.json.jbuilder +1 -0
- data/app/views/underworld/dashboard/groups/_form.html.slim +68 -0
- data/app/views/underworld/dashboard/groups/create.js.erb +3 -0
- data/app/views/underworld/dashboard/groups/edit.html.slim +3 -0
- data/app/views/underworld/dashboard/groups/errors.js.erb +3 -0
- data/app/views/underworld/dashboard/groups/index.html.slim +47 -0
- data/app/views/underworld/dashboard/groups/new.html.slim +2 -0
- data/app/views/underworld/dashboard/groups/update.js.erb +3 -0
- data/app/views/underworld/dashboard/index.html.erb +0 -0
- data/app/views/underworld/dashboard/login_required_page.html.erb +5 -0
- data/app/views/underworld/dashboard/not_found.html.slim +9 -0
- data/app/views/underworld/dashboard/not_found.js.erb +1 -0
- data/app/views/underworld/dashboard/profile/_form.html.erb +33 -0
- data/app/views/underworld/dashboard/profile/_profile_form.html.erb +33 -0
- data/app/views/underworld/dashboard/profile/create.js.erb +3 -0
- data/app/views/underworld/dashboard/profile/edit.html.erb +2 -0
- data/app/views/underworld/dashboard/profile/edit_password.html.erb +2 -0
- data/app/views/underworld/dashboard/profile/errors.js.erb +3 -0
- data/app/views/underworld/dashboard/resource/_form.html.slim +33 -0
- data/app/views/underworld/dashboard/resource/_input.html.slim +3 -0
- data/app/views/underworld/dashboard/resource/create.js.erb +3 -0
- data/app/views/underworld/dashboard/resource/destroy.js.erb +2 -0
- data/app/views/underworld/dashboard/resource/edit.html.slim +3 -0
- data/app/views/underworld/dashboard/resource/index.html.slim +60 -0
- data/app/views/underworld/dashboard/resource/new.html.slim +2 -0
- data/app/views/underworld/dashboard/resource/show.html.slim +22 -0
- data/app/views/underworld/dashboard/resource/update.js.erb +3 -0
- data/app/views/underworld/dashboard/shared/_content_header.html.slim +15 -0
- data/app/views/underworld/dashboard/shared/_control_sidebar.html.slim +50 -0
- data/app/views/underworld/dashboard/shared/_footer.html.slim +7 -0
- data/app/views/underworld/dashboard/shared/_header.html.erb +98 -0
- data/app/views/underworld/dashboard/shared/_sidebar.html.erb +69 -0
- data/app/views/underworld/dashboard/shared/_toolbar.html.slim +0 -0
- data/app/views/underworld/dashboard/shared/errors.js.erb +3 -0
- data/app/views/underworld/dashboard/user_messages/_form.html.slim +0 -0
- data/app/views/underworld/dashboard/user_messages/create.js.erb +0 -0
- data/app/views/underworld/dashboard/user_messages/destroy.js.erb +0 -0
- data/app/views/underworld/dashboard/user_messages/new.html.slim +72 -0
- data/app/views/underworld/dashboard/users/_form.html.slim +73 -0
- data/app/views/underworld/dashboard/users/_password_form.html.slim +37 -0
- data/app/views/underworld/dashboard/users/create.js.erb +3 -0
- data/app/views/underworld/dashboard/users/destroy.js.erb +2 -0
- data/app/views/underworld/dashboard/users/edit.html.slim +3 -0
- data/app/views/underworld/dashboard/users/edit_password.html.slim +1 -0
- data/app/views/underworld/dashboard/users/errors.js.erb +3 -0
- data/app/views/underworld/dashboard/users/index.html.slim +66 -0
- data/app/views/underworld/dashboard/users/new.html.slim +2 -0
- data/app/views/underworld/dashboard/users/show.html.slim +6 -0
- data/app/views/underworld/dashboard/users/update.js.erb +3 -0
- data/app/views/underworld/dashboard/users/update_password.js.erb +3 -0
- data/app/views/underworld/relations/_belongs_to.json.jbuilder +11 -0
- data/config/initializers/devise.rb +24 -0
- data/config/locales/devise.en.yml +59 -0
- data/config/locales/devise.fa.yml +58 -0
- data/config/locales/underworld.en.yml +96 -0
- data/config/locales/underworld.fa.yml +108 -0
- data/config/routes.rb +43 -0
- data/config/spring.rb +1 -0
- data/db/migrate/20131013091000_devise_create_underworld_users.rb +65 -0
- data/db/migrate/20131020124701_create_underworld_groups.rb +15 -0
- data/db/migrate/20131021170923_create_underworld_permissions.rb +15 -0
- data/db/migrate/20131123120422_add_permissions_groups_table.rb +16 -0
- data/db/migrate/20140613120923_add_users_groups_table.rb +13 -0
- data/db/migrate/20151122115129_add_uniqueness_index_to_users_groups.rb +11 -0
- data/db/migrate/20160310105736_create_underworld_user_messages.rb +25 -0
- data/db/seeds.rb +49 -0
- data/lib/generators/underworld/install_generator.rb +108 -0
- data/lib/generators/underworld/resource_generator.rb +70 -0
- data/lib/generators/underworld/resources_generator.rb +20 -0
- data/lib/generators/underworld/templates/README +21 -0
- data/lib/generators/underworld/templates/SPECS +13 -0
- data/lib/generators/underworld/templates/api/controller.rb.erb +60 -0
- data/lib/generators/underworld/templates/api_controller.rb +2 -0
- data/lib/generators/underworld/templates/dashboard/controller.rb.erb +2 -0
- data/lib/generators/underworld/templates/dashboard_controller.rb +18 -0
- data/lib/generators/underworld/templates/devise.rb +251 -0
- data/lib/generators/underworld/templates/features/api.feature +92 -0
- data/lib/generators/underworld/templates/features/api.step.rb +7 -0
- data/lib/generators/underworld/templates/features/step_definitions/email_steps.rb +206 -0
- data/lib/generators/underworld/templates/features/support/email_spec.rb +1 -0
- data/lib/generators/underworld/templates/features/support/env.rb +79 -0
- data/lib/generators/underworld/templates/javascripts/application.js +19 -0
- data/lib/generators/underworld/templates/policy/application_policy.rb +2 -0
- data/lib/generators/underworld/templates/policy/policy.rb.erb +2 -0
- data/lib/generators/underworld/templates/seeds.rb +1 -0
- data/lib/generators/underworld/templates/spec/factories/groups.rb +5 -0
- data/lib/generators/underworld/templates/spec/factories/users.rb +10 -0
- data/lib/generators/underworld/templates/spec/spec_helper.rb +69 -0
- data/lib/generators/underworld/templates/spec/support/devise.rb +3 -0
- data/lib/generators/underworld/templates/stylesheets/dashboard/ltr/application.css +3 -0
- data/lib/generators/underworld/templates/stylesheets/dashboard/rtl/application.css +3 -0
- data/lib/generators/underworld/templates/stylesheets/ltr/application.css +3 -0
- data/lib/generators/underworld/templates/stylesheets/rtl/application.css +3 -0
- data/lib/generators/underworld/templates/underworld.rb +12 -0
- data/lib/generators/underworld/templates/views/create.json.jbuilder.erb +3 -0
- data/lib/generators/underworld/templates/views/destroy.json.jbuilder.erb +1 -0
- data/lib/generators/underworld/templates/views/index.json.jbuilder.erb +13 -0
- data/lib/generators/underworld/templates/views/show.json.jbuilder.erb +6 -0
- data/lib/generators/underworld/templates/views/update.json.jbuilder.erb +6 -0
- data/lib/generators/underworld/views_generator.rb +57 -0
- data/lib/tasks/docs.rake +6 -0
- data/lib/tasks/sync.rake +9 -0
- data/lib/tasks/underworld_tasks.rake +38 -0
- data/lib/underworld.rb +35 -0
- data/lib/underworld/action_dispatch.rb +3 -0
- data/lib/underworld/api.rb +42 -0
- data/lib/underworld/api/groups_api.rb +41 -0
- data/lib/underworld/api/permissions_api.rb +24 -0
- data/lib/underworld/api/root.rb +15 -0
- data/lib/underworld/api/users_api.rb +20 -0
- data/lib/underworld/concerns.rb +7 -0
- data/lib/underworld/concerns/authorizable.rb +81 -0
- data/lib/underworld/configuration.rb +97 -0
- data/lib/underworld/dashboard.rb +11 -0
- data/lib/underworld/dashboard/dsl.rb +41 -0
- data/lib/underworld/dashboard/dsl/base.rb +133 -0
- data/lib/underworld/dashboard/dsl/create.rb +116 -0
- data/lib/underworld/dashboard/dsl/form_fields_properties.rb +62 -0
- data/lib/underworld/dashboard/dsl/index.rb +45 -0
- data/lib/underworld/dashboard/dsl/show.rb +6 -0
- data/lib/underworld/dashboard/dsl/update.rb +6 -0
- data/lib/underworld/dashboard/helpers/box_helpers.rb +129 -0
- data/lib/underworld/dashboard/models.rb +2 -0
- data/lib/underworld/dashboard/models/sidebar.rb +139 -0
- data/lib/underworld/dashboard/sections.rb +2 -0
- data/lib/underworld/dashboard/sections/resource.rb +229 -0
- data/lib/underworld/dashboard/sections/resource_create.rb +263 -0
- data/lib/underworld/dashboard/sections/resource_destroy.rb +27 -0
- data/lib/underworld/dashboard/sections/resource_show.rb +96 -0
- data/lib/underworld/dashboard/sections/resources_index.rb +113 -0
- data/lib/underworld/dashboard/sections/sidebar.rb +41 -0
- data/lib/underworld/discovery.rb +8 -0
- data/lib/underworld/discovery/permissions.rb +49 -0
- data/lib/underworld/engine.rb +53 -0
- data/lib/underworld/exceptions.rb +7 -0
- data/lib/underworld/extension.rb +18 -0
- data/lib/underworld/extension/base.rb +29 -0
- data/lib/underworld/fake_assets.rb +5 -0
- data/lib/underworld/i18n.rb +101 -0
- data/lib/underworld/initialize.rb +0 -0
- data/lib/underworld/liquid.rb +7 -0
- data/lib/underworld/liquid/block.rb +14 -0
- data/lib/underworld/liquid/render_tag.rb +50 -0
- data/lib/underworld/liquid/tag.rb +51 -0
- data/lib/underworld/middlewares.rb +1 -0
- data/lib/underworld/middlewares/locale.rb +29 -0
- data/lib/underworld/omniauth.rb +8 -0
- data/lib/underworld/omniauth/callbacks.rb +39 -0
- data/lib/underworld/orm.rb +30 -0
- data/lib/underworld/routes.rb +117 -0
- data/lib/underworld/version.rb +3 -0
- data/test/controllers/underworld/dashboard/resource_test.rb +118 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/javascripts/dashboard/application.js +19 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/assets/stylesheets/dashboard/ltr/application.css +3 -0
- data/test/dummy/app/assets/stylesheets/dashboard/rtl/application.css +3 -0
- data/test/dummy/app/assets/stylesheets/ltr/application.css +3 -0
- data/test/dummy/app/assets/stylesheets/rtl/application.css +3 -0
- data/test/dummy/app/controllers/api_controller.rb +2 -0
- data/test/dummy/app/controllers/application_controller.rb +6 -0
- data/test/dummy/app/controllers/dashboard/application_controller.rb +18 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/policies/application_policy.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +23 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +38 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/devise.rb +251 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/formstatic.rb +76 -0
- data/test/dummy/config/initializers/formtastic.rb +110 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/kaminari_config.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/underworld.rb +11 -0
- data/test/dummy/config/initializers/underworld_assets.rb +1 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +13 -0
- data/test/dummy/lib/templates/slim/scaffold/_form.html.slim +8 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fabricators/underworld/groups.rb +27 -0
- data/test/fabricators/underworld/permissions.rb +14 -0
- data/test/fabricators/underworld/users.rb +17 -0
- data/test/generators/install_generator_test.rb +84 -0
- data/test/integration/underworld/authentication_test.rb +36 -0
- data/test/integration/underworld/dashboard_test.rb +64 -0
- data/test/test_helper.rb +72 -0
- metadata +1045 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
module Underworld::Dashboard::Models
|
|
2
|
+
class Item
|
|
3
|
+
|
|
4
|
+
attr_reader :title, :url, :icon, :model, :members_only
|
|
5
|
+
def initialize(title, options)
|
|
6
|
+
@title = title
|
|
7
|
+
@model = nil
|
|
8
|
+
extract_options(options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def visible?(user)
|
|
12
|
+
return true if @model.nil?
|
|
13
|
+
|
|
14
|
+
if @model.respond_to? :map
|
|
15
|
+
permissions = @model.map do |model|
|
|
16
|
+
# Find the appropriate policy for each model
|
|
17
|
+
# and authorize the user against that.
|
|
18
|
+
Pundit.policy!(user, model.to_sym).index?
|
|
19
|
+
end
|
|
20
|
+
# If user don't have access to none of the models
|
|
21
|
+
# then the menu should not be visible
|
|
22
|
+
permissions.any?
|
|
23
|
+
else
|
|
24
|
+
|
|
25
|
+
# Authorize the menu visibility against user and given model
|
|
26
|
+
Pundit.policy!(user, @model.to_sym).index?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
def extract_options(options)
|
|
32
|
+
options.each do |key, value|
|
|
33
|
+
instance_variable_set("@#{key}", value)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Menu < Item
|
|
39
|
+
def children
|
|
40
|
+
@children || []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def add_child(child)
|
|
44
|
+
@children ||= []
|
|
45
|
+
@children << child
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def initialize(title, options)
|
|
49
|
+
children = options.delete :children
|
|
50
|
+
if children
|
|
51
|
+
@children = children.map do |child|
|
|
52
|
+
Item.new(child.delete(:title), child)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
super
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class RootMenu < Array
|
|
60
|
+
alias :add_child :<<
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class Sidebar
|
|
64
|
+
|
|
65
|
+
include ActionView::Helpers::TranslationHelper
|
|
66
|
+
|
|
67
|
+
def initialize(title, **options)
|
|
68
|
+
@title = title
|
|
69
|
+
extract_options(options)
|
|
70
|
+
@tree = RootMenu.new
|
|
71
|
+
@current_node = @tree
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def children
|
|
75
|
+
@tree
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def title
|
|
79
|
+
@title || I18n.t('underworld.dashboard.sidebar.title')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def menu(name, **options, &block)
|
|
83
|
+
item = Menu.new(name, options)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@current_node.add_child item
|
|
87
|
+
|
|
88
|
+
prev_node = @current_node
|
|
89
|
+
@current_node = item
|
|
90
|
+
|
|
91
|
+
block.call if block_given?
|
|
92
|
+
|
|
93
|
+
@current_node = prev_node
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def item(name, **options)
|
|
97
|
+
item = Item.new(name, options)
|
|
98
|
+
@current_node.add_child item
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def underworld_entries
|
|
102
|
+
menu(t('underworld.dashboard.user_management'),
|
|
103
|
+
icon: 'fa fa-users',
|
|
104
|
+
model: 'Underworld::User') do
|
|
105
|
+
item(I18n.t('underworld.dashboard.users'),
|
|
106
|
+
model: 'Underworld::User',
|
|
107
|
+
url: Underworld::Engine.routes.url_helpers.dashboard_auth_users_path)
|
|
108
|
+
|
|
109
|
+
item(I18n.t('underworld.dashboard.groups'),
|
|
110
|
+
model: 'Underworld::Group',
|
|
111
|
+
url: Underworld::Engine.routes.url_helpers.dashboard_auth_groups_path)
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
menu(t('underworld.dashboard.user_message'),
|
|
116
|
+
icon: 'fa fa-envelope-o',
|
|
117
|
+
model: 'Underworld::UserMessage') do
|
|
118
|
+
|
|
119
|
+
item(I18n.t('underworld.dashboard.user_messages.inbox'),
|
|
120
|
+
model: 'Underworld::UserMessage',
|
|
121
|
+
url: Underworld::Engine.routes.url_helpers.dashboard_user_messages_path)
|
|
122
|
+
item(I18n.t('underworld.dashboard.user_messages.sent'),
|
|
123
|
+
model: 'Underworld::UserMessage',
|
|
124
|
+
url: Underworld::Engine.routes.url_helpers.dashboard_user_messages_path)
|
|
125
|
+
item(I18n.t('underworld.dashboard.user_messages.draft'),
|
|
126
|
+
model: 'Underworld::UserMessage',
|
|
127
|
+
url: Underworld::Engine.routes.url_helpers.dashboard_user_messages_path)
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
private
|
|
133
|
+
def extract_options(options)
|
|
134
|
+
@icon = options.delete(:icon)
|
|
135
|
+
@id = options.delete(:id)
|
|
136
|
+
@class = options.delete(:class)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
module Underworld::Dashboard::Sections
|
|
2
|
+
# This module contains several helpers method which would
|
|
3
|
+
# be useful for the rest of underworld dashboard operation.
|
|
4
|
+
module Resource
|
|
5
|
+
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
included do |base|
|
|
9
|
+
base.before_action :setup_named_routes
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def _resource_title
|
|
13
|
+
controller_name.humanize
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
def _resources
|
|
19
|
+
instance_variable_get("@{plural_name")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def plural_name
|
|
23
|
+
controller_name.underscore
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def model_name
|
|
27
|
+
"::#{controller_path.gsub('dashboard/', '').classify}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def model
|
|
31
|
+
model_name.constantize
|
|
32
|
+
rescue
|
|
33
|
+
msg = "Can't find model '#{model_name}'. Please override 'model' method in your dashboard controller."
|
|
34
|
+
fail NameError, msg
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def _namespace
|
|
38
|
+
pieces = controller_path.gsub('dashboard/', '').split('/')
|
|
39
|
+
return '' if pieces.length == 1
|
|
40
|
+
|
|
41
|
+
pieces.pop
|
|
42
|
+
pieces.join('/')
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def _route_engine
|
|
46
|
+
if _namespace.empty?
|
|
47
|
+
Rails.application
|
|
48
|
+
else
|
|
49
|
+
engine = "#{_namespace.split('/')[0]}::Engine".classify
|
|
50
|
+
if Object.const_defined? engine
|
|
51
|
+
engine.constantize
|
|
52
|
+
else
|
|
53
|
+
logger.info 'You are using locale modules please define route_engine in your controller'
|
|
54
|
+
Rails.application
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Return the array of action buttons in given `property_object`.
|
|
60
|
+
# `property_object` is an instance of once of DSL classes.
|
|
61
|
+
def action_buttons(property_object)
|
|
62
|
+
@_action_buttons = property_object.action_buttons || []
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def _engine
|
|
66
|
+
nil
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
def _route_name
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def attachment_fields
|
|
76
|
+
if model.respond_to? :attachment_definitions
|
|
77
|
+
return model.attachment_definitions.keys
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
[]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def has_attachment?
|
|
84
|
+
!attachment_fields.empty?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def _index_route
|
|
88
|
+
if respond_to? :index
|
|
89
|
+
url_for(controller: params[:controller],
|
|
90
|
+
action: :index)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def _show_route(id)
|
|
95
|
+
if respond_to? :show
|
|
96
|
+
url_for(controller: params[:controller],
|
|
97
|
+
action: :show,
|
|
98
|
+
id: id)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def _edit_route(id)
|
|
103
|
+
if respond_to? :edit
|
|
104
|
+
url_for(controller: params[:controller],
|
|
105
|
+
action: :edit,
|
|
106
|
+
id: id)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def _new_route
|
|
111
|
+
if respond_to? :new
|
|
112
|
+
url_for(controller: params[:controller], action: :new)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def setup_named_routes
|
|
117
|
+
@engine = _engine || _route_engine
|
|
118
|
+
@index_route = method(:_index_route)
|
|
119
|
+
@new_route = method(:_new_route)
|
|
120
|
+
@show_route = method(:_show_route)
|
|
121
|
+
@edit_route = method(:_edit_route)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def successful_response(section, msg = nil)
|
|
125
|
+
@_msg = msg
|
|
126
|
+
|
|
127
|
+
respond_to do |f|
|
|
128
|
+
if _override_views.include? section.to_sym
|
|
129
|
+
f.js
|
|
130
|
+
f.html
|
|
131
|
+
else
|
|
132
|
+
flash[:success] = msg
|
|
133
|
+
|
|
134
|
+
f.js { render "underworld/dashboard/resource/#{section}" }
|
|
135
|
+
f.html { redirect_to _index_route }
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def errorful_resopnse(section, msg = nil, &block)
|
|
141
|
+
@_msg = msg
|
|
142
|
+
|
|
143
|
+
respond_to do |f|
|
|
144
|
+
if _override_views.include? section.to_sym
|
|
145
|
+
f.js { render :errors }
|
|
146
|
+
f.html { render :errors }
|
|
147
|
+
else
|
|
148
|
+
flash[:error] = msg
|
|
149
|
+
|
|
150
|
+
f.js { render 'underworld/dashboard/shared/errors' }
|
|
151
|
+
if block_given?
|
|
152
|
+
f.html(&block)
|
|
153
|
+
else
|
|
154
|
+
f.html { redirect_to _index_route }
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# TODO: Move this method to a suitable place
|
|
161
|
+
def symbolify_keys(hash)
|
|
162
|
+
hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# The actual DSL for resource ages
|
|
166
|
+
module ClassMethods
|
|
167
|
+
# Via this method user can specify the engine or application name
|
|
168
|
+
# which current resource is defined under. Default value is:
|
|
169
|
+
# Rails.application
|
|
170
|
+
def route_engine(name = nil, &block)
|
|
171
|
+
define_method(:_route_engine) do
|
|
172
|
+
return block.call if block_given?
|
|
173
|
+
return name unless name.nil?
|
|
174
|
+
fail 'You have to provide a name or a block'
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Via this method user can specify the name of current resource
|
|
179
|
+
# scope, Default value is `dashboard`
|
|
180
|
+
def route_scope(name, &block)
|
|
181
|
+
define_method(:_route_scope) do
|
|
182
|
+
return block.call if block_given?
|
|
183
|
+
name
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Using this method user can override the route namespace guessed by
|
|
188
|
+
# Underworld.
|
|
189
|
+
def route_namespace(name, &block)
|
|
190
|
+
define_method(:_namespace) do
|
|
191
|
+
return block.call if block_given?
|
|
192
|
+
name
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
# Set the engine name of current controller. It's necessary to provide and
|
|
196
|
+
# engine name if the controller belongs to an engine other than Underworld or
|
|
197
|
+
# Rails.application.
|
|
198
|
+
def engine(name)
|
|
199
|
+
define_method(:_engine) do
|
|
200
|
+
name.constantize
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Specify the model name of controller. This method overrides the
|
|
205
|
+
# `model_class` **class method** and `model_name` instance method.
|
|
206
|
+
def model_name(name)
|
|
207
|
+
define_singleton_method :model_class do
|
|
208
|
+
name.constantize
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
define_method :model_name do
|
|
212
|
+
name
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Returns the actual model class by looking at `controller_name` and
|
|
217
|
+
# and `controller_path`. If user uses the `model_name` **class method**
|
|
218
|
+
# (the `model_name` DSL) then this method will override by the
|
|
219
|
+
# `model_name` defination of `model_class`
|
|
220
|
+
def model_class
|
|
221
|
+
name = controller_name
|
|
222
|
+
path = controller_path.gsub(name, '').gsub(/dashboard\//, '')
|
|
223
|
+
|
|
224
|
+
"#{path}#{name}".classify.constantize
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
end
|
|
229
|
+
end
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
require 'set'
|
|
2
|
+
require_dependency 'underworld/dashboard/dsl/create'
|
|
3
|
+
|
|
4
|
+
module Underworld::Dashboard::Sections
|
|
5
|
+
module ResourceCreate
|
|
6
|
+
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
# The actual action method of a dashboard controller
|
|
10
|
+
def new
|
|
11
|
+
authorize model, :create?
|
|
12
|
+
|
|
13
|
+
collect_model_fields_for_form
|
|
14
|
+
|
|
15
|
+
@resource = model.new
|
|
16
|
+
@resource_title = t(_resource_title.singularize)
|
|
17
|
+
@_fields_properties = form_properties._field_details
|
|
18
|
+
@multipart = has_attachment?
|
|
19
|
+
|
|
20
|
+
new_hook(@resource)
|
|
21
|
+
return if _override_views.include? :new
|
|
22
|
+
render 'underworld/dashboard/resource/new'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def edit
|
|
26
|
+
# TODO: Handle nested resource in here
|
|
27
|
+
@resource = model.find(params[:id])
|
|
28
|
+
authorize @resource, :update?
|
|
29
|
+
|
|
30
|
+
collect_model_fields_for_form
|
|
31
|
+
|
|
32
|
+
@resource_title = t(_resource_title.singularize)
|
|
33
|
+
@_fields_properties = form_properties._field_details
|
|
34
|
+
@multipart = has_attachment?
|
|
35
|
+
|
|
36
|
+
edit_hook(@resource)
|
|
37
|
+
|
|
38
|
+
return if _override_views.include? :edit
|
|
39
|
+
render 'underworld/dashboard/resource/edit'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def update
|
|
43
|
+
# TODO: Handle nested resource in here
|
|
44
|
+
@resource = model.find(params[:id])
|
|
45
|
+
authorize @resource
|
|
46
|
+
|
|
47
|
+
new_params = creation_params
|
|
48
|
+
new_params.merge(reflections_hash) if reflections_hash
|
|
49
|
+
|
|
50
|
+
# Customize update behaviour before updating resource
|
|
51
|
+
before_update_hook(@resource)
|
|
52
|
+
|
|
53
|
+
# TODO: Move this method to a suitable place instead of controller
|
|
54
|
+
# itself
|
|
55
|
+
new_params = symbolify_keys(new_params)
|
|
56
|
+
|
|
57
|
+
@resource.assign_attributes(**new_params)
|
|
58
|
+
|
|
59
|
+
if @resource.save
|
|
60
|
+
# Customize update behaviour after updating resource
|
|
61
|
+
after_update_hook(@resource)
|
|
62
|
+
successful_response(:update)
|
|
63
|
+
else
|
|
64
|
+
errorful_resopnse(:update, @resource.errors) do
|
|
65
|
+
redirect_to :edit
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# The actual action method for creating new resource.
|
|
71
|
+
def create
|
|
72
|
+
authorize model
|
|
73
|
+
|
|
74
|
+
@resource = model.new(creation_params)
|
|
75
|
+
@resource.assign_attributes(**reflections_hash) unless reflections_hash.nil?
|
|
76
|
+
|
|
77
|
+
# Customize the create behaviour
|
|
78
|
+
before_create_hook(@resource)
|
|
79
|
+
|
|
80
|
+
# TODO: Handle M2M relations in here
|
|
81
|
+
if @resource.save
|
|
82
|
+
after_create_hook(@resource)
|
|
83
|
+
successful_response(:create)
|
|
84
|
+
else
|
|
85
|
+
errorful_resopnse(:create, @resource.errors) do
|
|
86
|
+
redirect_to Rails.application.routes.url_helpers.send(@new_route), turbolinks: true
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
protected
|
|
92
|
+
|
|
93
|
+
def collect_model_fields_for_form
|
|
94
|
+
@_fields ||= form_properties.fields_for_form
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def reflections_hash
|
|
98
|
+
# TODO: cach the result using and instance_var or something
|
|
99
|
+
reflections = model.reflections
|
|
100
|
+
result = {}
|
|
101
|
+
|
|
102
|
+
reflections.each do |name, column|
|
|
103
|
+
unless is_reflection?(column)
|
|
104
|
+
|
|
105
|
+
value = creation_params[column.foreign_key]
|
|
106
|
+
result[column.foreign_key.to_sym] = value
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return result unless result.empty?
|
|
111
|
+
nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def creation_params
|
|
115
|
+
resource = controller_name.singularize.underscore.to_sym
|
|
116
|
+
|
|
117
|
+
# TODO: replace this line with a better solution to not
|
|
118
|
+
# allowing the blacklisted fields like id, created_at and ...
|
|
119
|
+
fields = model.columns_hash.keys.map(&:to_sym)
|
|
120
|
+
fields.concat(attachment_fields.map(&:to_sym ))
|
|
121
|
+
fields = Set.new(fields).map(&:to_sym)
|
|
122
|
+
params.require(resource).permit(*fields)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Check whether the given column is a reflection or not.
|
|
126
|
+
def is_reflection?(c)
|
|
127
|
+
has_many = ActiveRecord::Reflection::HasManyReflection
|
|
128
|
+
has_and_belongs_to_many = ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
|
129
|
+
has_many_through = ActiveRecord::Reflection::ThroughReflection
|
|
130
|
+
|
|
131
|
+
result = c.is_a?(has_many) || c.is_a?(has_and_belongs_to_many)
|
|
132
|
+
result || c.is_a?(has_many_through)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
# You can override this method to change the behaviour of `create`
|
|
138
|
+
# action before save resource
|
|
139
|
+
def before_create_hook(resource)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# You can override this method to change the behaviour of `create`
|
|
143
|
+
# action afer save resource
|
|
144
|
+
def after_create_hook(resource)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# You can override this method to change the behaviour of `update`
|
|
148
|
+
# action before save resource
|
|
149
|
+
def before_update_hook(resource)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# You can override this method to change the behaviour of `update`
|
|
154
|
+
# action after save resource
|
|
155
|
+
def after_update_hook(resource)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# You can override this method to change the behaviour of `new`
|
|
159
|
+
# action
|
|
160
|
+
def new_hook(resource)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# You can override this method to change the behaviour of `edit`
|
|
164
|
+
# action
|
|
165
|
+
def edit_hook(resource)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def all_valid_columns_for_form
|
|
169
|
+
return @all_valid_columns_for_form unless @all_valid_columns_for_form.nil?
|
|
170
|
+
columns = model.columns_hash.dup
|
|
171
|
+
relations = model.reflections
|
|
172
|
+
|
|
173
|
+
relations.keys.each do |name|
|
|
174
|
+
has_many = ActiveRecord::Reflection::HasManyReflection
|
|
175
|
+
has_and_belongs_to_many = ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
|
176
|
+
|
|
177
|
+
unless relations[name].is_a? has_many
|
|
178
|
+
if relations[name].is_a? has_and_belongs_to_many
|
|
179
|
+
columns[name] = Class.new { def self.type() :multiple_select end }
|
|
180
|
+
else
|
|
181
|
+
col = relations[name]
|
|
182
|
+
column = columns.delete col.foreign_key
|
|
183
|
+
columns[name] = column
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
columns.delete('id')
|
|
189
|
+
columns.delete('created_at')
|
|
190
|
+
columns.delete('updated_at')
|
|
191
|
+
|
|
192
|
+
@all_valid_columns_for_form = columns
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def form_properties
|
|
196
|
+
Underworld::Dashboard::DSL::Create.new(model)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def _new_form_fields
|
|
200
|
+
all_valid_columns_for_form.keys.map(&:to_sym)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# The actual DSL for index ages
|
|
204
|
+
module ClassMethods
|
|
205
|
+
|
|
206
|
+
# To specify any property and action for `form` section both new and edit
|
|
207
|
+
# You must use `in_form` class method with block of properties. For
|
|
208
|
+
# example:
|
|
209
|
+
#
|
|
210
|
+
# class ExamplesController < Dashboard::Application
|
|
211
|
+
# in_form do
|
|
212
|
+
# attributes :name, :description
|
|
213
|
+
# action_button :close, dashboard_example_close_path
|
|
214
|
+
# end
|
|
215
|
+
# end
|
|
216
|
+
def in_form(&block)
|
|
217
|
+
model = model_class
|
|
218
|
+
form_props = Underworld::Dashboard::DSL::Create.new(model)
|
|
219
|
+
|
|
220
|
+
unless block_given?
|
|
221
|
+
fail ArgumentError, "You have to provide a block for 'in_form'"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
define_method(:form_properties) do
|
|
226
|
+
unless defined? @__form_props__
|
|
227
|
+
instance_exec(form_props, &block)
|
|
228
|
+
@__form_props__ = form_props
|
|
229
|
+
end
|
|
230
|
+
return @__form_props__
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
private :form_properties
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# User can provides the fields that he/she wants to be shown
|
|
237
|
+
# in the form for resource creation page.
|
|
238
|
+
# for example:
|
|
239
|
+
#
|
|
240
|
+
# class Dashboard::PostsController < Dashboard::ApplicationController
|
|
241
|
+
# new_form_fields :title, created_at
|
|
242
|
+
# end
|
|
243
|
+
def new_form_fields(*fields, **options)
|
|
244
|
+
define_method(:_new_form_fields) do
|
|
245
|
+
fields.map(&:to_sym)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
private :_new_form_fields
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def form_fields
|
|
252
|
+
form = ::Underworld::Dashboard::FormFieldsProperties.new
|
|
253
|
+
yield form
|
|
254
|
+
|
|
255
|
+
define_method(:_form_fields) do
|
|
256
|
+
form
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
private :_form_fields
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|