localtower 0.5.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.
- checksums.yaml +4 -4
- data/README.md +129 -33
- data/app/assets/stylesheets/application.css +68 -0
- data/app/controllers/localtower/pages_controller.rb +30 -30
- data/app/javascript/application.js +46 -0
- data/app/javascript/components/DarkSelect.js +115 -0
- data/app/javascript/components/ModernTooltip.js +26 -0
- data/app/javascript/components/NewMigrationForm.js +687 -0
- data/app/javascript/components/NewModelForm.js +432 -0
- data/app/javascript/components/data/Stores.js +294 -0
- data/app/views/layouts/localtower/application.html.erb +77 -80
- data/app/views/localtower/_migration.html.erb +30 -0
- data/app/views/localtower/pages/_alert_no_models.html.erb +3 -0
- data/app/views/localtower/pages/migrations.html.erb +25 -87
- data/app/views/localtower/pages/new_migration.html.erb +40 -0
- data/app/views/localtower/pages/new_model.html.erb +21 -0
- data/config/routes.rb +5 -5
- data/lib/localtower/engine.rb +5 -2
- data/lib/localtower/generators/migration.rb +219 -161
- data/lib/localtower/generators/model.rb +59 -26
- data/lib/localtower/generators/service_objects/insert_array.rb +25 -0
- data/lib/localtower/generators/service_objects/insert_defaults.rb +85 -43
- data/lib/localtower/generators/service_objects/insert_foreign_keys.rb +35 -0
- data/lib/localtower/generators/service_objects/insert_indexes.rb +103 -0
- data/lib/localtower/generators/service_objects/insert_nullable.rb +25 -0
- data/lib/localtower/status.rb +4 -2
- data/lib/localtower/tools.rb +31 -23
- data/lib/localtower/version.rb +1 -1
- data/lib/localtower.rb +0 -6
- data/public/com/favicon-64.png +0 -0
- data/public/com/twitter-cover-1.png +0 -0
- data/public/com/twitter-cover-2.png +0 -0
- data/public/fonts/Circular/CircularStd-Black.otf +0 -0
- data/public/fonts/Circular/CircularStd-BlackItalic.otf +0 -0
- data/public/fonts/Circular/CircularStd-Bold.otf +0 -0
- data/public/fonts/Circular/CircularStd-BoldItalic.otf +0 -0
- data/public/fonts/Circular/CircularStd-Book.otf +0 -0
- data/public/fonts/Circular/CircularStd-BookItalic.otf +0 -0
- data/public/fonts/Circular/CircularStd-Light Italic.otf +0 -0
- data/public/fonts/Circular/CircularStd-Light.otf +0 -0
- data/public/fonts/Circular/CircularStd-Medium.otf +0 -0
- data/public/fonts/Circular/CircularStd-MediumItalic.otf +0 -0
- data/public/fonts/Circular/Read Me.txt +5 -0
- data/public/fonts/Circular/www.dfonts.org.url +2 -0
- data/public/javascripts/application.js +30830 -0
- data/public/javascripts/application.js.map +7 -0
- data/public/screenshots/v0.1.1/1_schema.png +0 -0
- data/public/screenshots/v0.1.1/2_models_1.png +0 -0
- data/public/screenshots/v0.1.1/2_models_2.png +0 -0
- data/public/screenshots/v0.1.1/3_relations.png +0 -0
- data/public/screenshots/v0.1.1/4_migrations.png +0 -0
- data/public/screenshots/v0.1.6/1_schema.png +0 -0
- data/public/screenshots/v0.1.6/2_models_1.png +0 -0
- data/public/screenshots/v0.1.6/3_relations.png +0 -0
- data/public/screenshots/v0.1.6/4_migrations.png +0 -0
- data/public/screenshots/v0.1.6/5_capture.png +0 -0
- data/public/screenshots/v1.0.0/migrations.png +0 -0
- data/public/screenshots/v1.0.0/models.png +0 -0
- data/public/screenshots/v1.0.0/new_migration.png +0 -0
- data/public/screenshots/v1.0.0/new_model.png +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.30.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.42.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.44.54.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.21.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.28.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.48.51.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.49.09.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.04.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.11.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.50.19.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.51.47.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.51.48.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.02.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.18.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.26.jpg +0 -0
- data/public/screenshots/v2.0.0/Screenshot 2024-11-18 at 22.52.38.jpg +0 -0
- data/public/screenshots/v2.0.0/migrations.png +0 -0
- data/public/screenshots/v2.0.0/new_migration.png +0 -0
- data/public/screenshots/v2.0.0/new_model.png +0 -0
- data/public/stylesheets/application.css +1179 -0
- data/public/vendor/jquery-3.7.1.min.js +2 -0
- data/public/vendor/lucide.min.js +12 -0
- data/public/vendor/monokai-sublime.css +80 -0
- data/public/vendor/rails-ujs.min.js +8 -0
- data/spec/dummy/Gemfile +1 -3
- data/spec/dummy/Gemfile.lock +140 -111
- data/spec/dummy/config/database.yml +4 -6
- data/spec/dummy/config/environments/development.rb +1 -0
- data/spec/dummy/db/migrate/20241118233214_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20241118233233_add_column_titme_for_user.rb +6 -0
- data/spec/dummy/db/schema.rb +4 -8
- data/spec/dummy/lib/tasks/reset.rake +16 -0
- data/spec/dummy/log/development.log +21437 -4475
- data/spec/dummy/log/localtower.log +586 -139
- data/spec/dummy/log/test.log +716 -0
- data/spec/dummy/test/index.html +38 -0
- data/spec/dummy/tmp/cache/sessions/localtower/726/FE1/_session_id%3A2%3A%3A69d6764784f832ea25700ea2f242210f3f8d94b48912b0f09ffc44311f0376eb +0 -0
- data/spec/dummy/tmp/cache/sessions/localtower/77E/121/_session_id%3A2%3A%3A0b3c1fe7154461ba023ba6c81dd1b999348757880b505f4b082faed263a627f9 +1 -0
- data/spec/dummy/tmp/cache/sessions/localtower/7EB/8A1/_session_id%3A2%3A%3Af88237c1d157546a5dcde894fd6c1410162a8eba318748d4ac573ee75e40df16 +0 -0
- data/spec/dummy/tmp/local_secret.txt +1 -0
- data/spec/dummy/tmp/pids/server.pid +1 -0
- data/spec/factories/migration.rb +87 -66
- data/spec/factories/model.rb +54 -20
- data/spec/lib/localtower/generators/migration_spec.rb +28 -63
- data/spec/lib/localtower/generators/model_spec.rb +96 -24
- data/spec/lib/localtower/generators/service_objects/insert_array_spec.rb +47 -0
- data/spec/lib/localtower/generators/service_objects/insert_defaults_spec.rb +30 -35
- data/spec/lib/localtower/generators/service_objects/insert_foreign_keys_spec.rb +101 -0
- data/spec/lib/localtower/generators/service_objects/insert_indexes_spec.rb +90 -0
- data/spec/lib/localtower/generators/service_objects/insert_nullable_spec.rb +61 -0
- data/spec/lib/localtower/tools_spec.rb +1 -11
- data/spec/spec_helper.rb +10 -6
- metadata +130 -237
- data/app/views/localtower/pages/_migrations.html.erb +0 -57
- data/app/views/localtower/pages/models.html.erb +0 -80
- data/app/views/localtower/pages/schema.html.erb +0 -67
- data/public/css/app.css +0 -104
- data/public/js/app.js +0 -192
- data/public/light-bootstrap-dashboard-master/assets/css/animate.min.css +0 -6
- data/public/light-bootstrap-dashboard-master/assets/css/bootstrap.min.css +0 -5
- data/public/light-bootstrap-dashboard-master/assets/css/demo.css +0 -61
- data/public/light-bootstrap-dashboard-master/assets/css/light-bootstrap-dashboard.css +0 -2789
- data/public/light-bootstrap-dashboard-master/assets/css/pe-icon-7-stroke.css +0 -632
- data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.eot +0 -0
- data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.svg +0 -212
- data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.ttf +0 -0
- data/public/light-bootstrap-dashboard-master/assets/fonts/Pe-icon-7-stroke.woff +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/default-avatar.png +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-0.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-1.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-2.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-3.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-4.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-5.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-6.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/face-7.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/faces/tim_vector.jpe +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/favicon.ico +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/loading-bubbles.svg +0 -14
- data/public/light-bootstrap-dashboard-master/assets/img/mask.png +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/new_logo.png +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/sidebar-1.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/sidebar-2.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/sidebar-3.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/sidebar-4.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/sidebar-5.jpg +0 -0
- data/public/light-bootstrap-dashboard-master/assets/img/tim_80x80.png +0 -0
- data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-checkbox-radio-switch.js +0 -502
- data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-notify.js +0 -404
- data/public/light-bootstrap-dashboard-master/assets/js/bootstrap-select.js +0 -438
- data/public/light-bootstrap-dashboard-master/assets/js/bootstrap.min.js +0 -7
- data/public/light-bootstrap-dashboard-master/assets/js/chartist.min.js +0 -9
- data/public/light-bootstrap-dashboard-master/assets/js/demo.js +0 -152
- data/public/light-bootstrap-dashboard-master/assets/js/jquery-1.10.2.js +0 -9789
- data/public/light-bootstrap-dashboard-master/assets/js/light-bootstrap-dashboard.js +0 -179
- data/public/logo-localtower-white-300.png +0 -0
- data/public/logo-localtower-white.png +0 -0
- data/public/logo-localtower.png +0 -0
- data/public/vendor/font-awesome.min.css +0 -4
- data/public/vendor/highlight-js-default.min.css +0 -9
- data/spec/dummy/db/migrate/20221115190039_create_users.rb +0 -13
- data/spec/dummy/db/migrate/20221115193020_change_users.rb +0 -8
- data/spec/dummy/db/migrate/20221115193532_change_users_at1668540931.rb +0 -5
- data/spec/dummy/db/migrate/20221115193605_change_users_at1668540964.rb +0 -5
- data/spec/dummy/db/migrate/20221115193637_change_users_at1668540996.rb +0 -5
- data/spec/dummy/db/migrate/20221115193642_change_users_at1668541001.rb +0 -5
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-Y/-YOiiBKqc2UODHFjctm8xc7xFoZaL7zOjWQj6qQ2wyE.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-d/-dwueM4vmPt8L51S3jeSyg_AjGDcj0GUN6pDpCA1gCg.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0g/0gaJnJQdtd2ACbihXxn8OnjLWlDjnQ_WxfgOpbiLzhg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0r/0rFCsCV9kZnEYtZZ6sfig8329OU31bqjecDFqSVank8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/1J/1J2k_CpnQE3d-PZAQwOVGQALGkta4qVvhdsKjgG0e4Q.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2p/2pYVH2Z_syqh6ok8QYxJNKxXpx1Iwppf6JGElZI0gpw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/3W/3WBmqd-2V6q5N-jvbyp-tlcfn3aHYMwBppbOUm7x4qg.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/4K/4KFPlHkhdDW0riGUmlbaR-kmDz6JUnQvY6fwW8qsdaE.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/6x/6xMeRWmLpNK_flx6-JA3KazvUxSCxyPxHv9Zm3eC26Q.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/7d/7dNqI_dCDJLJmI1oM4xwFp9nRRNOem-4P4OD7PMyz2E.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/8X/8XquhxVcp5A8QquLtxO8NgKTMJch0eqQmzFmRGIZP6I.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ah/AhdfXXtU63kXS4TnsH2Vi1yWgVkIEeV8Z8XA68hrNQc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bt/BtAePnwLSGw82xUGI7wuhWDfuwarOQVS91YqCsweMcs.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bx/BxzoG0KxeNLac4xTNeJv3qfeytbNBw58xj2zD-xdbrE.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/CC/CCD0ROPX0yxHwNpVZmuP8ZNtgQpaVCMXpdzC0Wb5n24.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/DS/DS43oxBg6K5PMWLn2mTy_4EnxI03ehHkxpjV7NCi8yM.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Do/Do83AoOat5W-c1g7piDGy2GMmffsY6JY0Qfuh5PY3GM.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EI/EI0Nxk-VRATWstMuVCVc0_GdYlQ-a0dx6n2g0l3vIik.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EN/ENhJnzJAU2IK-7aHqubj9N8Jo_UTmjG_VEQqyIkolQ8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Fc/FcS6VUHN3Bd4pHGqd5NHA8jA4OLwWrU94s3b4GGxX9c.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/G0/G0kukI-r0q0Vbrg6e_jnYJoYcOX8K__h-mwKbCf4twE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/I1/I1Jw08-mz8xzgrgi6giCzpf1UmzGTSbl4eJEw4DAoJM.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/IV/IVOO1dXBmgjieDk__g57p6aYt0Z3CmfTa32jhegoyko.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/JY/JYPmv5WP4wxdI9EKEEPkK_fVtqeSLfmint_5E8fQLQ8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/MX/MXI3KxaQPZGImSvCNZ_TbQVruWCJ3E0xiVxza1ZCAjM.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/OU/OUoioCqXALK909jXPV3VSyCJIdNC7bsogUfdnRTpc5o.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/PH/PHjtqNLUPAUDiSlu5AbPjlIo20mOGNm0uNjMLhX2NvM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RC/RC9vfALY5K634pTeau0BAhTHl7d5_5yA3tM-QTLiKtI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RG/RG1PrmlixwaUlG8BV0kcm_3F7OQekxsrLYjBdf403-k.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ut/UtoMO6n6FHTpRCGk9VfxlfTI2Ao2GYJ_6kMzx3B9VH8.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/VE/VExnbpDk3LxYdPk3htUrZQXPI8NK_zlKtSFfVXJlxU4.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Wm/WmKTjykiU-Tx_Faf5zduEeEQ-DozAs5omKToM2l1cZM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/X-/X-KjhDPd0nI155N_FaxFSgaOiYo0_ytqlmkBlLM7ayw.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/XX/XXVhj-O91tJ5c8pz7DQlTABOv8TIRVg5haw9VOq9HuI.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/YC/YCiifo5NCMwDChFqYFiV4EaYEx8hy3Efle1PsGbIdak.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ya/YayMISAqD-Y3vBFywwKrXbUovGf5o77HUF5s8mnQgO0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Zl/Zl-NEb0aDLmZ9gN4gdY1OYlbUXD4JhkFY_y23m55zmo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/_h/_hnjPptBeD3GP5B0iJR6pvyVkiMiq-o2TxaYmGf9KJo.cache +0 -3
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/_p/_poEF6QbTPYJiQCFGoXxIXjmvcn6T0I87ElzJGHguk0.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/aa/aaSj2zt8ddc87nZqTpOI9gRCKVnoalXKFBww7t4t3Kg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/bZ/bZHWUkrOLp0WM_Ogo36Qjt4cxDt-rOFgtcj4LNB-BVE.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/cP/cPSNG_663TNT944Rke919luRS6FtpMwVc_7aDph645w.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ce/ceq8fcZGIoqWrCl9vrCRrywEdx42iy9PrGG9CwFSIF4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/cl/cljhP0Jc018nLnG1rpdg-FUf6mlIqrQYvXTNXTNG9Bw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dm/dmod3fTZdoKso2FGM5RTQtb4kTB6vywsiXLWDygYFN4.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dy/dySDGcUTqlKx2MTvOmIEP-WzhyhCfU5xhN9qgxbz3rI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gQ/gQYdmEzbLjTcFCnsfzXzEmeminOchF263snAk3IvXM0.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gh/ghvuMAqccBGljlmEaI3Gt5tH5rEg6hseKYMYfRMkHdY.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gt/gt8QC7k92A4hXA3HlCpQulW73tqd6x63I3uT-YrGMj0.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/hf/hfVg-y7dPSQKbb7V3I7M5w7IpOhDiIB2H31d2tmbZMU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/iF/iFLwyhZIu1Jxm77NUT2qWeTDMmyELW4U85t9rGE_KVg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/kF/kFlIcBBnSyKE00OjpM90pqSn93mLMUv9esz86nrO-Cs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ma/MazNt_5OaYexRuZnccZZ_7AONlxn1a4W3KdWyHyBdws.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/ma/ma3w08gnDTeqwY2-C9BlToxA6-AS8bvXlu-nBiz0UYs.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/n_/n_xYqQYhwEMQknb3jFQnjlxxBE9TzMNHCdJ-bEyZFIw.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/nx/nxTv3sKVUQZADJyM3dPaVmUA78MIsMLD_K279yN_GsI.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/pv/pv6tV3CDkIAmLXdU8EPLlNEkXAKJPufVD4VP30o4fWo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/qP/qPmv5snMrDw830S6hSICDcnIy7kVEWoFKXhGKT38lG4.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/sY/sYvTb1uPWWmnHJNXKuW_xSco-aUb-rN2f0J35zSIzuc.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/su/suQ_jjDxRiIn4VEqFJYKaBWJILaeGKBvoTv49XNX0vo.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/u8/u8IrW5IIQ7espwk2Vpk23zheL9YZA0tnbKq9X7E-WA0.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/wh/whzETExjcZCkn4msasD2aylgfhfpKPZrNxTkY-SOIDg.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/x7/x7PYh8DJvPykcEqpVab2vcY9-GFz-3cqtoMlRAu94Uc.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/y6/y6oxsJD3pAY9ph1_5M-77uiEjTVw8BheLZNygCKPm1g.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/yH/yHZ-a1J23ZCf2n5mEHINMz23Iec2cLGTKauW7k4yGTE.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/z7/z7KfUWYoSaGq8tQ5mbHwyfXyT3Pa4FWKJswHcIdJuds.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/zu/zuExWc5WHxeOUPZUKHl9a9ZRmN50g7jMOD28macn6M0.cache +0 -0
- data/spec/lib/localtower/generators/relation_spec.rb +0 -65
@@ -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;
|
@@ -2,97 +2,94 @@
|
|
2
2
|
<html lang="en">
|
3
3
|
<head>
|
4
4
|
<title>Localtower - <%= yield :title %></title>
|
5
|
-
|
6
5
|
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' name='viewport' />
|
7
6
|
<meta name="viewport" content="width=device-width" />
|
8
7
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
9
8
|
|
10
|
-
<link rel="
|
11
|
-
<link rel="stylesheet" type="text/css" href="/
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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" %>
|
20
35
|
|
21
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>
|
22
45
|
</head>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
<
|
46
|
-
<
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
<div class="content">
|
58
|
-
<div class="container-fluid">
|
59
|
-
<%= yield %>
|
60
|
-
</div>
|
61
|
-
</div>
|
62
|
-
</div>
|
63
|
-
</div>
|
64
|
-
|
65
|
-
<div class="full-message" style="display: none;">
|
66
|
-
|
67
|
-
<div class="text-center">
|
68
|
-
<br>
|
69
|
-
<h3>Magic stuff happening.</h3>
|
70
|
-
<br>
|
71
|
-
<i class="pe-7s-refresh-2 rotate"></i>
|
72
|
-
<br>
|
73
|
-
<br>
|
74
|
-
<br>
|
75
|
-
<p class="full-message-migrate" style="display: none;">
|
76
|
-
If you're seeing an error message on the next page (pending migrations), just run in your terminal:
|
77
|
-
<br>
|
78
|
-
<br>
|
79
|
-
<code>bundle exec rails db:migrate</code>
|
80
|
-
</p>
|
81
|
-
</div>
|
82
|
-
|
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>
|
83
80
|
</div>
|
84
81
|
|
85
82
|
<!-- Core JS Files -->
|
86
|
-
<script src="/
|
87
|
-
<script src="/light-bootstrap-dashboard-master/assets/js/bootstrap.min.js" type="text/javascript"></script>
|
88
|
-
|
89
|
-
<!-- Checkbox, Radio & Switch Plugins -->
|
90
|
-
<script src="/light-bootstrap-dashboard-master/assets/js/bootstrap-checkbox-radio-switch.js"></script>
|
91
|
-
|
92
|
-
<!-- Light Bootstrap Table Core javascript and methods for Demo purpose -->
|
93
|
-
<script src="/light-bootstrap-dashboard-master/assets/js/light-bootstrap-dashboard.js"></script>
|
83
|
+
<script src="/vendor/jquery-3.7.1.min.js"></script>
|
94
84
|
<script src="/vendor/highlight.min.js"></script>
|
95
85
|
<script src="/vendor/masonry.pkgd.min.js"></script>
|
96
|
-
<script src="/
|
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" %>
|
97
94
|
</body>
|
98
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,92 +1,30 @@
|
|
1
1
|
<% content_for :title do %>Migrations<% end %>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<%= form_tag
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
<th> <span data-selector=''>On Model</span></th>
|
16
|
-
<th> <span data-selector=''>Action</span></th>
|
17
|
-
<th> <span data-selector='belongs_to_label'>Belongs To</span></th>
|
18
|
-
<th> <span data-selector='column_label'>Column</span></th>
|
19
|
-
<th> <span data-selector='new_column_name_label'>New Column Name</span></th>
|
20
|
-
<th> <span data-selector='column_type_label'>Type</span></th>
|
21
|
-
<th> <span data-selector='index_label'>Index?</span></th>
|
22
|
-
<th> <span data-selector='nullable_label'>Can be null?</span></th>
|
23
|
-
<th> <span data-selector=''></span></th>
|
24
|
-
</thead>
|
25
|
-
|
26
|
-
<tbody data-selector="tbody">
|
27
|
-
<tr data-selector="tr">
|
28
|
-
<td>
|
29
|
-
<%= select_tag "migrations[migrations][][table_name]", options_for_select(Localtower::Tools.models.collect {|p| [ p, p.table_name ] }), class: "form-control" %>
|
30
|
-
</td>
|
31
|
-
|
32
|
-
<td>
|
33
|
-
<%= select_tag "migrations[migrations][][action]", options_for_select(::Localtower::Generators::Migration::ACTIONS), class: "form-control", "data-selector" => "action" %>
|
34
|
-
</td>
|
35
|
-
|
36
|
-
<td>
|
37
|
-
<%= select_tag "migrations[migrations][][belongs_to]", options_for_select(Localtower::Tools.models.collect {|p| [ p, p.table_name ] }), class: "form-control", "data-selector" => "belongs_to" %>
|
38
|
-
</td>
|
39
|
-
|
40
|
-
<td class="text-center">
|
41
|
-
<input type="text" name="migrations[migrations][][column]" class="form-control" data-selector="column_text">
|
42
|
-
|
43
|
-
<%= select_tag "migrations[migrations][][column_list]", options_for_select(::Localtower::Tools.all_columns), class: "form-control", include_blank: true, "data-selector" => "column_list", style: "display:none;" %>
|
44
|
-
</td>
|
45
|
-
|
46
|
-
<td>
|
47
|
-
<input type="text" name="migrations[migrations][][new_column_name]" class="form-control" data-selector="new_column_name">
|
48
|
-
</td>
|
49
|
-
|
50
|
-
<td>
|
51
|
-
<%= select_tag "migrations[migrations][][column_type]", options_for_select(::Localtower::Generators::Migration::TYPES), class: "form-control", "data-selector" => "column_type" %>
|
52
|
-
</td>
|
53
|
-
|
54
|
-
<td>
|
55
|
-
<input type="checkbox" name="migrations[migrations][][index]" class="form-control" data-selector="index">
|
56
|
-
</td>
|
57
|
-
|
58
|
-
<td>
|
59
|
-
<input type="checkbox" name="migrations[migrations][][nullable]" class="form-control" checked="" data-selector="nullable">
|
60
|
-
</td>
|
61
|
-
|
62
|
-
<td>
|
63
|
-
<div class="pull-right">
|
64
|
-
<button class="btn btn-danger btn-xs pointer" data-selector="remove">Remove</button>
|
65
|
-
</div>
|
66
|
-
</td>
|
67
|
-
</tr>
|
68
|
-
</tbody>
|
69
|
-
</table>
|
70
|
-
|
71
|
-
<div class="row">
|
72
|
-
<div class="col-md-12 text-center">
|
73
|
-
<i class="pe-7s-plus pointer" data-selector="duplicate" style="font-size: 3em;"></i>
|
74
|
-
</div>
|
75
|
-
</div>
|
76
|
-
|
77
|
-
<hr>
|
78
|
-
|
79
|
-
<div class="row">
|
80
|
-
<div class="col-md-12 text-center">
|
81
|
-
<button type="submit" value="true" class="btn btn-success" data-selector="submit">
|
82
|
-
Create the migration
|
83
|
-
</button>
|
84
|
-
</div>
|
85
|
-
</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>
|
86
15
|
<% end %>
|
87
|
-
|
16
|
+
<% 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>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
88
28
|
</div>
|
89
|
-
|
90
|
-
<%= render partial: "migrations", locals: { migrations: @migrations } %>
|
91
29
|
</div>
|
92
30
|
</div>
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<% content_for :title do %>New Migration<% end %>
|
2
|
+
<div>
|
3
|
+
<div>
|
4
|
+
<% if @models.empty? %>
|
5
|
+
<%= render partial: 'alert_no_models' %>
|
6
|
+
<% end %>
|
7
|
+
</div>
|
8
|
+
<% if @models.any? %>
|
9
|
+
<%= form_tag migrations_path, class: "pb-10" do %>
|
10
|
+
<input type="hidden" id="form_attributes" name="migrations">
|
11
|
+
<div class="flex flex-col gap-2 pb-4">
|
12
|
+
<div class="block text-localtower-100">Migration name <span class="text-localtower-400">(optionnal)</span></div>
|
13
|
+
<div class="w-80">
|
14
|
+
<input autocomplete="off" type="text" data-selector="modelName" name="migration_name" class="px-2 py-1.5 rounded bg-localtower-600 border border-localtower-500 inline-block w-full outline-none focus:border-localtower-400 transition-colors text-localtower-100 placeholder:italic placeholder:text-localtower-450 focus:placeholder:text-localtower-600 disabled:cursor-not-allowed" placeholder="Ex: AddFieldsToUser" <%= @migrations.any? ? 'disabled' : '' %>>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<div class="py-4 flex flex-col gap-4">
|
18
|
+
<label class="block text-localtower-100">Actions</label>
|
19
|
+
<div id="react-container-new-migration"></div>
|
20
|
+
</div>
|
21
|
+
<div>
|
22
|
+
<button type="submit" value="true" class="px-3 py-1.5 rounded-md bg-green-800 text-localtower-100 border border-green-700 inline-block outline-none hover:border-green-500 hover:bg-green-700 hover:text-white active:opacity-60 transition-colors text-md">
|
23
|
+
<%= @migrations.any? ? 'Add to Migration' : 'Generate Migration' %>
|
24
|
+
</button>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
27
|
+
<% end %>
|
28
|
+
<% if @migrations.any? %>
|
29
|
+
<div class="py-10 border-t border-localtower-500 flex flex-col gap-4">
|
30
|
+
<h4 class="text-localtower-300">
|
31
|
+
There is a pending migration. All new actions will be added to this one:
|
32
|
+
</h4>
|
33
|
+
<div>
|
34
|
+
<% @migrations.take(1).each do |entry| %>
|
35
|
+
<%= render partial: 'localtower/migration', locals: { entry: entry } %>
|
36
|
+
<% end %>
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
40
|
+
</div>
|