localtower 1.0.0 → 2.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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +121 -33
  3. data/app/assets/stylesheets/application.css +68 -0
  4. data/app/controllers/localtower/pages_controller.rb +20 -35
  5. data/app/javascript/application.js +46 -0
  6. data/app/javascript/components/DarkSelect.js +115 -0
  7. data/app/javascript/components/ModernTooltip.js +26 -0
  8. data/app/javascript/components/NewMigrationForm.js +687 -0
  9. data/app/javascript/components/NewModelForm.js +432 -0
  10. data/app/javascript/components/data/Stores.js +294 -0
  11. data/app/views/layouts/localtower/application.html.erb +80 -66
  12. data/app/views/localtower/_migration.html.erb +30 -0
  13. data/app/views/localtower/pages/_alert_no_models.html.erb +1 -1
  14. data/app/views/localtower/pages/migrations.html.erb +24 -55
  15. data/app/views/localtower/pages/new_migration.html.erb +33 -96
  16. data/app/views/localtower/pages/new_model.html.erb +17 -83
  17. data/config/routes.rb +1 -1
  18. data/lib/localtower/engine.rb +5 -2
  19. data/lib/localtower/generators/migration.rb +218 -91
  20. data/lib/localtower/generators/model.rb +29 -20
  21. data/lib/localtower/generators/service_objects/insert_array.rb +5 -3
  22. data/lib/localtower/generators/service_objects/insert_defaults.rb +73 -3
  23. data/lib/localtower/generators/service_objects/insert_foreign_keys.rb +35 -0
  24. data/lib/localtower/generators/service_objects/insert_indexes.rb +41 -18
  25. data/lib/localtower/generators/service_objects/insert_nullable.rb +5 -3
  26. data/lib/localtower/status.rb +3 -1
  27. data/lib/localtower/tools.rb +20 -9
  28. data/lib/localtower/version.rb +1 -1
  29. data/lib/localtower.rb +0 -6
  30. data/public/com/favicon-64.png +0 -0
  31. data/public/com/twitter-cover-1.png +0 -0
  32. data/public/com/twitter-cover-2.png +0 -0
  33. data/public/fonts/Circular/CircularStd-Black.otf +0 -0
  34. data/public/fonts/Circular/CircularStd-BlackItalic.otf +0 -0
  35. data/public/fonts/Circular/CircularStd-Bold.otf +0 -0
  36. data/public/fonts/Circular/CircularStd-BoldItalic.otf +0 -0
  37. data/public/fonts/Circular/CircularStd-Book.otf +0 -0
  38. data/public/fonts/Circular/CircularStd-BookItalic.otf +0 -0
  39. data/public/fonts/Circular/CircularStd-Light Italic.otf +0 -0
  40. data/public/fonts/Circular/CircularStd-Light.otf +0 -0
  41. data/public/fonts/Circular/CircularStd-Medium.otf +0 -0
  42. data/public/fonts/Circular/CircularStd-MediumItalic.otf +0 -0
  43. data/public/fonts/Circular/Read Me.txt +5 -0
  44. data/public/fonts/Circular/www.dfonts.org.url +2 -0
  45. data/public/javascripts/application.js +30830 -0
  46. data/public/javascripts/application.js.map +7 -0
  47. data/public/screenshots/v0.1.1/1_schema.png +0 -0
  48. data/public/screenshots/v0.1.1/2_models_1.png +0 -0
  49. data/public/screenshots/v0.1.1/2_models_2.png +0 -0
  50. data/public/screenshots/v0.1.1/3_relations.png +0 -0
  51. data/public/screenshots/v0.1.1/4_migrations.png +0 -0
  52. data/public/screenshots/v0.1.6/1_schema.png +0 -0
  53. data/public/screenshots/v0.1.6/2_models_1.png +0 -0
  54. data/public/screenshots/v0.1.6/3_relations.png +0 -0
  55. data/public/screenshots/v0.1.6/4_migrations.png +0 -0
  56. data/public/screenshots/v0.1.6/5_capture.png +0 -0
  57. data/public/screenshots/v1.0.0/migrations.png +0 -0
  58. data/public/screenshots/v1.0.0/models.png +0 -0
  59. data/public/screenshots/v1.0.0/new_migration.png +0 -0
  60. data/public/screenshots/v1.0.0/new_model.png +0 -0
  61. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.30.jpg +0 -0
  62. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.42.jpg +0 -0
  63. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.54.jpg +0 -0
  64. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.21.jpg +0 -0
  65. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.28.jpg +0 -0
  66. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.51.jpg +0 -0
  67. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.49.09.jpg +0 -0
  68. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.04.jpg +0 -0
  69. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.11.jpg +0 -0
  70. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.19.jpg +0 -0
  71. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.51.47.jpg +0 -0
  72. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.51.48.jpg +0 -0
  73. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.02.jpg +0 -0
  74. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.18.jpg +0 -0
  75. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.26.jpg +0 -0
  76. data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.38.jpg +0 -0
  77. data/public/screenshots/v2.0.0/migrations.png +0 -0
  78. data/public/screenshots/v2.0.0/new_migration.png +0 -0
  79. data/public/screenshots/v2.0.0/new_model.png +0 -0
  80. data/public/stylesheets/application.css +1179 -0
  81. data/public/vendor/jquery-3.7.1.min.js +2 -0
  82. data/public/vendor/lucide.min.js +12 -0
  83. data/public/vendor/monokai-sublime.css +80 -0
  84. data/public/vendor/rails-ujs.min.js +8 -0
  85. data/spec/dummy/Gemfile +1 -1
  86. data/spec/dummy/Gemfile.lock +140 -102
  87. data/spec/dummy/app/models/user.rb +0 -1
  88. data/spec/dummy/config/database.yml +4 -6
  89. data/spec/dummy/config/puma.rb +1 -1
  90. data/spec/dummy/db/migrate/20241118233214_create_users.rb +9 -0
  91. data/spec/dummy/db/migrate/20241118233233_add_column_titme_for_user.rb +6 -0
  92. data/spec/dummy/db/schema.rb +3 -19
  93. data/spec/dummy/lib/tasks/reset.rake +16 -0
  94. data/spec/dummy/log/development.log +20995 -15969
  95. data/spec/dummy/log/localtower.log +588 -1906
  96. data/spec/dummy/log/test.log +716 -0
  97. data/spec/dummy/tmp/cache/sessions/localtower/726/FE1/_session_id%3A2%3A%3A69d6764784f832ea25700ea2f242210f3f8d94b48912b0f09ffc44311f0376eb +0 -0
  98. data/spec/dummy/tmp/cache/sessions/localtower/77E/121/_session_id%3A2%3A%3A0b3c1fe7154461ba023ba6c81dd1b999348757880b505f4b082faed263a627f9 +1 -0
  99. data/spec/dummy/tmp/cache/sessions/localtower/7EB/8A1/_session_id%3A2%3A%3Af88237c1d157546a5dcde894fd6c1410162a8eba318748d4ac573ee75e40df16 +0 -0
  100. data/spec/dummy/tmp/local_secret.txt +1 -0
  101. data/spec/dummy/tmp/pids/server.pid +1 -1
  102. data/spec/factories/migration.rb +77 -40
  103. data/spec/factories/model.rb +46 -26
  104. data/spec/lib/localtower/generators/migration_spec.rb +16 -24
  105. data/spec/lib/localtower/generators/model_spec.rb +71 -8
  106. data/spec/lib/localtower/generators/service_objects/insert_array_spec.rb +1 -1
  107. data/spec/lib/localtower/generators/service_objects/insert_defaults_spec.rb +1 -1
  108. data/spec/lib/localtower/generators/service_objects/insert_foreign_keys_spec.rb +101 -0
  109. data/spec/lib/localtower/generators/service_objects/insert_indexes_spec.rb +1 -1
  110. data/spec/lib/localtower/generators/service_objects/insert_nullable_spec.rb +2 -2
  111. data/spec/spec_helper.rb +2 -3
  112. metadata +111 -234
  113. data/app/views/localtower/pages/models.html.erb +0 -63
  114. data/public/css/app.css +0 -55
  115. data/public/js/app.js +0 -337
  116. data/public/light-bootstrap-dashboard-master/assets/css/animate.min.css +0 -6
  117. data/public/light-bootstrap-dashboard-master/assets/css/bootstrap.min.css +0 -5
  118. data/public/light-bootstrap-dashboard-master/assets/css/demo.css +0 -61
  119. data/public/light-bootstrap-dashboard-master/assets/css/light-bootstrap-dashboard.css +0 -2789
  120. data/public/light-bootstrap-dashboard-master/assets/css/pe-icon-7-stroke.css +0 -632
  121. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.eot +0 -0
  122. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.svg +0 -212
  123. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.ttf +0 -0
  124. data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.woff +0 -0
  125. data/public/light-bootstrap-dashboard-master/assets/img/default-avatar.png +0 -0
  126. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-0.jpg +0 -0
  127. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-1.jpg +0 -0
  128. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-2.jpg +0 -0
  129. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-3.jpg +0 -0
  130. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-4.jpg +0 -0
  131. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-5.jpg +0 -0
  132. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-6.jpg +0 -0
  133. data/public/light-bootstrap-dashboard-master/assets/img/faces/face-7.jpg +0 -0
  134. data/public/light-bootstrap-dashboard-master/assets/img/faces/tim_vector.jpe +0 -0
  135. data/public/light-bootstrap-dashboard-master/assets/img/favicon.ico +0 -0
  136. data/public/light-bootstrap-dashboard-master/assets/img/loading-bubbles.svg +0 -14
  137. data/public/light-bootstrap-dashboard-master/assets/img/mask.png +0 -0
  138. data/public/light-bootstrap-dashboard-master/assets/img/new_logo.png +0 -0
  139. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-1.jpg +0 -0
  140. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-2.jpg +0 -0
  141. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-3.jpg +0 -0
  142. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-4.jpg +0 -0
  143. data/public/light-bootstrap-dashboard-master/assets/img/sidebar-5.jpg +0 -0
  144. data/public/light-bootstrap-dashboard-master/assets/img/tim_80x80.png +0 -0
  145. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-checkbox-radio-switch.js +0 -502
  146. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-notify.js +0 -404
  147. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-select.js +0 -438
  148. data/public/light-bootstrap-dashboard-master/assets/js/bootstrap.min.js +0 -7
  149. data/public/light-bootstrap-dashboard-master/assets/js/chartist.min.js +0 -9
  150. data/public/light-bootstrap-dashboard-master/assets/js/demo.js +0 -152
  151. data/public/light-bootstrap-dashboard-master/assets/js/jquery-1.10.2.js +0 -9789
  152. data/public/light-bootstrap-dashboard-master/assets/js/light-bootstrap-dashboard.js +0 -179
  153. data/public/logo-localtower-white-300.png +0 -0
  154. data/public/logo-localtower-white.png +0 -0
  155. data/public/logo-localtower.png +0 -0
  156. data/public/vendor/font-awesome.min.css +0 -4
  157. data/public/vendor/highlight-js-default.min.css +0 -9
  158. data/spec/dummy/app/models/post.rb +0 -3
  159. data/spec/dummy/db/migrate/20230119221452_create_users.rb +0 -14
  160. data/spec/dummy/db/migrate/20230119221751_change_users_at1674166670.rb +0 -7
  161. data/spec/dummy/db/migrate/20230119222054_create_posts.rb +0 -11
  162. data/spec/dummy/db/migrate/20230119222106_change_posts_at1674166865.rb +0 -5
  163. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-Y/-YOiiBKqc2UODHFjctm8xc7xFoZaL7zOjWQj6qQ2wyE.cache +0 -1
  164. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-d/-dwueM4vmPt8L51S3jeSyg_AjGDcj0GUN6pDpCA1gCg.cache +0 -3
  165. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0g/0gaJnJQdtd2ACbihXxn8OnjLWlDjnQ_WxfgOpbiLzhg.cache +0 -1
  166. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0r/0rFCsCV9kZnEYtZZ6sfig8329OU31bqjecDFqSVank8.cache +0 -1
  167. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/1J/1J2k_CpnQE3d-PZAQwOVGQALGkta4qVvhdsKjgG0e4Q.cache +0 -0
  168. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2p/2pYVH2Z_syqh6ok8QYxJNKxXpx1Iwppf6JGElZI0gpw.cache +0 -0
  169. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/3W/3WBmqd-2V6q5N-jvbyp-tlcfn3aHYMwBppbOUm7x4qg.cache +0 -1
  170. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/4K/4KFPlHkhdDW0riGUmlbaR-kmDz6JUnQvY6fwW8qsdaE.cache +0 -3
  171. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/6x/6xMeRWmLpNK_flx6-JA3KazvUxSCxyPxHv9Zm3eC26Q.cache +0 -1
  172. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/7d/7dNqI_dCDJLJmI1oM4xwFp9nRRNOem-4P4OD7PMyz2E.cache +0 -0
  173. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/8X/8XquhxVcp5A8QquLtxO8NgKTMJch0eqQmzFmRGIZP6I.cache +0 -1
  174. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ah/AhdfXXtU63kXS4TnsH2Vi1yWgVkIEeV8Z8XA68hrNQc.cache +0 -0
  175. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bt/BtAePnwLSGw82xUGI7wuhWDfuwarOQVS91YqCsweMcs.cache +0 -0
  176. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bx/BxzoG0KxeNLac4xTNeJv3qfeytbNBw58xj2zD-xdbrE.cache +0 -2
  177. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/CC/CCD0ROPX0yxHwNpVZmuP8ZNtgQpaVCMXpdzC0Wb5n24.cache +0 -1
  178. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/DS/DS43oxBg6K5PMWLn2mTy_4EnxI03ehHkxpjV7NCi8yM.cache +0 -1
  179. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Do/Do83AoOat5W-c1g7piDGy2GMmffsY6JY0Qfuh5PY3GM.cache +0 -2
  180. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EI/EI0Nxk-VRATWstMuVCVc0_GdYlQ-a0dx6n2g0l3vIik.cache +0 -0
  181. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EN/ENhJnzJAU2IK-7aHqubj9N8Jo_UTmjG_VEQqyIkolQ8.cache +0 -1
  182. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Fc/FcS6VUHN3Bd4pHGqd5NHA8jA4OLwWrU94s3b4GGxX9c.cache +0 -1
  183. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/G0/G0kukI-r0q0Vbrg6e_jnYJoYcOX8K__h-mwKbCf4twE.cache +0 -0
  184. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/I1/I1Jw08-mz8xzgrgi6giCzpf1UmzGTSbl4eJEw4DAoJM.cache +0 -1
  185. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/IV/IVOO1dXBmgjieDk__g57p6aYt0Z3CmfTa32jhegoyko.cache +0 -3
  186. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/JY/JYPmv5WP4wxdI9EKEEPkK_fVtqeSLfmint_5E8fQLQ8.cache +0 -1
  187. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/MX/MXI3KxaQPZGImSvCNZ_TbQVruWCJ3E0xiVxza1ZCAjM.cache +0 -1
  188. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/OU/OUoioCqXALK909jXPV3VSyCJIdNC7bsogUfdnRTpc5o.cache +0 -1
  189. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/PH/PHjtqNLUPAUDiSlu5AbPjlIo20mOGNm0uNjMLhX2NvM.cache +0 -0
  190. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RC/RC9vfALY5K634pTeau0BAhTHl7d5_5yA3tM-QTLiKtI.cache +0 -0
  191. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RG/RG1PrmlixwaUlG8BV0kcm_3F7OQekxsrLYjBdf403-k.cache +0 -2
  192. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ut/UtoMO6n6FHTpRCGk9VfxlfTI2Ao2GYJ_6kMzx3B9VH8.cache +0 -1
  193. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/VE/VExnbpDk3LxYdPk3htUrZQXPI8NK_zlKtSFfVXJlxU4.cache +0 -1
  194. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Wm/WmKTjykiU-Tx_Faf5zduEeEQ-DozAs5omKToM2l1cZM.cache +0 -0
  195. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/X-/X-KjhDPd0nI155N_FaxFSgaOiYo0_ytqlmkBlLM7ayw.cache +0 -1
  196. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/XX/XXVhj-O91tJ5c8pz7DQlTABOv8TIRVg5haw9VOq9HuI.cache +0 -1
  197. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/YC/YCiifo5NCMwDChFqYFiV4EaYEx8hy3Efle1PsGbIdak.cache +0 -1
  198. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ya/YayMISAqD-Y3vBFywwKrXbUovGf5o77HUF5s8mnQgO0.cache +0 -0
  199. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Zl/Zl-NEb0aDLmZ9gN4gdY1OYlbUXD4JhkFY_y23m55zmo.cache +0 -0
  200. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/_h/_hnjPptBeD3GP5B0iJR6pvyVkiMiq-o2TxaYmGf9KJo.cache +0 -3
  201. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/_p/_poEF6QbTPYJiQCFGoXxIXjmvcn6T0I87ElzJGHguk0.cache +0 -1
  202. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/aa/aaSj2zt8ddc87nZqTpOI9gRCKVnoalXKFBww7t4t3Kg.cache +0 -0
  203. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/bZ/bZHWUkrOLp0WM_Ogo36Qjt4cxDt-rOFgtcj4LNB-BVE.cache +0 -1
  204. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/cP/cPSNG_663TNT944Rke919luRS6FtpMwVc_7aDph645w.cache +0 -1
  205. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ce/ceq8fcZGIoqWrCl9vrCRrywEdx42iy9PrGG9CwFSIF4.cache +0 -0
  206. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/cl/cljhP0Jc018nLnG1rpdg-FUf6mlIqrQYvXTNXTNG9Bw.cache +0 -0
  207. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dm/dmod3fTZdoKso2FGM5RTQtb4kTB6vywsiXLWDygYFN4.cache +0 -1
  208. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dy/dySDGcUTqlKx2MTvOmIEP-WzhyhCfU5xhN9qgxbz3rI.cache +0 -0
  209. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gQ/gQYdmEzbLjTcFCnsfzXzEmeminOchF263snAk3IvXM0.cache +0 -1
  210. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gh/ghvuMAqccBGljlmEaI3Gt5tH5rEg6hseKYMYfRMkHdY.cache +0 -1
  211. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gt/gt8QC7k92A4hXA3HlCpQulW73tqd6x63I3uT-YrGMj0.cache +0 -1
  212. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/hf/hfVg-y7dPSQKbb7V3I7M5w7IpOhDiIB2H31d2tmbZMU.cache +0 -0
  213. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/iF/iFLwyhZIu1Jxm77NUT2qWeTDMmyELW4U85t9rGE_KVg.cache +0 -0
  214. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/kF/kFlIcBBnSyKE00OjpM90pqSn93mLMUv9esz86nrO-Cs.cache +0 -1
  215. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ma/MazNt_5OaYexRuZnccZZ_7AONlxn1a4W3KdWyHyBdws.cache +0 -0
  216. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ma/ma3w08gnDTeqwY2-C9BlToxA6-AS8bvXlu-nBiz0UYs.cache +0 -1
  217. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/n_/n_xYqQYhwEMQknb3jFQnjlxxBE9TzMNHCdJ-bEyZFIw.cache +0 -2
  218. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/nx/nxTv3sKVUQZADJyM3dPaVmUA78MIsMLD_K279yN_GsI.cache +0 -2
  219. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/pv/pv6tV3CDkIAmLXdU8EPLlNEkXAKJPufVD4VP30o4fWo.cache +0 -0
  220. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/qP/qPmv5snMrDw830S6hSICDcnIy7kVEWoFKXhGKT38lG4.cache +0 -2
  221. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/sY/sYvTb1uPWWmnHJNXKuW_xSco-aUb-rN2f0J35zSIzuc.cache +0 -1
  222. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/su/suQ_jjDxRiIn4VEqFJYKaBWJILaeGKBvoTv49XNX0vo.cache +0 -1
  223. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/u8/u8IrW5IIQ7espwk2Vpk23zheL9YZA0tnbKq9X7E-WA0.cache +0 -1
  224. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/wh/whzETExjcZCkn4msasD2aylgfhfpKPZrNxTkY-SOIDg.cache +0 -2
  225. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/x7/x7PYh8DJvPykcEqpVab2vcY9-GFz-3cqtoMlRAu94Uc.cache +0 -2
  226. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/y6/y6oxsJD3pAY9ph1_5M-77uiEjTVw8BheLZNygCKPm1g.cache +0 -1
  227. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/yH/yHZ-a1J23ZCf2n5mEHINMz23Iec2cLGTKauW7k4yGTE.cache +0 -0
  228. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/z7/z7KfUWYoSaGq8tQ5mbHwyfXyT3Pa4FWKJswHcIdJuds.cache +0 -1
  229. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/zu/zuExWc5WHxeOUPZUKHl9a9ZRmN50g7jMOD28macn6M0.cache +0 -0
@@ -0,0 +1,294 @@
1
+ import React from "react";
2
+ import {
3
+ Braces,
4
+ ALargeSmall,
5
+ Calendar1,
6
+ CalendarClock,
7
+ Hash,
8
+ Brackets,
9
+ ListOrdered,
10
+ ToggleRight,
11
+ Binary,
12
+ LetterText,
13
+ Bolt,
14
+ Package,
15
+ CirclePlus,
16
+ CircleMinus,
17
+ RefreshCw,
18
+ } from "lucide-react";
19
+
20
+ const Stores = () => {
21
+ const COLUMN_TYPES = window.COLUMN_TYPES;
22
+ const COLUMN_INDEXES = window.COLUMN_INDEXES;
23
+ const COLUMN_DEFAULTS = window.COLUMN_DEFAULTS;
24
+ const APP_MODELS = window.APP_MODELS;
25
+
26
+ const modelsForSelect = () => {
27
+ return APP_MODELS.map((model) => ({
28
+ value: model.underscore,
29
+ label: (
30
+ <div className="flex flex-row gap-2">
31
+ <div className="py-1 flex justify-center items-center text-localtower-50">
32
+ {model.name}
33
+ </div>
34
+ <div className="text-localtower-400 py-1 flex justify-center items-center text-xss font-mono">
35
+ {model.table_name}
36
+ </div>
37
+ </div>
38
+ ),
39
+ }));
40
+ };
41
+
42
+ const actionsForSelect = () => {
43
+ return COLUMN_ACTIONS.map((action) => ({
44
+ value: action.name,
45
+ label: (
46
+ <div className="flex flex-row gap-2">
47
+ <div className="py-1 flex justify-center items-center w-5 text-localtower-300">
48
+ {iconForAction(action.name)}
49
+ </div>
50
+ <div className="py-1 flex justify-center items-center text-localtower-50">
51
+ {action.label}
52
+ </div>
53
+ <div className="text-localtower-400 py-1 flex justify-center items-center text-xss font-mono">
54
+ {action.example}
55
+ </div>
56
+ </div>
57
+ ),
58
+ }));
59
+ };
60
+
61
+ const modelsForSelectWithout = (excludedModelNames) => {
62
+ return modelsForSelect().filter((entry) => {
63
+ return !excludedModelNames.includes(entry.value);
64
+ });
65
+ };
66
+
67
+ const snakeCase = (str) => {
68
+ return str
69
+ .replace(/\ /g, "_")
70
+ .replace(/[^a-zA-Z0-9\_]/g, "")
71
+ .replace(/\_\_/g, "_")
72
+ .toLowerCase();
73
+ };
74
+
75
+ const modelByValue = (value) => {
76
+ return APP_MODELS.find((model) => model.underscore === value);
77
+ };
78
+
79
+ const filterAttributes = (row) => {
80
+ let model = modelByValue(row.model_name);
81
+
82
+ return model ? model.attributes_list : [];
83
+ };
84
+
85
+ const filterIndexes = (row) => {
86
+ let model = modelByValue(row.model_name);
87
+
88
+ let indexes = [];
89
+
90
+ if (model) {
91
+ let attributes_with_index = model.attributes_list.filter(
92
+ (attribute) => attribute.index.length > 0
93
+ );
94
+
95
+ attributes_with_index.map((attribute) => {
96
+ attribute.index.map((index) => {
97
+ let columns = [index.columns.map((column) => column).join(", ")];
98
+
99
+ indexes.push({
100
+ value: index.name,
101
+ label: (
102
+ <div className="flex flex-row gap-2">
103
+ <div className="py-1 flex justify-center items-center">
104
+ {columns}
105
+ </div>
106
+ <div className="text-localtower-400 py-1 flex justify-center items-center text-xss font-mono">
107
+ {index.name}{" "}
108
+ {index.unique && (
109
+ <span className="bg-localtower-300 text-xs font-sans mx-2 px-2 text-localtower-700 rounded-full">
110
+ unique
111
+ </span>
112
+ )}
113
+ </div>
114
+ </div>
115
+ ),
116
+ });
117
+ });
118
+ });
119
+ }
120
+
121
+ return indexes;
122
+ };
123
+
124
+ const attributesForSelect = (attributes_list, additional = []) => {
125
+ // "additional" is used to add columns that are already in the migration file
126
+ const existingColumns = additional
127
+ .filter((row) => row.action_name === "add_column")
128
+ .filter((row) => row.column_name.length)
129
+ .map((row) => {
130
+ return {
131
+ name: row.column_name,
132
+ type: row.column_type,
133
+ index: [],
134
+ };
135
+ });
136
+
137
+ const list = existingColumns.concat(attributes_list);
138
+
139
+ return list.map((attr) => ({
140
+ value: attr.name,
141
+ label: (
142
+ <div className="flex flex-row gap-2">
143
+ <div className="py-1 flex justify-center items-center">
144
+ {attr.name}
145
+ </div>
146
+ <div className="text-localtower-400 py-1 flex justify-center items-center text-xss font-mono">
147
+ {attr.type}{" "}
148
+ {attr.index.length > 0 && (
149
+ <span className="bg-localtower-300 text-xs font-sans mx-2 px-2 text-localtower-700 rounded-full">
150
+ index
151
+ </span>
152
+ )}
153
+ </div>
154
+ </div>
155
+ ),
156
+ }));
157
+ };
158
+
159
+ const iconForAction = (action) => {
160
+ const size = 17;
161
+ const strokeWidth = 1;
162
+
163
+ if (action.indexOf("add") !== -1 || action === "belongs_to") {
164
+ return <CirclePlus strokeWidth={strokeWidth} size={size} />;
165
+ }
166
+
167
+ if (action.indexOf("remove") !== -1 || action === "drop_table") {
168
+ return <CircleMinus strokeWidth={strokeWidth} size={size} />;
169
+ }
170
+
171
+ if (action.indexOf("change") !== -1 || action === "rename_column") {
172
+ return <RefreshCw strokeWidth={strokeWidth} size={size} />;
173
+ }
174
+
175
+ return;
176
+ };
177
+
178
+ const iconForType = (type) => {
179
+ const size = 17;
180
+ const strokeWidth = 1;
181
+
182
+ if (type === "string") {
183
+ return <ALargeSmall strokeWidth={strokeWidth} size={size} />;
184
+ }
185
+
186
+ if (type === "text") {
187
+ return <LetterText strokeWidth={strokeWidth} size={size} />;
188
+ }
189
+
190
+ if (type === "datetime") {
191
+ return <CalendarClock strokeWidth={strokeWidth} size={size} />;
192
+ }
193
+
194
+ if (type === "date") {
195
+ return <Calendar1 strokeWidth={strokeWidth} size={size} />;
196
+ }
197
+
198
+ if (
199
+ type === "integer" ||
200
+ type === "bigint" ||
201
+ type === "float" ||
202
+ type === "numeric" ||
203
+ type === "decimal"
204
+ ) {
205
+ return <Hash strokeWidth={strokeWidth} size={size} />;
206
+ }
207
+
208
+ if (type === "array") {
209
+ return <Brackets strokeWidth={strokeWidth} size={size} />;
210
+ }
211
+
212
+ if (type === "uuid") {
213
+ return <ListOrdered strokeWidth={strokeWidth} size={size} />;
214
+ }
215
+
216
+ if (type === "json" || type === "jsonb") {
217
+ return <Braces strokeWidth={strokeWidth} size={size} />;
218
+ }
219
+
220
+ if (type === "boolean") {
221
+ return <ToggleRight strokeWidth={strokeWidth} size={size} />;
222
+ }
223
+
224
+ if (type === "binary") {
225
+ return <Binary strokeWidth={strokeWidth} size={size} />;
226
+ }
227
+
228
+ if (type === "blob") {
229
+ return <Package strokeWidth={strokeWidth} size={size} />;
230
+ }
231
+
232
+ if (type === "references") {
233
+ return <Bolt strokeWidth={strokeWidth} size={size} />;
234
+ }
235
+
236
+ return;
237
+ };
238
+
239
+ const typesForSelect = () => {
240
+ return COLUMN_TYPES.map((type) => ({
241
+ value: type.name,
242
+ label: (
243
+ <div className="flex flex-row gap-2 items-center">
244
+ <div className="py-1 flex justify-center items-center w-5 text-localtower-300">
245
+ {iconForType(type.name)}
246
+ </div>
247
+ <div className="py-1 flex justify-center items-center text-localtower-50">
248
+ {type.name}
249
+ </div>
250
+ <div className="text-localtower-400 py-1 flex justify-center items-center text-xss font-mono">
251
+ {type.example}
252
+ </div>
253
+ </div>
254
+ ),
255
+ }));
256
+ };
257
+
258
+ const indexesForSelect = () => {
259
+ return [{ value: "", label: "(none)" }].concat(
260
+ COLUMN_INDEXES.map((type) => ({
261
+ value: type.name,
262
+ label: (
263
+ <div className="flex flex-row gap-2 items-center">
264
+ <div className="py-1 flex justify-center items-center text-localtower-50">
265
+ {type.label || type.name}
266
+ </div>
267
+ <div className="text-localtower-400 py-1 flex justify-center items-center text-xss font-mono">
268
+ {type.example}
269
+ </div>
270
+ </div>
271
+ ),
272
+ }))
273
+ );
274
+ };
275
+
276
+ return {
277
+ actionsForSelect: actionsForSelect,
278
+ modelsForSelect: modelsForSelect,
279
+ typesForSelect: typesForSelect,
280
+ attributesForSelect: attributesForSelect,
281
+ indexesForSelect: indexesForSelect,
282
+ modelsForSelectWithout: modelsForSelectWithout,
283
+ modelByValue: modelByValue,
284
+ filterAttributes: filterAttributes,
285
+ filterIndexes: filterIndexes,
286
+ snakeCase: snakeCase,
287
+ APP_MODELS: APP_MODELS,
288
+ COLUMN_DEFAULTS: COLUMN_DEFAULTS,
289
+ COLUMN_TYPES: COLUMN_TYPES,
290
+ COLUMN_INDEXES: COLUMN_INDEXES,
291
+ };
292
+ };
293
+
294
+ export default Stores;
@@ -5,77 +5,91 @@
5
5
  <meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
6
6
  <meta name="viewport" content="width=device-width" />
7
7
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
8
- <link rel="stylesheet" type="text/css" href="/light-bootstrap-dashboard-master/assets/css/bootstrap.min.css">
9
- <!-- <link rel="stylesheet" type="text/css" href="/light-bootstrap-dashboard-master/assets/css/animate.min.css"> -->
10
- <link rel="stylesheet" type="text/css" href="/light-bootstrap-dashboard-master/assets/css/light-bootstrap-dashboard.css">
11
- <!-- Fonts and icons -->
12
- <link href="/vendor/font-awesome.min.css" rel="stylesheet">
13
- <link rel="stylesheet" type="text/css" href="/light-bootstrap-dashboard-master/assets/css/pe-icon-7-stroke.css">
14
- <link rel="stylesheet" type="text/css" href="/vendor/highlight-js-default.min.css">
15
- <link rel="stylesheet" type="text/css" href="/css/app.css">
8
+
9
+ <link rel="shortcut icon" href="/com/favicon-64.png" type="image/png" />
10
+ <link rel="stylesheet" type="text/css" href="/vendor/monokai-sublime.css">
11
+
12
+ <style>
13
+ @font-face {
14
+ font-family: 'Circular';
15
+ src: url('/fonts/Circular/CircularStd-Book.otf') format('opentype');
16
+ font-weight: 400;
17
+ font-style: normal;
18
+ }
19
+
20
+ @font-face {
21
+ font-family: 'Circular';
22
+ src: url('/fonts/Circular/CircularStd-Medium.otf') format('opentype');
23
+ font-weight: 500;
24
+ font-style: normal;
25
+ }
26
+
27
+ @font-face {
28
+ font-family: 'Circular';
29
+ src: url('/fonts/Circular/CircularStd-Bold.otf') format('opentype');
30
+ font-weight: 700;
31
+ font-style: normal;
32
+ }
33
+ </style>
34
+ <%= stylesheet_link_tag "application" %>
35
+
16
36
  <%= csrf_meta_tags %>
37
+ <script>
38
+ window.COLUMN_TYPES = <%= ::Localtower::Generators::Migration::TYPES.to_json.html_safe %>;
39
+ window.COLUMN_ACTIONS = <%= ::Localtower::Generators::Migration::ACTIONS.to_json.html_safe %>;
40
+ window.COLUMN_INDEXES = <%= ::Localtower::Generators::ServiceObjects::InsertIndexes::USING.to_json.html_safe %>;
41
+ window.COLUMN_INDEXES_ALGORITHMS = <%= ::Localtower::Generators::ServiceObjects::InsertIndexes::ALGO.to_json.html_safe %>;
42
+ window.COLUMN_DEFAULTS = <%= ::Localtower::Generators::ServiceObjects::InsertDefaults::DEFAULTS_BY_TYPE.to_json.html_safe %>;
43
+ window.APP_MODELS = <%= ::Localtower::Tools.models_presented.to_json.html_safe %>;
44
+ </script>
17
45
  </head>
18
- <body>
19
- <div class="wrapper">
20
- <div class="sidebar">
21
- <div class="sidebar-wrapper">
22
- <ul class="nav">
23
- <li class="<%= is_active_link?(models_path, :exclusive) ? "active" : nil %>">
24
- <a href="<%= models_path %>">
25
- <i class="pe-7s-network"></i>
26
- <p>Models</p>
27
- </a>
28
- </li>
29
- <li class="<%= is_active_link?(migrations_path, :exclusive) ? "active" : nil %>">
30
- <a href="<%= migrations_path %>">
31
- <i class="pe-7s-back"></i>
32
- <p>Migrations</p>
33
- </a>
34
- </li>
35
- <li class="<%= is_active_link?(new_model_path, :inclusive) ? "active" : nil %>">
36
- <a href="<%= new_model_path %>">
37
- <i class="pe-7s-server"></i>
38
- <p>New Model</p>
39
- </a>
40
- </li>
41
- <li class="<%= is_active_link?(new_migration_path, :exclusive) ? "active" : nil %>">
42
- <a href="<%= new_migration_path %>">
43
- <i class="pe-7s-edit"></i>
44
- <p>New Migration</p>
45
- </a>
46
- </li>
47
- </ul>
48
- </div>
49
- </div>
50
- <div class="main-panel">
51
- <div class="content">
52
- <div class="container-fluid">
53
- <%= yield %>
54
- </div>
55
- </div>
56
- </div>
57
- </div>
58
- <div class="full-message" style="display: none;">
59
- <div class="text-center">
60
- <br>
61
- <h3>Generating files</h3>
62
- <br>
63
- <i class="pe-7s-refresh-2 rotate"></i>
64
- <br>
65
- <br>
66
- <br>
67
- <p class="full-message-migrate" style="display: none;">
68
- If you're seeing an error message on the next page (pending migrations), just run in your terminal:
69
- <br>
70
- <br>
71
- <code>bundle exec rails db:migrate</code>
72
- </p>
73
- </div>
46
+ <body class="bg-localtower-700 text-localtower-300 text-sm">
47
+ <div class="wrapper flex h-screen">
48
+ <!-- Sidebar -->
49
+ <nav class="w-[200px] flex-shrink-0 h-screen border-r border-localtower-500">
50
+ <ul class="flex flex-col py-2 px-2">
51
+ <li class="py-0.5">
52
+ <a href="<%= new_model_path %>" class="flex flex-row gap-2 items-center px-4 py-2.5 hover:text-white transition-colors duration-200 rounded <%= is_active_link?(new_model_path, :inclusive) ? 'bg-localtower-500 text-localtower-100 hover:bg-localtower-500' : 'text-gray-400 hover:bg-localtower-600' %> active:opacity-70">
53
+ <i data-lucide="circle-plus" class="w-5 " stroke-width="2"></i>
54
+ <p class="text-sm">New Model</p>
55
+ </a>
56
+ </li>
57
+
58
+ <li class="py-0.5">
59
+ <a href="<%= new_migration_path %>" class="flex flex-row gap-2 items-center px-4 py-2.5 hover:text-white transition-colors duration-200 rounded <%= is_active_link?(new_migration_path, :exclusive) ? 'bg-localtower-500 text-localtower-100 hover:bg-localtower-500' : 'text-gray-400 hover:bg-localtower-600' %> active:opacity-70">
60
+ <i data-lucide="circle-plus" class="w-5 " stroke-width="2"></i>
61
+ <p class="text-sm">New Migration</p>
62
+ </a>
63
+ </li>
64
+
65
+ <li class="my-2 border-t border-localtower-500 h-1"></li>
66
+
67
+ <li class="py-0.5">
68
+ <a href="<%= migrations_path %>" class="flex flex-row gap-2 items-center px-4 py-2.5 hover:text-white transition-colors duration-200 rounded <%= is_active_link?(migrations_path, :exclusive) ? 'bg-localtower-500 text-localtower-100 hover:bg-localtower-500' : 'text-gray-400 hover:bg-localtower-600' %> active:opacity-70">
69
+ <i data-lucide="book-plus" class="w-5 " stroke-width="2"></i>
70
+ <p class="text-sm">Migrations</p>
71
+ </a>
72
+ </li>
73
+ </ul>
74
+ </nav>
75
+
76
+ <!-- Main Content -->
77
+ <main class="flex-1 overflow-y-auto p-8">
78
+ <%= yield %>
79
+ </main>
74
80
  </div>
81
+
75
82
  <!-- Core JS Files -->
76
- <script src="/light-bootstrap-dashboard-master/assets/js/jquery-1.10.2.js" type="text/javascript"></script>
83
+ <script src="/vendor/jquery-3.7.1.min.js"></script>
77
84
  <script src="/vendor/highlight.min.js"></script>
78
85
  <script src="/vendor/masonry.pkgd.min.js"></script>
79
- <script src="/js/app.js"></script>
86
+ <script src="/vendor/lucide.min.js"></script>
87
+ <script src="/vendor/rails-ujs.min.js"></script>
88
+
89
+ <script>
90
+ lucide.createIcons();
91
+ </script>
92
+
93
+ <%= javascript_include_tag "application" %>
80
94
  </body>
81
95
  </html>
@@ -0,0 +1,30 @@
1
+ <div class="">
2
+ <div class="">
3
+ <h5 class="py-3 flex flex-row gap-3 items-center">
4
+ <% if entry['status'] == :todo %>
5
+ <div class="rounded-full bg-orange-700 text-localtower-100 text-xs px-3 py-0.5 inline-flex items-center">
6
+ <span>Pending</span>
7
+ </div>
8
+ <% else %>
9
+ <%= form_tag actions_path, class: "inline-flex" do %>
10
+ <button name="cmd" title="rake db:migrate:down VERSION=<%= entry['time'] %>" type="submit" value="rake db:migrate:down VERSION=<%= entry['time'] %>" class="px-2 py-0.5 rounded-md bg-green-800 text-localtower-100 border border-green-700 outline-none hover:border-green-500 hover:bg-green-700 hover:text-white active:opacity-60 transition-colors text-xs inline-flex items-center">
11
+ Rollback
12
+ </button>
13
+ <% end %>
14
+ <% end %>
15
+ <a href="<%= file_link(entry['file_full_path']) %>" class="font-mono text-xs text-localtower-400 inline-flex"><%= entry['relative_path'] %></a>
16
+ <% if entry['status'] == :todo %>
17
+ <%= form_tag rm_file_path, class: "inline-flex" do %>
18
+ <button name="file" title="rake db:migrate:down VERSION=<%= entry['time'] %>" type="submit" value="<%= entry['file_full_path'] %>" class="px-2 py-0.5 rounded-md text-red-500 border border-red-500 hover:border-red-300 outline-none active:opacity-60 transition-colors text-xs inline-flex items-center" data-confirm="Are you sure?">
19
+ destroy
20
+ </button>
21
+ <% end %>
22
+ <% end %>
23
+ </h5>
24
+ </div>
25
+ </div>
26
+ <div class="pb-4 border-b border-localtower-500">
27
+ <div class="">
28
+ <pre class="px-3 py-1.5 rounded border border-localtower-500 block" style="background-color: rgb(35, 36, 31);"><code class="language-ruby text-xs"><%= entry['content'] %></code></pre>
29
+ </div>
30
+ </div>
@@ -1,3 +1,3 @@
1
1
  <div class="alert alert-danger">
2
- You don't have any models in this app. You can create one <%= link_to 'here.', models_path, class: 'btn btn-primary btn-fill btn-xs' %>
2
+ You don't have any models in this app. You can create one <%= link_to 'here.', new_model_path, class: 'font-bold' %>
3
3
  </div>
@@ -1,61 +1,30 @@
1
1
  <% content_for :title do %>Migrations<% end %>
2
- <div class="row">
3
- <div class="col-md-12">
4
- <div class="content">
5
- <% if flash[:notice] %>
6
- <div class="alert alert-info">
7
- <span><%= flash[:notice] %></span>
8
- </div>
2
+ <div class="">
3
+ <% if flash[:notice] %>
4
+ <div class="">
5
+ <span><%= flash[:notice] %></span>
6
+ </div>
7
+ <% end %>
8
+ <div class="flex flex-col gap-3">
9
+ <div class="">
10
+ <% if @migrations.select {|i| i['status'] == :todo}.any? %>
11
+ <%= form_tag actions_path, class: "" do %>
12
+ <button name="cmd" type="submit" value="rails db:migrate" class="px-3 py-1 rounded-md bg-green-800 text-localtower-100 border border-green-700 outline-none hover:border-green-500 hover:bg-green-700 hover:text-white active:opacity-60 transition-colors text-xs inline-flex items-center">
13
+ <code>bundle exec rails db:migrate</code>
14
+ </button>
15
+ <% end %>
9
16
  <% end %>
10
- <div class="card">
11
- <div class="header">
12
- <% if @migrations.select {|i| i['status'] == :todo}.any? %>
13
- <%= form_tag actions_path, class: "form" do %>
14
- <button name="cmd" type="submit" value="rails db:migrate" class="btn btn-warning btn-fill" data-selector="submit">
15
- Migrate Pending Migrations <code>bundle exec rails db:migrate</code>
16
- </button>
17
- <% end %>
18
- <% end %>
19
- </div>
20
- <div class="content">
21
- <% if @migrations.any? %>
22
- <% @migrations.each do |entry| %>
23
- <div class="container-fluid">
24
- <div class="row">
25
- <div class="col-md-12">
26
- <h5 style="color: <%= entry['status'] == :todo ? 'red' : 'green' %>;">
27
- <% if entry['status'] == :todo %>
28
- <button type="button" class="btn btn-danger btn-xs">PENDING</button>
29
- <a href="<%= file_link(entry['file_full_path']) %>"><%= entry['name'] %></a>
30
- <% else %>
31
- <%= form_tag actions_path, class: "form" do %>
32
- <button name="cmd" title="rake db:migrate:down VERSION=<%= entry['time'] %>" type="submit" value="rake db:migrate:down VERSION=<%= entry['time'] %>" class="btn btn-info btn-xs btn-fill">
33
- ROLLBACK
34
- </button>
35
- <a href="<%= file_link(entry['file_full_path']) %>"><%= entry['name'] %></a>
36
- <% end %>
37
- <% end %>
38
- </h5>
39
- </div>
40
- </div>
41
- <div class="row">
42
- <div class="col-md-12">
43
- <pre><code class="language-ruby"><%= entry['content'] %></code></pre>
44
- </div>
45
- </div>
46
- </div>
47
- <% end %>
48
- <% else %>
49
- <div class="card">
50
- <div class="">
51
- </div>
52
- <div class="alert alert-info">
53
- <span>No migrations found</span>
54
- </div>
55
- </div>
56
- <% end %>
17
+ </div>
18
+ <div class="">
19
+ <% if @migrations.any? %>
20
+ <% @migrations.each do |entry| %>
21
+ <%= render partial: 'localtower/migration', locals: { entry: entry } %>
22
+ <% end %>
23
+ <% else %>
24
+ <div class="">
25
+ <span>No migrations found</span>
57
26
  </div>
58
- </div>
27
+ <% end %>
59
28
  </div>
60
29
  </div>
61
30
  </div>