hyper_admin 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/hyper_admin/angularjs/config.js.coffee +12 -0
  3. data/app/assets/javascripts/hyper_admin/angularjs/controllers/edit_ctrl.js.coffee +5 -0
  4. data/app/assets/javascripts/hyper_admin/angularjs/controllers/form_ctrl.js.coffee +40 -0
  5. data/app/assets/javascripts/hyper_admin/angularjs/controllers/index_ctrl.js.coffee +7 -0
  6. data/app/assets/javascripts/hyper_admin/angularjs/controllers/main_ctrl.js.coffee +3 -0
  7. data/app/assets/javascripts/hyper_admin/angularjs/controllers/navbar_ctrl.js.coffee +8 -0
  8. data/app/assets/javascripts/hyper_admin/angularjs/controllers/new_ctrl.js.coffee +5 -0
  9. data/app/assets/javascripts/hyper_admin/angularjs/controllers/show_ctrl.js.coffee +9 -0
  10. data/app/assets/javascripts/hyper_admin/angularjs/directives/delete_link.js.coffee +8 -0
  11. data/app/assets/javascripts/hyper_admin/angularjs/directives/flash_messages.js.coffee +11 -0
  12. data/app/assets/javascripts/hyper_admin/angularjs/directives/form/form_actions.js.coffee +16 -0
  13. data/app/assets/javascripts/hyper_admin/angularjs/directives/form/form_errors.js.coffee +22 -0
  14. data/app/assets/javascripts/hyper_admin/angularjs/directives/form/form_input.js.coffee +18 -0
  15. data/app/assets/javascripts/hyper_admin/angularjs/directives/form/form_input_group.js.coffee +23 -0
  16. data/app/assets/javascripts/hyper_admin/angularjs/directives/form/resource_form.js.coffee +27 -0
  17. data/app/assets/javascripts/hyper_admin/angularjs/directives/page_header.js.coffee +12 -0
  18. data/app/assets/javascripts/hyper_admin/angularjs/directives/table/resource_table.js.coffee +23 -0
  19. data/app/assets/javascripts/hyper_admin/angularjs/directives/table/table_row.js.coffee +18 -0
  20. data/app/assets/javascripts/hyper_admin/angularjs/filters/truncate.js.coffee +8 -0
  21. data/app/assets/javascripts/hyper_admin/angularjs/services/flash.js.coffee +15 -0
  22. data/app/assets/javascripts/hyper_admin/angularjs/states.js.coffee +37 -0
  23. data/app/assets/javascripts/hyper_admin/application.js.coffee +8 -0
  24. data/app/assets/stylesheets/hyper_admin/application.css.sass +1 -0
  25. data/app/assets/stylesheets/hyper_admin/forms.css.sass +19 -0
  26. data/app/controllers/hyper_admin/application_controller.rb +0 -8
  27. data/app/controllers/hyper_admin/resource_classes_controller.rb +20 -0
  28. data/app/controllers/hyper_admin/resource_controller.rb +21 -13
  29. data/app/views/admin/resources/_form.html.erb +34 -26
  30. data/app/views/admin/resources/_resource.json.jbuilder +3 -0
  31. data/app/views/admin/resources/edit.html.erb +7 -8
  32. data/app/views/admin/resources/index.html.erb +49 -38
  33. data/app/views/admin/resources/index.json.jbuilder +3 -0
  34. data/app/views/admin/resources/new.html.erb +7 -8
  35. data/app/views/admin/resources/show.html.erb +50 -15
  36. data/app/views/admin/resources/show.json.jbuilder +1 -0
  37. data/app/views/hyper_admin/resource_classes/index.json.jbuilder +23 -0
  38. data/app/views/hyper_admin/resource_classes/show.json.jbuilder +21 -0
  39. data/app/views/layouts/hyper_admin/application.html.erb +13 -9
  40. data/config/routes.rb +1 -0
  41. data/lib/hyper_admin/version.rb +1 -1
  42. data/lib/hyper_admin.rb +2 -0
  43. data/spec/dummy/app/models/person.rb +3 -0
  44. data/spec/dummy/config/locales/en.yml +4 -0
  45. data/spec/dummy/config/routes.rb +2 -0
  46. data/spec/dummy/db/development.sqlite3 +0 -0
  47. data/spec/dummy/db/migrate/20140916195117_add_published_at_to_articles.rb +5 -0
  48. data/spec/dummy/db/migrate/20140916210918_add_email_to_people.rb +5 -0
  49. data/spec/dummy/db/migrate/20140916211114_add_url_to_people.rb +5 -0
  50. data/spec/dummy/db/migrate/20140916211657_add_birthday_to_people.rb +5 -0
  51. data/spec/dummy/db/schema.rb +5 -1
  52. data/spec/dummy/log/development.log +15339 -0
  53. data/spec/dummy/log/test.log +33 -0
  54. data/spec/dummy/tmp/cache/assets/development/sprockets/01924c706dd1b7de217f342099dcfa3f +0 -0
  55. data/spec/dummy/tmp/cache/assets/development/sprockets/06f8c2a573a416251bf5e507d716a2e1 +0 -0
  56. data/spec/dummy/tmp/cache/assets/development/sprockets/0f187a2ccdd305e6d153597ecd00bf3b +0 -0
  57. data/spec/dummy/tmp/cache/assets/development/sprockets/125ec787290ff1586c163c0ca12ba62f +0 -0
  58. data/spec/dummy/tmp/cache/assets/development/sprockets/129ae300cd13764786ea4b5704c0503c +0 -0
  59. data/spec/dummy/tmp/cache/assets/development/sprockets/1390e33dca626e5abb05f08e99b336ef +0 -0
  60. data/spec/dummy/tmp/cache/assets/development/sprockets/182fae6bb2ded49fb9e1a2fb6b0ed5be +0 -0
  61. data/spec/dummy/tmp/cache/assets/development/sprockets/1a17fb3abd9919e28b6af53bad5cfcd6 +0 -0
  62. data/spec/dummy/tmp/cache/assets/development/sprockets/1f2d024064a1603f3d45f322414e3eb6 +0 -0
  63. data/spec/dummy/tmp/cache/assets/development/sprockets/1f9d2e324ff8491fae3c73ad41e07c94 +0 -0
  64. data/spec/dummy/tmp/cache/assets/development/sprockets/20533c55869299ed9aa5b4c019517dc8 +0 -0
  65. data/spec/dummy/tmp/cache/assets/development/sprockets/210dc54df072ff8aa801be4a5cfaa52c +0 -0
  66. data/spec/dummy/tmp/cache/assets/development/sprockets/21f2070c3edc32aeeb85d9ce4f9f84de +0 -0
  67. data/spec/dummy/tmp/cache/assets/development/sprockets/22282a54aa58df7a70e3177452e4013a +0 -0
  68. data/spec/dummy/tmp/cache/assets/development/sprockets/233eb26722587b9bedfea4efdb95844d +0 -0
  69. data/spec/dummy/tmp/cache/assets/development/sprockets/246cd7d124c2b5c489c92ff0c1db047d +0 -0
  70. data/spec/dummy/tmp/cache/assets/development/sprockets/265e1b8b1f67b586e82cf68693d6000b +0 -0
  71. data/spec/dummy/tmp/cache/assets/development/sprockets/283aabf8eaa95b30342ac59ec1fa1313 +0 -0
  72. data/spec/dummy/tmp/cache/assets/development/sprockets/2aa9269bc07919114bffba5e9c919561 +0 -0
  73. data/spec/dummy/tmp/cache/assets/development/sprockets/2b9b2182b16b5a4c3c5d1560df5de0d0 +0 -0
  74. data/spec/dummy/tmp/cache/assets/development/sprockets/30a5c1dbe092e168fe430bbb41f374de +0 -0
  75. data/spec/dummy/tmp/cache/assets/development/sprockets/31e25d39e4c17797d201e2a4243efb4a +0 -0
  76. data/spec/dummy/tmp/cache/assets/development/sprockets/3359accba5cc1fb307a5afbefc314c99 +0 -0
  77. data/spec/dummy/tmp/cache/assets/development/sprockets/36b7ac26ce8d497f663785ede3b1069e +0 -0
  78. data/spec/dummy/tmp/cache/assets/development/sprockets/36e5b3d779b93cb69f60386bbc521bc0 +0 -0
  79. data/spec/dummy/tmp/cache/assets/development/sprockets/3a89445fd816e24e5e7c863fdc42b675 +0 -0
  80. data/spec/dummy/tmp/cache/assets/development/sprockets/3d8764a7279799826e72bb55e4fafe26 +0 -0
  81. data/spec/dummy/tmp/cache/assets/development/sprockets/3dfce56bcf85a8a70d6306eace2b2e0e +0 -0
  82. data/spec/dummy/tmp/cache/assets/development/sprockets/3fc47eb10fa7224c92423534c9671a23 +0 -0
  83. data/spec/dummy/tmp/cache/assets/development/sprockets/4143364cc108fcecd6281314d82d47f4 +0 -0
  84. data/spec/dummy/tmp/cache/assets/development/sprockets/41bb46727f2d6c961f664ec0bab005af +0 -0
  85. data/spec/dummy/tmp/cache/assets/development/sprockets/45f0889ff048a64505d5206b7b33ead1 +0 -0
  86. data/spec/dummy/tmp/cache/assets/development/sprockets/481acac6eeb5c92456356785e900be1a +0 -0
  87. data/spec/dummy/tmp/cache/assets/development/sprockets/4878081f8996c1f15bfba3f2a2180992 +0 -0
  88. data/spec/dummy/tmp/cache/assets/development/sprockets/49437706323ed3c6250b7e6b2d4ca84a +0 -0
  89. data/spec/dummy/tmp/cache/assets/development/sprockets/4cc704d7bdd419b79bf65609f24a8ca0 +0 -0
  90. data/spec/dummy/tmp/cache/assets/development/sprockets/5817d714b843218e26feb1bbf2c64a4a +0 -0
  91. data/spec/dummy/tmp/cache/assets/development/sprockets/5d2d334072610a8b33f89e1c1e3b09f1 +0 -0
  92. data/spec/dummy/tmp/cache/assets/development/sprockets/5dda74c0c8b6f1468aae30b26a2de87c +0 -0
  93. data/spec/dummy/tmp/cache/assets/development/sprockets/5e0bb4ec4d880a8d13aa3fb4f56f8dba +0 -0
  94. data/spec/dummy/tmp/cache/assets/development/sprockets/62f93a3bdbe098f4c6d495ad2a2a9e54 +0 -0
  95. data/spec/dummy/tmp/cache/assets/development/sprockets/6b2211be110fb2e55b3c112d41e62a67 +0 -0
  96. data/spec/dummy/tmp/cache/assets/development/sprockets/750defd195c7e34d0b8ff410451e164f +0 -0
  97. data/spec/dummy/tmp/cache/assets/development/sprockets/76db8861208428afff99184b4b87410a +0 -0
  98. data/spec/dummy/tmp/cache/assets/development/sprockets/835213f339beaa129e265d17814d92a9 +0 -0
  99. data/spec/dummy/tmp/cache/assets/development/sprockets/83a638f9944e25db78590de89d9f6580 +0 -0
  100. data/spec/dummy/tmp/cache/assets/development/sprockets/86709205fe01b8340285e06f0f7b9540 +0 -0
  101. data/spec/dummy/tmp/cache/assets/development/sprockets/875cfb30bea588bd29ea187083a02927 +0 -0
  102. data/spec/dummy/tmp/cache/assets/development/sprockets/888680ef9887d508fb9f94d306e58986 +0 -0
  103. data/spec/dummy/tmp/cache/assets/development/sprockets/8a3a1ff827df47a7a8d90a7c41e1549f +0 -0
  104. data/spec/dummy/tmp/cache/assets/development/sprockets/8bed64fba8987e05b7883ec69b84e0b5 +0 -0
  105. data/spec/dummy/tmp/cache/assets/development/sprockets/8fce096622774700a53e0bae363c3931 +0 -0
  106. data/spec/dummy/tmp/cache/assets/development/sprockets/91a5cc4a6166e54d588c8decf774d04a +0 -0
  107. data/spec/dummy/tmp/cache/assets/development/sprockets/944445ca0183d48b09ab52f3813a7a73 +0 -0
  108. data/spec/dummy/tmp/cache/assets/development/sprockets/97a00ae9511caadbf68d011ce54d94ca +0 -0
  109. data/spec/dummy/tmp/cache/assets/development/sprockets/99d492ff5654a4d4b238047d3ced9aa9 +0 -0
  110. data/spec/dummy/tmp/cache/assets/development/sprockets/a1f1fbb9115cf49e86ee8970633e5e7d +0 -0
  111. data/spec/dummy/tmp/cache/assets/development/sprockets/a4531dc856fbec90e4252b3a137cf4fc +0 -0
  112. data/spec/dummy/tmp/cache/assets/development/sprockets/a48ddcfaeabb844016847600a68b0af8 +0 -0
  113. data/spec/dummy/tmp/cache/assets/development/sprockets/a4ccfc66938b201e326831a8c5e4a9b9 +0 -0
  114. data/spec/dummy/tmp/cache/assets/development/sprockets/a965b3ea15d855c3a8c0de0455af861f +0 -0
  115. data/spec/dummy/tmp/cache/assets/development/sprockets/aef10572991d4451e1b77f3ac122d412 +0 -0
  116. data/spec/dummy/tmp/cache/assets/development/sprockets/af31e93a907aa085f33777d42ceceb60 +0 -0
  117. data/spec/dummy/tmp/cache/assets/development/sprockets/afc1c0672e1d6450e3e2c57bbf813de3 +0 -0
  118. data/spec/dummy/tmp/cache/assets/development/sprockets/b9b1856b9db2caaf2e6b4721a86f57d1 +0 -0
  119. data/spec/dummy/tmp/cache/assets/development/sprockets/ba1b9d5a702585ba02b445cbd4f16080 +0 -0
  120. data/spec/dummy/tmp/cache/assets/development/sprockets/bcc36a6e918ec179b87ca0e8d7ac18c5 +0 -0
  121. data/spec/dummy/tmp/cache/assets/development/sprockets/c189bdd96d738128a78ee47e7ed0ca6f +0 -0
  122. data/spec/dummy/tmp/cache/assets/development/sprockets/c27cec6ddeaab0cafd2edbb61e975a95 +0 -0
  123. data/spec/dummy/tmp/cache/assets/development/sprockets/c397f6c9af946760da8841ad05bd4431 +0 -0
  124. data/spec/dummy/tmp/cache/assets/development/sprockets/c671831af9e7e1c6da2f589673c74a6a +0 -0
  125. data/spec/dummy/tmp/cache/assets/development/sprockets/c8730a8220ec89fcf6bb2da7a0f35093 +0 -0
  126. data/spec/dummy/tmp/cache/assets/development/sprockets/cca5ad888c966eeff6b735ed1e55a312 +0 -0
  127. data/spec/dummy/tmp/cache/assets/development/sprockets/d07cbf1d8a0b4b975a59fc017fa29563 +0 -0
  128. data/spec/dummy/tmp/cache/assets/development/sprockets/d397eeece764eeb57c641034f1210be2 +0 -0
  129. data/spec/dummy/tmp/cache/assets/development/sprockets/d4c163fff15a22af5c6e8b63146a2c0b +0 -0
  130. data/spec/dummy/tmp/cache/assets/development/sprockets/d583bba6e1d2c1b41726702d299dd494 +0 -0
  131. data/spec/dummy/tmp/cache/assets/development/sprockets/d7e55f83763944bcc50de5ab23764387 +0 -0
  132. data/spec/dummy/tmp/cache/assets/development/sprockets/d8bd2a2fe67a4fcb7001f1fd53912993 +0 -0
  133. data/spec/dummy/tmp/cache/assets/development/sprockets/dd0e90d5366ba2c0b614457be5afeca2 +0 -0
  134. data/spec/dummy/tmp/cache/assets/development/sprockets/dfbcee5c2f1bc9fc50f9216a0dbce852 +0 -0
  135. data/spec/dummy/tmp/cache/assets/development/sprockets/e166d873a957ea113040c9008439bc30 +0 -0
  136. data/spec/dummy/tmp/cache/assets/development/sprockets/e2907d6b7bc4cb7aba7f283117d15eac +0 -0
  137. data/spec/dummy/tmp/cache/assets/development/sprockets/e7c2a37a322afa44ecd67fccbeffd209 +0 -0
  138. data/spec/dummy/tmp/cache/assets/development/sprockets/e815f671a8bcf1e651eed8dee00eba51 +0 -0
  139. data/spec/dummy/tmp/cache/assets/development/sprockets/e8cac11b7c752cd692b94d83732f4183 +0 -0
  140. data/spec/dummy/tmp/cache/assets/development/sprockets/e9d1c32abde1f876bdef211286c31bf1 +0 -0
  141. data/spec/dummy/tmp/cache/assets/development/sprockets/ebf7e75ff6dd6735ef46a63b0da89668 +0 -0
  142. data/spec/dummy/tmp/cache/assets/development/sprockets/ed3843275b21843a93d01c48c1502c4c +0 -0
  143. data/spec/dummy/tmp/cache/assets/development/sprockets/ee7aee67b689b4238ffc9b404b41dc38 +0 -0
  144. data/spec/dummy/tmp/cache/assets/development/sprockets/f0524602f5c3e166c46feca6e8895d8b +0 -0
  145. data/spec/dummy/tmp/cache/assets/development/sprockets/f0d2b5185b8f10dfc7e41f8c4f379fab +0 -0
  146. data/spec/dummy/tmp/cache/assets/development/sprockets/f50ffee7d1224de2e536e55a94b4b324 +0 -0
  147. data/spec/dummy/tmp/cache/assets/development/sprockets/f8118ba169e2aa16e9a6cc1f0df9b732 +0 -0
  148. data/spec/dummy/tmp/cache/assets/development/sprockets/fcb835765a4145484827b05fcb69812b +0 -0
  149. data/spec/dummy/tmp/cache/assets/development/sprockets/fce44b243bccba1345556e2fb7b0f8ad +0 -0
  150. data/spec/dummy/tmp/pids/server.pid +1 -0
  151. metadata +133 -7
  152. data/app/assets/javascripts/hyper_admin/application.js +0 -2
  153. data/app/assets/stylesheets/hyper_admin/application.css +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca64683cb272c25b4eeb5007b084ae000c24eefc
4
- data.tar.gz: 9c413d53f02d48973e763d79e22e3c17ed41092e
3
+ metadata.gz: 892fb43df29ba674cc93e307fe0da6468f913183
4
+ data.tar.gz: 85c2871d89a0bf17ae5a66e209f4d1b86fbf5b40
5
5
  SHA512:
6
- metadata.gz: 5f4762f95187e6c9528cdaddaa7fc3ab92ee08515396aa08c59d818b3994c9cda96423ed5480251f67819904ce3867904732e97c94428be671c1b281ec021b0c
7
- data.tar.gz: 504312af56071a2148ed7d36c83df58b254592c8ef761e2b9058f284fca5ad7823b647592bfa0210fe79f39e0ea258817aea4c9b58f67325d4d5772e92c93401
6
+ metadata.gz: 33baa5048c224fc55d765c94e9c3aed2bebbaa83b0a7905fc0236ba6287276c362322d1147d1ed20d29695555f767aba0216593c489a11fea3da18a47a836410
7
+ data.tar.gz: a3db6f9479aa407f55115b2a86177c7676591fb95639b1dfe4ac440d2cbf798581062ab44d7bc245c2878b979ed12947686beb52779bbaa4ecf73783233088f4
@@ -0,0 +1,12 @@
1
+ angular.module("hyperadmin", [ "restangular", "ui.router" ])
2
+ .config ($httpProvider) ->
3
+ authToken = $("meta[name=\"csrf-token\"]").attr("content")
4
+ $httpProvider.defaults.headers.common["X-CSRF-TOKEN"] = authToken
5
+ $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"
6
+ $httpProvider.defaults.headers.common["Accept"] = "text/html,application/json"
7
+
8
+ .config ($stateProvider) ->
9
+ window.stateProvider = $stateProvider
10
+
11
+ .config (RestangularProvider) ->
12
+ RestangularProvider.setRequestSuffix '.json'
@@ -0,0 +1,5 @@
1
+ angular.module("hyperadmin")
2
+ .controller "EditCtrl", ($state, resourceClass) ->
3
+ @resource_class = resourceClass
4
+
5
+ this
@@ -0,0 +1,40 @@
1
+ angular.module("hyperadmin")
2
+ .controller "FormCtrl", ($scope, $state, Restangular, Flash) ->
3
+ @resource = { }
4
+ mode = $state.current.data.mode
5
+
6
+ if mode == "new"
7
+ method = "post"
8
+ target = "admin/#{$scope.resourceClass.plural}"
9
+ successMessage = "#{$scope.resourceClass.singular_human} created successfully."
10
+ else
11
+ method = "patch"
12
+ target = "admin/#{$scope.resourceClass.plural}/#{$state.params.id}"
13
+ successMessage = "#{$scope.resourceClass.singular_human} updated successfully."
14
+
15
+ Restangular.one(target).get().then (resource) =>
16
+ @resource = resource
17
+
18
+ $scope.resourceClass.attributes.forEach (attr) =>
19
+ if attr.type == "date" or attr.type == "datetime"
20
+ if @resource[attr.key]
21
+ @resource[attr.key] = new Date @resource[attr.key]
22
+
23
+ [ "id", "created_at", "updated_at" ].forEach (key) ->
24
+ _.remove $scope.resourceClass.attributes, (attr) ->
25
+ attr.key == key
26
+
27
+ @submit = =>
28
+ onError = (response) =>
29
+ @errors = response.data
30
+
31
+ onSuccess = (resource) =>
32
+ $state.go "^.show", id: resource.id
33
+ Flash.setMessage "success", successMessage
34
+
35
+ if method == "post"
36
+ Restangular.all(target).post(@resource).then onSuccess, onError
37
+ else if method == "patch"
38
+ Restangular.one(target).patch(@resource).then onSuccess, onError
39
+
40
+ this
@@ -0,0 +1,7 @@
1
+ angular.module("hyperadmin")
2
+ .controller "IndexCtrl", ($state, Restangular, resourceClass) ->
3
+ @resource_class = resourceClass
4
+ Restangular.all("admin/#{resourceClass.plural}").getList().then (resources) =>
5
+ @resources = Restangular.stripRestangular resources
6
+
7
+ this
@@ -0,0 +1,3 @@
1
+ angular.module("hyperadmin")
2
+ .controller "MainCtrl", ->
3
+ this
@@ -0,0 +1,8 @@
1
+ angular.module("hyperadmin")
2
+ .controller "NavbarCtrl", (Restangular) ->
3
+ Restangular.all("admin/resource_classes").getList().then (resources) =>
4
+ @resources = resources.map (resource) ->
5
+ list_state: "#{resource.plural}"
6
+ label: resource.menu_label
7
+
8
+ this
@@ -0,0 +1,5 @@
1
+ angular.module("hyperadmin")
2
+ .controller "NewCtrl", ($state, resourceClass) ->
3
+ @resource_class = resourceClass
4
+
5
+ this
@@ -0,0 +1,9 @@
1
+ angular.module("hyperadmin")
2
+ .controller "ShowCtrl", ($state, Restangular, resourceClass) ->
3
+ @resource_class = resourceClass
4
+ Restangular.one("admin/#{resourceClass.plural}", $state.params.id).get().then (resource) =>
5
+ @resource = Restangular.stripRestangular resource
6
+
7
+ @template = (attribute) -> "show-#{attribute.type}"
8
+
9
+ this
@@ -0,0 +1,8 @@
1
+ angular.module("hyperadmin")
2
+ .directive "deleteLink", ($http) ->
3
+ link: (scope, element, attributes) ->
4
+ element.off("click").on "click", (event) ->
5
+ event.preventDefault()
6
+
7
+ href = element.attr("href")
8
+ $http(method: "DELETE", url: href) if href
@@ -0,0 +1,11 @@
1
+ angular.module("hyperadmin")
2
+ .directive "flashMessages", (Flash) ->
3
+ template: """
4
+ <aside class="alert alert-{{ flash.getMessage().type }}"
5
+ ng-show="!!flash.getMessage().type">
6
+ <p>{{ flash.getMessage().message }}</p>
7
+ </aside>
8
+ """
9
+ restrict: "E"
10
+ link: (scope) ->
11
+ scope.flash = Flash
@@ -0,0 +1,16 @@
1
+ angular.module("hyperadmin")
2
+ .directive "formActions", ->
3
+ template: """
4
+ <div class="form-group">
5
+ <div class="col-sm-offset-2 col-sm-10">
6
+ <button type="submit" class="btn btn-primary" ng-disabled="form.$invalid">
7
+ Submit
8
+ </button>
9
+ <a class="btn btn-danger" ui-sref="^">Cancel</a>
10
+ </div>
11
+ </div>
12
+ """
13
+ restrict: "E"
14
+ scope:
15
+ cancelState: "=cancelState"
16
+ form: "=form"
@@ -0,0 +1,22 @@
1
+ angular.module("hyperadmin")
2
+ .directive "formErrors", ->
3
+ template: """
4
+ <section class="panel panel-danger" ng-if="errors">
5
+ <div class="panel-heading">
6
+ <h3 class="panel-title">Errors occurred</h3>
7
+ </div>
8
+
9
+ <div class="panel-body">
10
+ <div ng-repeat="(attr, messages) in errors">
11
+ <h4>{{ attr }}</h4>
12
+
13
+ <ul>
14
+ <li ng-repeat="message in messages">{{ message }}</li>
15
+ </ul>
16
+ </div>
17
+ </div>
18
+ </section>
19
+ """
20
+ restrict: "E"
21
+ scope:
22
+ errors: "=errors"
@@ -0,0 +1,18 @@
1
+ angular.module("hyperadmin")
2
+ .directive "formInput", ->
3
+ template: """
4
+ <div class="col-sm-10" ng-class="{ field_with_errors: !!errors }">
5
+ <ng-include src="type"></ng-include>
6
+ <span class="glyphicon glyphicon-remove form-control-feedback"></span>
7
+ <span class="help-block error" ng-show="!!errors" ng-repeat="error in errors">
8
+ {{ placeholder }} {{ error }}
9
+ </span>
10
+ </div>
11
+ """
12
+ restrict: "E"
13
+ scope:
14
+ resource: "=resource"
15
+ name: "=attr"
16
+ placeholder: "=human"
17
+ errors: "=errors"
18
+ type: "=type"
@@ -0,0 +1,23 @@
1
+ angular.module("hyperadmin")
2
+ .directive "formInputGroup", ->
3
+ template: """
4
+ <div class="form-group has-feedback"
5
+ ng-class="{ 'field_with_errors': !!errors }">
6
+ <label class="col-sm-2 control-label" for="{{ attr }}">
7
+ {{ human }}
8
+ </label>
9
+
10
+ <form-input attr="attr" human="human"
11
+ resource="resource" errors="errors"
12
+ type="type">
13
+ </form-input>
14
+ </div>
15
+ """
16
+ restrict: "E"
17
+ scope:
18
+ resource: "=resource"
19
+ attribute: "=attribute"
20
+ attr: "=attr"
21
+ errors: "=errors"
22
+ human: "=human"
23
+ type: "=type"
@@ -0,0 +1,27 @@
1
+ angular.module("hyperadmin")
2
+ .directive "resourceForm", ->
3
+ template: """
4
+ <div class="row">
5
+ <div class="col-xs-12" ng-controller="FormCtrl as formCtrl">
6
+ <form-errors errors="formCtrl.errors"></form-errors>
7
+
8
+ <form class="form-horizontal" name="form" ng-submit="formCtrl.submit()" novalidate>
9
+ <form-input-group ng-repeat="attribute in resourceClass.attributes"
10
+ resource="formCtrl.resource"
11
+ attr="attribute.key"
12
+ errors="formCtrl.errors[attribute.key]"
13
+ human="attribute.human"
14
+ type="attribute.type">
15
+ </form-input-group>
16
+
17
+ <form-actions form="form" cancel-state="resourceClass.plural"
18
+ </form>
19
+ </div>
20
+ </div>
21
+ """
22
+ restrict: "E"
23
+ scope:
24
+ resourceClass: "=resourceClass"
25
+ controller: ($scope) ->
26
+ [ "id", "created_at", "updated_at" ].forEach (attr) ->
27
+ delete $scope.resourceClass.attributes[attr]
@@ -0,0 +1,12 @@
1
+ angular.module("hyperadmin")
2
+ .directive "pageHeader", ->
3
+ transclude: true
4
+ template: """
5
+ <div class="row">
6
+ <div class="col-xs-12">
7
+ <header class="page-header" ng-transclude>
8
+ </header>
9
+ </div>
10
+ </div>
11
+ """
12
+ restrict: "E"
@@ -0,0 +1,23 @@
1
+ angular.module("hyperadmin")
2
+ .directive "resourceTable", ->
3
+ template: """
4
+ <table class="table table-striped">
5
+ <thead>
6
+ <tr>
7
+ <th ng-repeat="attribute in resourceClass.attributes">
8
+ {{ attribute.human }}
9
+ </th>
10
+ <th>Actions</th>
11
+ </tr>
12
+ </thead>
13
+ <tbody>
14
+ <tr table-row attributes="resourceClass.attributes"
15
+ ng-repeat="resource in resources" resource="resource">
16
+ </tr>
17
+ </tbody>
18
+ </table>
19
+ """
20
+ scope:
21
+ resourceClass: "="
22
+ resources: "="
23
+ restrict: "E"
@@ -0,0 +1,18 @@
1
+ angular.module("hyperadmin")
2
+ .directive "tableRow", ->
3
+ template: """
4
+ <td ng-repeat="attribute in attributes">
5
+ <ng-include src="template(attribute)"></ng-include>
6
+ </td>
7
+ <td>
8
+ <a ui-sref=".show({ id: resource.id })">Show</a>
9
+ <a ui-sref=".edit({ id: resource.id })">Edit</a>
10
+ <a ui-sref=".show({ id: resource.id })" delete-link>Destroy</a>
11
+ </td>
12
+ """
13
+ restrict: "A"
14
+ scope:
15
+ attributes: "="
16
+ resource: "="
17
+ link: (scope) ->
18
+ scope.template = (attr) -> "table-#{attr.type}"
@@ -0,0 +1,8 @@
1
+ angular.module("hyperadmin")
2
+ .filter "truncate", ->
3
+ (input, limit = 30) ->
4
+ return '' unless input
5
+ return input unless input.length > limit
6
+
7
+ result = input.substring 0, limit - 1
8
+ result + "…"
@@ -0,0 +1,15 @@
1
+ angular.module("hyperadmin")
2
+ .factory "Flash", ($rootScope) ->
3
+ queue = []
4
+ currentMessage = { }
5
+
6
+ $rootScope.$on "$viewContentLoaded", ->
7
+ currentMessage = queue.shift() || { }
8
+
9
+ setMessage: (type, message) ->
10
+ queue.push
11
+ type: type
12
+ message: message
13
+
14
+ getMessage: ->
15
+ currentMessage
@@ -0,0 +1,37 @@
1
+ angular.module("hyperadmin")
2
+ .config ($locationProvider, $stateProvider, $urlRouterProvider) ->
3
+ $locationProvider.html5Mode true
4
+
5
+ $stateProvider
6
+ .state "index",
7
+ url: "/admin/:pluralName"
8
+ templateUrl: (params) ->
9
+ "/admin/#{params.pluralName}.html"
10
+ controller: "IndexCtrl as indexCtrl"
11
+ resolve:
12
+ resourceClass: ($stateParams, Restangular) ->
13
+ Restangular.one("admin/resource_classes", $stateParams.pluralName).get()
14
+ data:
15
+ resource: "resource"
16
+ .state "index.new",
17
+ url: "/new"
18
+ templateUrl: (params) ->
19
+ "/admin/#{params.pluralName}/new.html"
20
+ controller: "NewCtrl as newCtrl"
21
+ data:
22
+ mode: "new"
23
+ .state "index.show",
24
+ url: "/:id"
25
+ templateUrl: (params) ->
26
+ "/admin/#{params.pluralName}/#{params.id}.html"
27
+ controller: "ShowCtrl as showCtrl"
28
+ data:
29
+ resource: "resource"
30
+ .state "index.edit",
31
+ url: "/:id/edit"
32
+ templateUrl: (params) ->
33
+ "/admin/#{params.pluralName}/#{params.id}/edit.html"
34
+ controller: "EditCtrl as editCtrl"
35
+ data:
36
+ resource: "resource"
37
+ mode: "edit"
@@ -0,0 +1,8 @@
1
+ #= require jquery
2
+ #= require jquery_ujs
3
+ #= require unstable/angular
4
+ #= require angular-ui-router
5
+ #= require lodash
6
+ #= require restangular
7
+ #= require ./angularjs/config
8
+ #= require_tree ./angularjs
@@ -0,0 +1 @@
1
+ //= require hyper_admin/forms
@@ -0,0 +1,19 @@
1
+ .form-control-feedback
2
+ visibility: hidden
3
+
4
+ .field_with_errors
5
+ $error-color: #a94442
6
+ .control-label
7
+ color: $error-color
8
+
9
+ .form-control
10
+ border-color: $error-color
11
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.075)
12
+
13
+ & + .form-control-feedback
14
+ color: $error-color
15
+ visibility: visible
16
+
17
+ & ~ .help-block.error
18
+ color: $error-color
19
+ display: block
@@ -1,12 +1,4 @@
1
1
  module HyperAdmin
2
2
  class ApplicationController < ActionController::Base
3
- before_action :load_all_resource_classes
4
-
5
- protected
6
-
7
- def load_all_resource_classes
8
- collection = ::HyperAdmin.application.resources
9
- @resource_classes = collection.resources.values.map(&:resource_class)
10
- end
11
3
  end
12
4
  end
@@ -0,0 +1,20 @@
1
+ module HyperAdmin
2
+ class ResourceClassesController < ApplicationController
3
+ respond_to :json
4
+
5
+ def index
6
+ collection = ::HyperAdmin.application.resources
7
+ @resource_classes = collection.resources.values.map(&:resource_class)
8
+
9
+ respond_with @resource_classes
10
+ end
11
+
12
+ def show
13
+ collection = ::HyperAdmin.application.resources
14
+ resource_classes = collection.resources.values.map(&:resource_class)
15
+ @resource_class = resource_classes.find { |c| c.model_name.route_key == params[:id] }
16
+
17
+ respond_with @resource_class
18
+ end
19
+ end
20
+ end
@@ -3,33 +3,41 @@ module HyperAdmin
3
3
  before_action :set_resource_class
4
4
  before_action :permit_params, only: [ :create, :update ]
5
5
 
6
+ before_action :set_layout, only: [ :index, :show, :new, :edit ]
7
+
6
8
  def index
7
9
  @resources = resource_class.all
8
- render 'admin/resources/index', layout: layout
10
+ render 'admin/resources/index'
9
11
  end
10
12
 
11
13
  def show
12
14
  @resource = resource
13
- render 'admin/resources/show', layout: layout
15
+ render 'admin/resources/show'
14
16
  end
15
17
 
16
18
  def new
17
19
  @resource = resource_class.new
18
- render 'admin/resources/new', layout: layout
20
+ @attributes = @resource.attributes.delete_if do |k, v|
21
+ k.to_sym.in? [ :id, :created_at, :updated_at ]
22
+ end
23
+ render 'admin/resources/new'
19
24
  end
20
25
 
21
26
  def edit
22
27
  @resource = resource
23
- render 'admin/resources/edit', layout: layout
28
+ @attributes = @resource.attributes.delete_if do |k, v|
29
+ k.to_sym.in? [ :id, :created_at, :updated_at ]
30
+ end
31
+ render 'admin/resources/edit'
24
32
  end
25
33
 
26
34
  def create
27
35
  @resource = @resource_class.new params[@resource_class.model_name.param_key]
28
36
 
29
37
  if @resource.save
30
- redirect_to [ :admin, @resource ]
38
+ render json: @resource
31
39
  else
32
- render "admin/resources/new", layout: layout
40
+ render json: @resource.errors, status: 422
33
41
  end
34
42
  end
35
43
 
@@ -37,9 +45,9 @@ module HyperAdmin
37
45
  @resource = @resource_class.find params[:id]
38
46
 
39
47
  if @resource.update params[@resource_class.model_name.param_key]
40
- redirect_to [ :admin, @resource ]
48
+ render json: @resource
41
49
  else
42
- render "admin/resources/edit", layout: layout
50
+ render json: @resource.errors, status: 422
43
51
  end
44
52
  end
45
53
 
@@ -48,7 +56,7 @@ module HyperAdmin
48
56
 
49
57
  @resource.destroy
50
58
 
51
- redirect_to [ :admin, @resource_class ]
59
+ head 200
52
60
  end
53
61
 
54
62
  def resource
@@ -61,6 +69,10 @@ module HyperAdmin
61
69
 
62
70
  protected
63
71
 
72
+ def set_layout
73
+ self.class.layout ->{ request.xhr? ? false : 'hyper_admin/application' }
74
+ end
75
+
64
76
  def set_resource_class
65
77
  @resource_class = resource_class
66
78
  end
@@ -68,9 +80,5 @@ module HyperAdmin
68
80
  def permit_params
69
81
  params.permit!
70
82
  end
71
-
72
- def layout
73
- 'hyper_admin/application'
74
- end
75
83
  end
76
84
  end
@@ -1,27 +1,35 @@
1
- <div class="row">
2
- <div class="col-xs-12">
3
- <%= form_for [ :admin, resource ], html: { class: 'form-horizontal' } do |form| %>
4
- <%
5
- attributes = resource.attributes.delete_if do |k, v|
6
- k.to_sym.in? [ :id, :created_at, :updated_at ]
7
- end
8
- %>
9
- <% attributes.each do |key, val| %>
10
- <div class="form-group">
11
- <%= form.label key, class: "col-sm-2 control-label" %>
12
- <div class="col-sm-10">
13
- <%= form.text_field key, class: "form-control",
14
- placeholder: resource_class.human_attribute_name(key) %>
15
- </div>
16
- </div>
17
- <% end %>
1
+ <script type="text/ng-template" id="date">
2
+ <input class="form-control" name="{{ name }}" type="date"
3
+ placeholder="{{ placeholder }}" ng-model="resource[name]">
4
+ </script>
18
5
 
19
- <div class="form-group">
20
- <div class="col-sm-offset-2 col-sm-10">
21
- <button type="submit" class="btn btn-primary">Submit</button>
22
- <%= link_to "Cancel", [ :admin, resource_class ], class: "btn btn-danger" %>
23
- </div>
24
- </div>
25
- <% end %>
26
- </div>
27
- </div>
6
+ <script type="text/ng-template" id="datetime">
7
+ <input class="form-control" name="{{ name }}" type="datetime-local"
8
+ placeholder="{{ placeholder }}" ng-model="resource[name]">
9
+ </script>
10
+
11
+ <script type="text/ng-template" id="email">
12
+ <input class="form-control" name="{{ name }}" type="email"
13
+ placeholder="{{ placeholder }}" ng-model="resource[name]">
14
+ </script>
15
+
16
+ <script type="text/ng-template" id="integer">
17
+ <input class="form-control" name="{{ name }}" type="number"
18
+ placeholder="{{ placeholder }}" ng-model="resource[name]" step="1">
19
+ </script>
20
+
21
+ <script type="text/ng-template" id="string">
22
+ <input class="form-control" name="{{ name }}" type="text"
23
+ placeholder="{{ placeholder }}" ng-model="resource[name]">
24
+ </script>
25
+
26
+ <script type="text/ng-template" id="text">
27
+ <textarea class="form-control" name="{{ name }}"
28
+ placeholder="{{ placeholder }}" ng-model="resource[name]">
29
+ </textarea>
30
+ </script>
31
+
32
+ <script type="text/ng-template" id="url">
33
+ <input class="form-control" name="{{ name }}" type="url"
34
+ placeholder="{{ placeholder }}" ng-model="resource[name]">
35
+ </script>
@@ -0,0 +1,3 @@
1
+ resource.attributes.each do |attr, value|
2
+ json.set! attr, value
3
+ end
@@ -1,9 +1,8 @@
1
- <div class="row">
2
- <div class="col-xs-12">
3
- <header class="page-header">
4
- <h1>Edit <%= @resource_class.model_name.singular %></h1>
5
- </header>
6
- </div>
7
- </div>
1
+ <page-header>
2
+ <h1>Edit {{ editCtrl.resource_class.singular }}</h1>
3
+ </page-header>
8
4
 
9
- <%= render "admin/resources/form", resource_class: @resource_class, resource: @resource %>
5
+ <resource-form resource-class="editCtrl.resource_class">
6
+ </resource-form>
7
+
8
+ <%= render "admin/resources/form" %>