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.
Files changed (365) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +339 -0
  5. data/Rakefile +48 -0
  6. data/app/assets/fonts/DroidNaskh-Bold.ttf +0 -0
  7. data/app/assets/fonts/DroidNaskh-Regular.ttf +0 -0
  8. data/app/assets/fonts/OpenSans-Bold.ttf +0 -0
  9. data/app/assets/fonts/OpenSans-BoldItalic.ttf +0 -0
  10. data/app/assets/fonts/OpenSans-ExtraBold.ttf +0 -0
  11. data/app/assets/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  12. data/app/assets/fonts/OpenSans-Italic.ttf +0 -0
  13. data/app/assets/fonts/OpenSans-Light.ttf +0 -0
  14. data/app/assets/fonts/OpenSans-LightItalic.ttf +0 -0
  15. data/app/assets/fonts/OpenSans-Regular.ttf +0 -0
  16. data/app/assets/fonts/OpenSans-Semibold.ttf +0 -0
  17. data/app/assets/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  18. data/app/assets/images/underworld/select2-spinner.gif +0 -0
  19. data/app/assets/images/underworld/select2.png +0 -0
  20. data/app/assets/images/underworld/select2x2.png +0 -0
  21. data/app/assets/javascripts/underworld/application.js +16 -0
  22. data/app/assets/javascripts/underworld/dashboard/application.js.erb +30 -0
  23. data/app/assets/javascripts/underworld/dashboard/functions.js.erb +50 -0
  24. data/app/assets/javascripts/underworld/dashboard/init.js.coffee +33 -0
  25. data/app/assets/javascripts/underworld/dashboard/lib/actions.js +7 -0
  26. data/app/assets/javascripts/underworld/dashboard/lib/amd.js.coffee.erb +0 -0
  27. data/app/assets/javascripts/underworld/dashboard/lib/flash_message.js +71 -0
  28. data/app/assets/javascripts/underworld/dashboard/lib/locale.js +14 -0
  29. data/app/assets/javascripts/underworld/dashboard/lib/misc.js +5 -0
  30. data/app/assets/javascripts/underworld/dashboard/lib/string.js +3 -0
  31. data/app/assets/javascripts/underworld/dashboard/lib/ujs_patches.js.coffee +28 -0
  32. data/app/assets/javascripts/underworld/dashboard/manifest.js +5 -0
  33. data/app/assets/javascripts/underworld/dashboard/variables.js.erb +6 -0
  34. data/app/assets/javascripts/underworld/groups.js +2 -0
  35. data/app/assets/javascripts/underworld/home.js +2 -0
  36. data/app/assets/javascripts/underworld/i18n.js +13 -0
  37. data/app/assets/javascripts/underworld/simple.js +20 -0
  38. data/app/assets/javascripts/underworld/users.js +2 -0
  39. data/app/assets/stylesheets/underworld/dashboard/loadindicator.scss +17 -0
  40. data/app/assets/stylesheets/underworld/dashboard/ltr/application.css +38 -0
  41. data/app/assets/stylesheets/underworld/dashboard/ltr/base.css.scss +0 -0
  42. data/app/assets/stylesheets/underworld/dashboard/rtl/application.css +11 -0
  43. data/app/assets/stylesheets/underworld/dashboard/rtl/base.css.scss +0 -0
  44. data/app/assets/stylesheets/underworld/dashboard/share.scss +62 -0
  45. data/app/assets/stylesheets/underworld/dashboard/variables.scss +9 -0
  46. data/app/assets/stylesheets/underworld/ltr/application.css +0 -0
  47. data/app/assets/stylesheets/underworld/rtl/application.css +0 -0
  48. data/app/assets/stylesheets/underworld/simple/ltr/application.css +2 -0
  49. data/app/assets/stylesheets/underworld/simple/rtl/application.css +2 -0
  50. data/app/assets/stylesheets/underworld/simple/rtl/rtl.scss +16 -0
  51. data/app/assets/stylesheets/underworld/simple/share.scss +11 -0
  52. data/app/controllers/underworld/api_controller.rb +133 -0
  53. data/app/controllers/underworld/application_controller.rb +16 -0
  54. data/app/controllers/underworld/assets_controller.rb +6 -0
  55. data/app/controllers/underworld/dashboard/application_controller.rb +43 -0
  56. data/app/controllers/underworld/dashboard/groups_controller.rb +85 -0
  57. data/app/controllers/underworld/dashboard/profile_controller.rb +49 -0
  58. data/app/controllers/underworld/dashboard/user_messages_controller.rb +27 -0
  59. data/app/controllers/underworld/dashboard/users_controller.rb +116 -0
  60. data/app/controllers/underworld/dashboard_controller.rb +16 -0
  61. data/app/controllers/underworld/omniauth/callbacks_controller.rb +24 -0
  62. data/app/helpers/underworld/application_helper.rb +4 -0
  63. data/app/helpers/underworld/dashboard_helper.rb +107 -0
  64. data/app/helpers/underworld/groups_helper.rb +4 -0
  65. data/app/helpers/underworld/home_helper.rb +4 -0
  66. data/app/helpers/underworld/users_helper.rb +8 -0
  67. data/app/models/application_record.rb +3 -0
  68. data/app/models/underworld/concerns/assignment.rb +16 -0
  69. data/app/models/underworld/concerns/user/auth_definitions.rb +87 -0
  70. data/app/models/underworld/concerns/user/gravatar.rb +11 -0
  71. data/app/models/underworld/concerns/user/mongoid_fields.rb +81 -0
  72. data/app/models/underworld/concerns/user/permission.rb +47 -0
  73. data/app/models/underworld/concerns/user/user_roles.rb +24 -0
  74. data/app/models/underworld/group.rb +57 -0
  75. data/app/models/underworld/permission.rb +43 -0
  76. data/app/models/underworld/user.rb +81 -0
  77. data/app/models/underworld/user_message.rb +6 -0
  78. data/app/policies/underworld/admin_only_policy.rb +66 -0
  79. data/app/policies/underworld/application_policy.rb +55 -0
  80. data/app/policies/underworld/group_policy.rb +8 -0
  81. data/app/policies/underworld/user_message_policy.rb +9 -0
  82. data/app/policies/underworld/user_policy.rb +9 -0
  83. data/app/views/angular/auth/groups/details.html +2 -0
  84. data/app/views/angular/auth/groups/index.html +2 -0
  85. data/app/views/angular/auth/groups/new.html +2 -0
  86. data/app/views/angular/auth/index.html +30 -0
  87. data/app/views/angular/auth/profile/edit.html +54 -0
  88. data/app/views/angular/auth/users/details.html +28 -0
  89. data/app/views/angular/auth/users/index.html +6 -0
  90. data/app/views/angular/auth/users/new.html +57 -0
  91. data/app/views/angular/conversations/details.html +19 -0
  92. data/app/views/angular/conversations/index.html +13 -0
  93. data/app/views/angular/conversations/new.html +39 -0
  94. data/app/views/angular/conversations/show.html +6 -0
  95. data/app/views/angular/conversations/show_details.html +15 -0
  96. data/app/views/angular/fields/boolean/boolean.html +4 -0
  97. data/app/views/angular/fields/control-combo/control-list.html +19 -0
  98. data/app/views/angular/fields/datetime/datetime.html +10 -0
  99. data/app/views/angular/fields/datetime/time.html +25 -0
  100. data/app/views/angular/fields/file/file.html.slim +0 -0
  101. data/app/views/angular/fields/float/float.html +4 -0
  102. data/app/views/angular/fields/image/image.html +1 -0
  103. data/app/views/angular/fields/integer/integer.html +4 -0
  104. data/app/views/angular/fields/relation/relation.html +44 -0
  105. data/app/views/angular/fields/string/string.html +22 -0
  106. data/app/views/angular/fields/tag/tag.html +1 -0
  107. data/app/views/angular/fields/text/text.html +4 -0
  108. data/app/views/angular/filter/index.html +15 -0
  109. data/app/views/angular/index.html +3 -0
  110. data/app/views/angular/locale/fa.po +25 -0
  111. data/app/views/angular/locale/templates.pot +24 -0
  112. data/app/views/angular/logs/index.html +6 -0
  113. data/app/views/angular/modules.html +0 -0
  114. data/app/views/angular/nav.html.erb +39 -0
  115. data/app/views/angular/underworld/views/generic_add_view.html.slim +5 -0
  116. data/app/views/devise/registrations/edit.html.erb +29 -0
  117. data/app/views/devise/registrations/new.html.erb +38 -0
  118. data/app/views/devise/sessions/new.html.erb +37 -0
  119. data/app/views/devise/shared/_links.erb +19 -0
  120. data/app/views/devise/shared/_omni_link.erb +33 -0
  121. data/app/views/kaminari/_first_page.html.slim +3 -0
  122. data/app/views/kaminari/_gap.html.slim +2 -0
  123. data/app/views/kaminari/_last_page.html.slim +3 -0
  124. data/app/views/kaminari/_next_page.html.slim +3 -0
  125. data/app/views/kaminari/_page.html.slim +3 -0
  126. data/app/views/kaminari/_paginator.html.slim +13 -0
  127. data/app/views/kaminari/_prev_page.html.slim +3 -0
  128. data/app/views/layouts/underworld/application.html.erb +79 -0
  129. data/app/views/layouts/underworld/dashboard.html.erb +52 -0
  130. data/app/views/layouts/underworld/simple.html.erb +27 -0
  131. data/app/views/underworld/api/v1/conversations/create.json.jbuilder +1 -0
  132. data/app/views/underworld/api/v1/conversations/destroy.json.jbuilder +1 -0
  133. data/app/views/underworld/api/v1/conversations/index.json.jbuilder +1 -0
  134. data/app/views/underworld/api/v1/conversations/reply.json.jbuilder +1 -0
  135. data/app/views/underworld/api/v1/conversations/show.json.jbuilder +14 -0
  136. data/app/views/underworld/api/v1/conversations/trash.json.jbuilder +1 -0
  137. data/app/views/underworld/api/v1/groups/create.json.jbuilder +4 -0
  138. data/app/views/underworld/api/v1/groups/destroy.html.erb +2 -0
  139. data/app/views/underworld/api/v1/groups/destroy.json.jbuilder +1 -0
  140. data/app/views/underworld/api/v1/groups/edit.html.erb +2 -0
  141. data/app/views/underworld/api/v1/groups/index.html.erb +2 -0
  142. data/app/views/underworld/api/v1/groups/index.json.jbuilder +6 -0
  143. data/app/views/underworld/api/v1/groups/new.html.erb +2 -0
  144. data/app/views/underworld/api/v1/groups/show.html.erb +2 -0
  145. data/app/views/underworld/api/v1/groups/show.json.jbuilder +5 -0
  146. data/app/views/underworld/api/v1/groups/update.json.jbuilder +4 -0
  147. data/app/views/underworld/api/v1/logs/index.json.jbuilder +1 -0
  148. data/app/views/underworld/api/v1/permissions/index.json.jbuilder +1 -0
  149. data/app/views/underworld/api/v1/permissions/user_permissions.json.jbuilder +1 -0
  150. data/app/views/underworld/api/v1/users/create.html.erb +2 -0
  151. data/app/views/underworld/api/v1/users/create.json.jbuilder +1 -0
  152. data/app/views/underworld/api/v1/users/destroy.json.jbuilder +1 -0
  153. data/app/views/underworld/api/v1/users/distroy.html.erb +2 -0
  154. data/app/views/underworld/api/v1/users/edit.html.erb +2 -0
  155. data/app/views/underworld/api/v1/users/index.html.erb +2 -0
  156. data/app/views/underworld/api/v1/users/index.json.jbuilder +4 -0
  157. data/app/views/underworld/api/v1/users/show.html.erb +2 -0
  158. data/app/views/underworld/api/v1/users/show.json.jbuilder +2 -0
  159. data/app/views/underworld/api/v1/users/update.json.jbuilder +1 -0
  160. data/app/views/underworld/dashboard/groups/_form.html.slim +68 -0
  161. data/app/views/underworld/dashboard/groups/create.js.erb +3 -0
  162. data/app/views/underworld/dashboard/groups/edit.html.slim +3 -0
  163. data/app/views/underworld/dashboard/groups/errors.js.erb +3 -0
  164. data/app/views/underworld/dashboard/groups/index.html.slim +47 -0
  165. data/app/views/underworld/dashboard/groups/new.html.slim +2 -0
  166. data/app/views/underworld/dashboard/groups/update.js.erb +3 -0
  167. data/app/views/underworld/dashboard/index.html.erb +0 -0
  168. data/app/views/underworld/dashboard/login_required_page.html.erb +5 -0
  169. data/app/views/underworld/dashboard/not_found.html.slim +9 -0
  170. data/app/views/underworld/dashboard/not_found.js.erb +1 -0
  171. data/app/views/underworld/dashboard/profile/_form.html.erb +33 -0
  172. data/app/views/underworld/dashboard/profile/_profile_form.html.erb +33 -0
  173. data/app/views/underworld/dashboard/profile/create.js.erb +3 -0
  174. data/app/views/underworld/dashboard/profile/edit.html.erb +2 -0
  175. data/app/views/underworld/dashboard/profile/edit_password.html.erb +2 -0
  176. data/app/views/underworld/dashboard/profile/errors.js.erb +3 -0
  177. data/app/views/underworld/dashboard/resource/_form.html.slim +33 -0
  178. data/app/views/underworld/dashboard/resource/_input.html.slim +3 -0
  179. data/app/views/underworld/dashboard/resource/create.js.erb +3 -0
  180. data/app/views/underworld/dashboard/resource/destroy.js.erb +2 -0
  181. data/app/views/underworld/dashboard/resource/edit.html.slim +3 -0
  182. data/app/views/underworld/dashboard/resource/index.html.slim +60 -0
  183. data/app/views/underworld/dashboard/resource/new.html.slim +2 -0
  184. data/app/views/underworld/dashboard/resource/show.html.slim +22 -0
  185. data/app/views/underworld/dashboard/resource/update.js.erb +3 -0
  186. data/app/views/underworld/dashboard/shared/_content_header.html.slim +15 -0
  187. data/app/views/underworld/dashboard/shared/_control_sidebar.html.slim +50 -0
  188. data/app/views/underworld/dashboard/shared/_footer.html.slim +7 -0
  189. data/app/views/underworld/dashboard/shared/_header.html.erb +98 -0
  190. data/app/views/underworld/dashboard/shared/_sidebar.html.erb +69 -0
  191. data/app/views/underworld/dashboard/shared/_toolbar.html.slim +0 -0
  192. data/app/views/underworld/dashboard/shared/errors.js.erb +3 -0
  193. data/app/views/underworld/dashboard/user_messages/_form.html.slim +0 -0
  194. data/app/views/underworld/dashboard/user_messages/create.js.erb +0 -0
  195. data/app/views/underworld/dashboard/user_messages/destroy.js.erb +0 -0
  196. data/app/views/underworld/dashboard/user_messages/new.html.slim +72 -0
  197. data/app/views/underworld/dashboard/users/_form.html.slim +73 -0
  198. data/app/views/underworld/dashboard/users/_password_form.html.slim +37 -0
  199. data/app/views/underworld/dashboard/users/create.js.erb +3 -0
  200. data/app/views/underworld/dashboard/users/destroy.js.erb +2 -0
  201. data/app/views/underworld/dashboard/users/edit.html.slim +3 -0
  202. data/app/views/underworld/dashboard/users/edit_password.html.slim +1 -0
  203. data/app/views/underworld/dashboard/users/errors.js.erb +3 -0
  204. data/app/views/underworld/dashboard/users/index.html.slim +66 -0
  205. data/app/views/underworld/dashboard/users/new.html.slim +2 -0
  206. data/app/views/underworld/dashboard/users/show.html.slim +6 -0
  207. data/app/views/underworld/dashboard/users/update.js.erb +3 -0
  208. data/app/views/underworld/dashboard/users/update_password.js.erb +3 -0
  209. data/app/views/underworld/relations/_belongs_to.json.jbuilder +11 -0
  210. data/config/initializers/devise.rb +24 -0
  211. data/config/locales/devise.en.yml +59 -0
  212. data/config/locales/devise.fa.yml +58 -0
  213. data/config/locales/underworld.en.yml +96 -0
  214. data/config/locales/underworld.fa.yml +108 -0
  215. data/config/routes.rb +43 -0
  216. data/config/spring.rb +1 -0
  217. data/db/migrate/20131013091000_devise_create_underworld_users.rb +65 -0
  218. data/db/migrate/20131020124701_create_underworld_groups.rb +15 -0
  219. data/db/migrate/20131021170923_create_underworld_permissions.rb +15 -0
  220. data/db/migrate/20131123120422_add_permissions_groups_table.rb +16 -0
  221. data/db/migrate/20140613120923_add_users_groups_table.rb +13 -0
  222. data/db/migrate/20151122115129_add_uniqueness_index_to_users_groups.rb +11 -0
  223. data/db/migrate/20160310105736_create_underworld_user_messages.rb +25 -0
  224. data/db/seeds.rb +49 -0
  225. data/lib/generators/underworld/install_generator.rb +108 -0
  226. data/lib/generators/underworld/resource_generator.rb +70 -0
  227. data/lib/generators/underworld/resources_generator.rb +20 -0
  228. data/lib/generators/underworld/templates/README +21 -0
  229. data/lib/generators/underworld/templates/SPECS +13 -0
  230. data/lib/generators/underworld/templates/api/controller.rb.erb +60 -0
  231. data/lib/generators/underworld/templates/api_controller.rb +2 -0
  232. data/lib/generators/underworld/templates/dashboard/controller.rb.erb +2 -0
  233. data/lib/generators/underworld/templates/dashboard_controller.rb +18 -0
  234. data/lib/generators/underworld/templates/devise.rb +251 -0
  235. data/lib/generators/underworld/templates/features/api.feature +92 -0
  236. data/lib/generators/underworld/templates/features/api.step.rb +7 -0
  237. data/lib/generators/underworld/templates/features/step_definitions/email_steps.rb +206 -0
  238. data/lib/generators/underworld/templates/features/support/email_spec.rb +1 -0
  239. data/lib/generators/underworld/templates/features/support/env.rb +79 -0
  240. data/lib/generators/underworld/templates/javascripts/application.js +19 -0
  241. data/lib/generators/underworld/templates/policy/application_policy.rb +2 -0
  242. data/lib/generators/underworld/templates/policy/policy.rb.erb +2 -0
  243. data/lib/generators/underworld/templates/seeds.rb +1 -0
  244. data/lib/generators/underworld/templates/spec/factories/groups.rb +5 -0
  245. data/lib/generators/underworld/templates/spec/factories/users.rb +10 -0
  246. data/lib/generators/underworld/templates/spec/spec_helper.rb +69 -0
  247. data/lib/generators/underworld/templates/spec/support/devise.rb +3 -0
  248. data/lib/generators/underworld/templates/stylesheets/dashboard/ltr/application.css +3 -0
  249. data/lib/generators/underworld/templates/stylesheets/dashboard/rtl/application.css +3 -0
  250. data/lib/generators/underworld/templates/stylesheets/ltr/application.css +3 -0
  251. data/lib/generators/underworld/templates/stylesheets/rtl/application.css +3 -0
  252. data/lib/generators/underworld/templates/underworld.rb +12 -0
  253. data/lib/generators/underworld/templates/views/create.json.jbuilder.erb +3 -0
  254. data/lib/generators/underworld/templates/views/destroy.json.jbuilder.erb +1 -0
  255. data/lib/generators/underworld/templates/views/index.json.jbuilder.erb +13 -0
  256. data/lib/generators/underworld/templates/views/show.json.jbuilder.erb +6 -0
  257. data/lib/generators/underworld/templates/views/update.json.jbuilder.erb +6 -0
  258. data/lib/generators/underworld/views_generator.rb +57 -0
  259. data/lib/tasks/docs.rake +6 -0
  260. data/lib/tasks/sync.rake +9 -0
  261. data/lib/tasks/underworld_tasks.rake +38 -0
  262. data/lib/underworld.rb +35 -0
  263. data/lib/underworld/action_dispatch.rb +3 -0
  264. data/lib/underworld/api.rb +42 -0
  265. data/lib/underworld/api/groups_api.rb +41 -0
  266. data/lib/underworld/api/permissions_api.rb +24 -0
  267. data/lib/underworld/api/root.rb +15 -0
  268. data/lib/underworld/api/users_api.rb +20 -0
  269. data/lib/underworld/concerns.rb +7 -0
  270. data/lib/underworld/concerns/authorizable.rb +81 -0
  271. data/lib/underworld/configuration.rb +97 -0
  272. data/lib/underworld/dashboard.rb +11 -0
  273. data/lib/underworld/dashboard/dsl.rb +41 -0
  274. data/lib/underworld/dashboard/dsl/base.rb +133 -0
  275. data/lib/underworld/dashboard/dsl/create.rb +116 -0
  276. data/lib/underworld/dashboard/dsl/form_fields_properties.rb +62 -0
  277. data/lib/underworld/dashboard/dsl/index.rb +45 -0
  278. data/lib/underworld/dashboard/dsl/show.rb +6 -0
  279. data/lib/underworld/dashboard/dsl/update.rb +6 -0
  280. data/lib/underworld/dashboard/helpers/box_helpers.rb +129 -0
  281. data/lib/underworld/dashboard/models.rb +2 -0
  282. data/lib/underworld/dashboard/models/sidebar.rb +139 -0
  283. data/lib/underworld/dashboard/sections.rb +2 -0
  284. data/lib/underworld/dashboard/sections/resource.rb +229 -0
  285. data/lib/underworld/dashboard/sections/resource_create.rb +263 -0
  286. data/lib/underworld/dashboard/sections/resource_destroy.rb +27 -0
  287. data/lib/underworld/dashboard/sections/resource_show.rb +96 -0
  288. data/lib/underworld/dashboard/sections/resources_index.rb +113 -0
  289. data/lib/underworld/dashboard/sections/sidebar.rb +41 -0
  290. data/lib/underworld/discovery.rb +8 -0
  291. data/lib/underworld/discovery/permissions.rb +49 -0
  292. data/lib/underworld/engine.rb +53 -0
  293. data/lib/underworld/exceptions.rb +7 -0
  294. data/lib/underworld/extension.rb +18 -0
  295. data/lib/underworld/extension/base.rb +29 -0
  296. data/lib/underworld/fake_assets.rb +5 -0
  297. data/lib/underworld/i18n.rb +101 -0
  298. data/lib/underworld/initialize.rb +0 -0
  299. data/lib/underworld/liquid.rb +7 -0
  300. data/lib/underworld/liquid/block.rb +14 -0
  301. data/lib/underworld/liquid/render_tag.rb +50 -0
  302. data/lib/underworld/liquid/tag.rb +51 -0
  303. data/lib/underworld/middlewares.rb +1 -0
  304. data/lib/underworld/middlewares/locale.rb +29 -0
  305. data/lib/underworld/omniauth.rb +8 -0
  306. data/lib/underworld/omniauth/callbacks.rb +39 -0
  307. data/lib/underworld/orm.rb +30 -0
  308. data/lib/underworld/routes.rb +117 -0
  309. data/lib/underworld/version.rb +3 -0
  310. data/test/controllers/underworld/dashboard/resource_test.rb +118 -0
  311. data/test/dummy/README.rdoc +28 -0
  312. data/test/dummy/Rakefile +6 -0
  313. data/test/dummy/app/assets/javascripts/application.js +13 -0
  314. data/test/dummy/app/assets/javascripts/dashboard/application.js +19 -0
  315. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  316. data/test/dummy/app/assets/stylesheets/dashboard/ltr/application.css +3 -0
  317. data/test/dummy/app/assets/stylesheets/dashboard/rtl/application.css +3 -0
  318. data/test/dummy/app/assets/stylesheets/ltr/application.css +3 -0
  319. data/test/dummy/app/assets/stylesheets/rtl/application.css +3 -0
  320. data/test/dummy/app/controllers/api_controller.rb +2 -0
  321. data/test/dummy/app/controllers/application_controller.rb +6 -0
  322. data/test/dummy/app/controllers/dashboard/application_controller.rb +18 -0
  323. data/test/dummy/app/helpers/application_helper.rb +2 -0
  324. data/test/dummy/app/policies/application_policy.rb +2 -0
  325. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  326. data/test/dummy/bin/bundle +3 -0
  327. data/test/dummy/bin/rails +4 -0
  328. data/test/dummy/bin/rake +4 -0
  329. data/test/dummy/config.ru +4 -0
  330. data/test/dummy/config/application.rb +23 -0
  331. data/test/dummy/config/boot.rb +5 -0
  332. data/test/dummy/config/database.yml +25 -0
  333. data/test/dummy/config/environment.rb +5 -0
  334. data/test/dummy/config/environments/development.rb +29 -0
  335. data/test/dummy/config/environments/production.rb +80 -0
  336. data/test/dummy/config/environments/test.rb +38 -0
  337. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  338. data/test/dummy/config/initializers/devise.rb +251 -0
  339. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  340. data/test/dummy/config/initializers/formstatic.rb +76 -0
  341. data/test/dummy/config/initializers/formtastic.rb +110 -0
  342. data/test/dummy/config/initializers/inflections.rb +16 -0
  343. data/test/dummy/config/initializers/kaminari_config.rb +10 -0
  344. data/test/dummy/config/initializers/mime_types.rb +5 -0
  345. data/test/dummy/config/initializers/secret_token.rb +12 -0
  346. data/test/dummy/config/initializers/session_store.rb +3 -0
  347. data/test/dummy/config/initializers/underworld.rb +11 -0
  348. data/test/dummy/config/initializers/underworld_assets.rb +1 -0
  349. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  350. data/test/dummy/config/locales/en.yml +23 -0
  351. data/test/dummy/config/routes.rb +13 -0
  352. data/test/dummy/lib/templates/slim/scaffold/_form.html.slim +8 -0
  353. data/test/dummy/public/404.html +58 -0
  354. data/test/dummy/public/422.html +58 -0
  355. data/test/dummy/public/500.html +57 -0
  356. data/test/dummy/public/favicon.ico +0 -0
  357. data/test/fabricators/underworld/groups.rb +27 -0
  358. data/test/fabricators/underworld/permissions.rb +14 -0
  359. data/test/fabricators/underworld/users.rb +17 -0
  360. data/test/generators/install_generator_test.rb +84 -0
  361. data/test/integration/underworld/authentication_test.rb +36 -0
  362. data/test/integration/underworld/dashboard_test.rb +64 -0
  363. data/test/test_helper.rb +72 -0
  364. metadata +1045 -0
  365. metadata.gz.sig +0 -0
@@ -0,0 +1,11 @@
1
+ #require_dependency 'underworld/dashboard/dsl'
2
+
3
+ module Underworld::Dashboard
4
+ autoload :DSL, 'underworld/dashboard/dsl'
5
+
6
+ module Helpers
7
+ end
8
+
9
+ autoload :Models, 'underworld/dashboard/models'
10
+ autoload :Sections, 'underworld/dashboard/sections.rb'
11
+ end
@@ -0,0 +1,41 @@
1
+ require_dependency 'underworld/dashboard/dsl/form_fields_properties'
2
+ require_dependency 'underworld/dashboard/sections/resource'
3
+ require_dependency 'underworld/dashboard/sections/resources_index'
4
+ require_dependency 'underworld/dashboard/sections/resource_create'
5
+ require_dependency 'underworld/dashboard/sections/resource_show'
6
+ require_dependency 'underworld/dashboard/sections/resource_destroy'
7
+ require_dependency 'underworld/dashboard/sections/sidebar'
8
+
9
+ module Underworld::Dashboard
10
+ module DSL
11
+
12
+ extend ActiveSupport::Concern
13
+
14
+ include Underworld::Dashboard::Sections::Resource
15
+ include Underworld::Dashboard::Sections::ResourcesIndex
16
+ include Underworld::Dashboard::Sections::ResourceCreate
17
+ include Underworld::Dashboard::Sections::ResourceShow
18
+ include Underworld::Dashboard::Sections::ResourceDestroy
19
+ include Underworld::Dashboard::Sections::Sidebar
20
+
21
+ attr_accessor :_override_views
22
+
23
+ def _override_views
24
+ @_override_views ||= []
25
+ end
26
+
27
+ module ClassMethods
28
+ # override the default view for given views or the result
29
+ # of the given block, by the one from the application
30
+ def override_views(*views, &block)
31
+
32
+ define_method(:_override_views) do
33
+ result = views || []
34
+ result.concat(block.call) if block_given?
35
+ result
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,133 @@
1
+ require 'set'
2
+
3
+ module Underworld::Dashboard::DSL
4
+ class Base
5
+ attr_reader(:action_buttons, :fields, :model, :default_scope,
6
+ :action_buttons)
7
+
8
+ # Base class for all the DSL property classes to be
9
+ # used as the yielded object inside each section DSL
10
+ # scope.
11
+ #
12
+ # For example the below code will yield an instance of
13
+ # one of this class children.
14
+ #
15
+ # in_index do
16
+ # # This will yield an instance of this class child
17
+ # end
18
+ #
19
+ # The most important note in this class is that all the public
20
+ # methods that their name starts with an underscore (_) not meant to
21
+ # be used as DSL.
22
+ def initialize(model)
23
+ @action_buttons = []
24
+ @model = model
25
+ @fields = resolve_model_reflections
26
+ @fields_type = {}
27
+ end
28
+
29
+ # Allow user to specify an array of model attributes to be used
30
+ # in respected section. For example attributes to show as header
31
+ # columns in index section
32
+ def attributes(*fields_name, **options, &block)
33
+ if options.include? :except
34
+ @fields = resolve_model_reflections.reject do |field|
35
+ options[:except].include? field.to_sym
36
+ end
37
+ elsif options.include? :append
38
+
39
+ @fields += options[:append]
40
+ else
41
+
42
+ # Check for valid field names
43
+ fields_name.each do |name|
44
+ unless @fields.include? name.to_s
45
+ raise ArgumentError, "can't find '#{name}' field for model '#{model}'."
46
+ end
47
+ end
48
+ # set new value for fields
49
+ @fields = fields_name.map(&:to_s) unless fields_name.empty?
50
+ end
51
+
52
+ @fields.concat(block.call.map(&:to_s)) if block_given?
53
+ end
54
+
55
+ # Return the default scope for current properties object.
56
+ # scope will be used to fetch all the records for the given
57
+ # section. The Default implementation belongs to index section
58
+ # and return a page aware list of all the objects.
59
+ #
60
+ # You can easily change it via the corresponding section dsl.
61
+ # For example in case of `index` section:
62
+ #
63
+ # in_index do |index|
64
+ # index.scope do |params|
65
+ # YourModel.all
66
+ # end
67
+ #
68
+ # # or ...
69
+ #
70
+ # scope :my_scope
71
+ # end
72
+ #
73
+ # private
74
+ # def my_scope
75
+ # YourModel.where(...)
76
+ #
77
+ # end
78
+ #
79
+ # Arguments:
80
+ # * **params**: Is the same params passed to controller action.
81
+ def scope(name = nil, &block)
82
+ return @default_scope = block if block_given?
83
+ @default_scope = name.to_sym
84
+ end
85
+
86
+ # Define a new action on the `action` place of the current section
87
+ # **options**: Is a hash which contains the action button properties.
88
+ #
89
+ # `name`: Label to use with the button.
90
+ # `href`: The link href to use in the `a` tag
91
+ # `class`: classes of the button.
92
+ # `icon_class`: font awesome icon to use in button.
93
+ def action_button(**options)
94
+ @action_buttons ||= []
95
+ @action_buttons << options
96
+ @action_buttons.uniq!
97
+ end
98
+
99
+ private
100
+
101
+ # Replace foreign key names with their reflection names
102
+ # and create an array of model fields
103
+ def resolve_model_reflections
104
+ # TODO: cach the result using and instance_var or something
105
+ reflections = model.reflections
106
+ columns = Set.new model.column_names
107
+ new_fields = Set.new
108
+ fields_to_remove = Set.new
109
+
110
+ reflections.each do |name, column|
111
+ has_many = ActiveRecord::Reflection::HasManyReflection
112
+ has_and_belongs_to_many = ActiveRecord::Reflection::HasAndBelongsToManyReflection
113
+
114
+ if !column.is_a?(has_many) && !column.is_a?(has_and_belongs_to_many)
115
+ new_fields << name.to_s
116
+ fields_to_remove << column.foreign_key.to_s
117
+ end
118
+ end
119
+
120
+ if model.respond_to? :attachment_definitions
121
+ # Paperclip is installed and model contains attachments
122
+ model.attachment_definitions.each do |name, _|
123
+ new_fields << name.to_s
124
+ ["file_name", "content_type", "file_size", "updated_at"].each do |x|
125
+ fields_to_remove << "#{name}_#{x}"
126
+ end
127
+ end
128
+ end
129
+
130
+ columns.union(new_fields) - fields_to_remove
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,116 @@
1
+ require_dependency 'underworld/dashboard/dsl/base'
2
+
3
+ module Underworld::Dashboard::DSL
4
+ class Create < Base
5
+
6
+ def initialize(model)
7
+ super
8
+ @field_details = {}
9
+ end
10
+
11
+ # Specify attributes details, for example if you want to change a datetime
12
+ # field type to string you need to do like this:
13
+ #
14
+ # in_form do
15
+ # attributes_properties date: { as: :string }
16
+ # end
17
+ def attributes_properties(**options)
18
+ options_set = Set.new options.keys.map(&:to_s)
19
+
20
+ unless options_set.subset? Set.new(@fields)
21
+ fail "You have to provide correct attribute names in" +
22
+ "'attributes_properties' for '#{@model}'."
23
+ end
24
+
25
+ # TODO: Check for valid value for each key
26
+ @field_details = options || {}
27
+ end
28
+
29
+ def _field_details
30
+ details = @field_details.dup
31
+
32
+ fields_for_form.each do |field|
33
+ if !details.include? field.to_sym
34
+
35
+ type = guess_field_type(field)
36
+ details[field.to_sym] = initialize_field(field.to_sym, type)
37
+ end
38
+ end
39
+
40
+ details
41
+ end
42
+
43
+ def fields_for_form
44
+ fields_name = @fields.dup
45
+
46
+ fields_name.delete('id')
47
+ fields_name.delete('created_at')
48
+ fields_name.delete('updated_at')
49
+
50
+ fields_name
51
+ end
52
+
53
+ private
54
+
55
+ def guess_field_type(field)
56
+ column = model.columns_hash[field.to_s]
57
+ return column.type.to_sym unless column.nil?
58
+
59
+ return :file if has_attachment? field.to_sym
60
+
61
+ has_many = ActiveRecord::Reflection::HasManyReflection
62
+ has_and_belongs_to_many = ActiveRecord::Reflection::HasAndBelongsToManyReflection
63
+ reflection = model.reflections[field.to_s]
64
+
65
+ unless reflection.nil?
66
+ return nil if reflection.is_a? has_many
67
+ return :multiple_select if reflection.is_a? has_and_belongs_to_many
68
+ :select
69
+ end
70
+ end
71
+
72
+ def has_attachment?(name)
73
+ if model.respond_to? :attachment_definitions
74
+ return true if model.attachment_definitions.keys.include? name
75
+ end
76
+
77
+ false
78
+ end
79
+
80
+ def initialize_field(name, type)
81
+ if respond_to?("setup_#{type}".to_sym, true)
82
+ return send("setup_#{type}", name)
83
+ end
84
+ { as: type.to_sym }
85
+ end
86
+
87
+ def setup_datetime(name)
88
+ { as: :string,
89
+ input_html: { class: 'datetimepicker' }
90
+ }
91
+ end
92
+
93
+ def setup_time(name)
94
+ { as: :string,
95
+ input_html: { class: 'timepicker' }
96
+ }
97
+ end
98
+
99
+ def setup_date(name)
100
+ { as: :string,
101
+ input_html: { class: 'datepicker1' }
102
+ }
103
+ end
104
+
105
+ def setup_multiple_select(name)
106
+ { as: :select,
107
+ input_html: { class: 'multiple select' }
108
+ }
109
+ end
110
+
111
+ def setup_integer(name)
112
+ { as: nil }
113
+ end
114
+
115
+ end
116
+ end
@@ -0,0 +1,62 @@
1
+ module Underworld::Dashboard
2
+ class FormFieldsProperties
3
+
4
+ def initializer
5
+ @fields = {}
6
+ end
7
+
8
+ def fields=(all_fields)
9
+ fields.each do |name, field|
10
+ unless all_fields.include? name.to_s
11
+ raise ArgumentError, "'#{name}' is not a valid field"
12
+ end
13
+ end
14
+
15
+ all_fields.each do |name, field|
16
+ unless fields.include?(name.to_sym)
17
+
18
+ Rails.logger.debug("FIELD NAME: #{name}")
19
+ Rails.logger.debug("FIELD TYPE: #{field.type}")
20
+
21
+ if self.respond_to?("setup_#{field.type}".to_sym, true)
22
+ puts "sdasda" * 100
23
+ send("setup_#{field.type}", name)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def fields
30
+ @fields || {}
31
+ end
32
+
33
+ def []=(name, detail)
34
+ @fields ||= {}
35
+ @fields[name.to_sym] = detail
36
+ end
37
+
38
+ def [](index)
39
+ unless @fields.nil?
40
+ return @fields[index] || {}
41
+ end
42
+ {}
43
+ end
44
+
45
+ def method_missing(m, *args, &block)
46
+ @fields ||= {}
47
+ if self.respond_to? m
48
+ return self.send(m, *args, &block)
49
+ else
50
+ # FIXME: This probably is a bad idea. We should get the whole
51
+ # args
52
+ @fields[m] = args[0]
53
+ end
54
+ end
55
+
56
+ def to_hash
57
+ fields
58
+ end
59
+
60
+
61
+ end
62
+ end
@@ -0,0 +1,45 @@
1
+ require_dependency 'underworld/dashboard/dsl/base'
2
+
3
+ module Underworld::Dashboard::DSL
4
+ class Index < Base
5
+ attr_reader :tool_buttons
6
+
7
+ # Allow user to specify an array of model attributes to be used
8
+ # in respected section. For example attributes to show as header
9
+ # columns in index section
10
+ def attributes(*fields_name, **options, &block)
11
+ if options.include? :except
12
+ @fields = resolve_model_reflections.reject do |field|
13
+ options[:except].include? field.to_sym
14
+ end
15
+ elsif options.include? :append
16
+ @fields += options[:append]
17
+ else
18
+ # set new value for fields
19
+ @fields = fields_name.map(&:to_s) unless fields_name.empty?
20
+ end
21
+
22
+ @fields.concat(block.call.map(&:to_s)) if block_given?
23
+ end
24
+
25
+ # Define a new tool on the `tool` place of the index section
26
+ # **options**: Is a hash which contains the tool button properties.
27
+ #
28
+ # `name`: name of the button. used as identifier
29
+ # `class`: classes of the button.
30
+ # `icon_class`: font awesome icon to use in button.
31
+ # `remote`: whether
32
+ #
33
+ # You have to provide a block for this method which returns
34
+ # a string to be used as the **href** for the link
35
+ def tool_button(**options, &block)
36
+ fail 'You have to provide a block for `tool_button`' if !block_given?
37
+
38
+ options[:block] = block
39
+ @tool_buttons ||= {}
40
+ @tool_buttons[options[:name]] = options
41
+ end
42
+
43
+ alias_method :table_fields, :attributes
44
+ end
45
+ end
@@ -0,0 +1,6 @@
1
+ require_dependency 'underworld/dashboard/dsl/base'
2
+
3
+ module Underworld::Dashboard::DSL
4
+ class Show < Index
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ require_dependency 'underworld/dashboard/dsl/base'
2
+
3
+ module Underworld::Dashboard::DSL
4
+ class Update < Base
5
+ end
6
+ end
@@ -0,0 +1,129 @@
1
+ module Underworld::Dashboard
2
+ module Helpers
3
+ module BoxHelpers
4
+
5
+ class Box
6
+ def footer(&block)
7
+ return @footer = nil unless block_given?
8
+ @footer = block
9
+ end
10
+
11
+ def body(&block)
12
+ @body = block
13
+ end
14
+
15
+ def footer_content
16
+ @footer
17
+ end
18
+
19
+ def body_content
20
+ @body
21
+ end
22
+ end
23
+
24
+ class Tabs
25
+
26
+ class Tab
27
+ attr_reader :title, :title_icon
28
+ attr_accessor :content, :id
29
+
30
+ def initialize(title, **options)
31
+ @title = title
32
+ @active = false
33
+ @active = true if options[:active] == true
34
+ @title_icon = options[:title_icon]
35
+ end
36
+
37
+ def active?
38
+ @active
39
+ end
40
+ end
41
+
42
+ attr_reader :title_icon
43
+
44
+ def initialize(**options)
45
+ @tabs = []
46
+ @title_icon = options[:title_icon]
47
+ end
48
+
49
+
50
+ def tab(title, **options, &block)
51
+ id = @tabs.length
52
+ tab = Tab.new(title, **options)
53
+ tab.content = block
54
+ tab.id = id
55
+ @tabs << tab
56
+ end
57
+
58
+ def tabs
59
+ @tabs
60
+ end
61
+ end
62
+
63
+ def box(title = nil, **options)
64
+ content = Box.new
65
+
66
+ yield content
67
+
68
+ result = "<div class='box #{options[:box_class] || 'box-default'}'>" +
69
+ "<div class='box-header with-border'>" +
70
+ "<h3 class='box-title'>" +
71
+ title +
72
+ '</h3>'
73
+
74
+ unless options[:show_tools].nil?
75
+ result += "<div class='box-tools pull-right'>" +
76
+ "<button class='btn btn-box-tool' data-widget='collapse'>" +
77
+ "<i class='fa fa-minus'></i></button>" +
78
+ "</div><!-- /.box-tools -->"
79
+ end
80
+
81
+ result += "</div><!-- /.box-header -->" +
82
+ "<div class='box-body'>" +
83
+ capture(&content.body_content) +
84
+ "</div><!-- /.box-body -->"
85
+
86
+ unless content.footer_content.nil?
87
+ result += '<div class="box-footer">' +
88
+ content.footer_content +
89
+ "</div><!-- /.box-footer-->"
90
+ end
91
+
92
+ result += "</div><!-- /.box -->"
93
+
94
+ result.html_safe
95
+ end
96
+
97
+
98
+ def tabbed_box(title = nil, **options)
99
+ content = Tabs.new
100
+
101
+ yield content
102
+
103
+ result = "<div class='nav-tabs-custom'>" +
104
+ "<ul class='nav nav-tabs pull-right'>"
105
+
106
+ content.tabs.each do |tab|
107
+ active = nil
108
+ active = "class='active'" if tab.active?
109
+
110
+ result += "<li #{active}><a href='#tab_#{tab.id}-#{tab.id}' data-toggle='tab'>" +
111
+ "<i class='fa #{tab.title_icon}'></i> #{tab.title}</a></li>"
112
+ end
113
+
114
+ result += "<li class='pull-left header'><i class='fa #{options[:title_icon]}'></i>#{title}</li>" +
115
+ "</ul>" +
116
+ "<div class='tab-content'>"
117
+
118
+ content.tabs.each do |tab|
119
+ result += "<div class='tab-pane #{'active' if tab.active?}' id='tab_#{tab.id}-#{tab.id}'>" +
120
+ capture(&tab.content) +
121
+ "</div><!-- /.tab-pane -->"
122
+ end
123
+
124
+ result += "</div><!-- /.tab-content --></div>"
125
+ result.html_safe
126
+ end
127
+ end
128
+ end
129
+ end