inline_forms 8.1.21 → 8.1.42
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/.forgejo/workflows/ci.yml +63 -0
- data/.forgejo/workflows/full-gate.yml +77 -0
- data/.gitignore +10 -5
- data/.rubocop.yml +31 -0
- data/.rubocop_todo.yml +151 -0
- data/CHANGELOG.md +305 -0
- data/CLAUDE.md +68 -0
- data/Gemfile +18 -2
- data/README.rdoc +23 -6
- data/Rakefile +53 -12
- data/app/assets/fonts/opensans-v44-latin-italic.woff2 +0 -0
- data/app/assets/fonts/opensans-v44-latin-regular.woff2 +0 -0
- data/app/assets/javascripts/inline_forms/inline_forms.js +30 -43
- data/app/assets/stylesheets/inline_forms/_foundation_icons.scss +6 -12
- data/app/assets/stylesheets/inline_forms/_theme.scss +134 -0
- data/app/assets/stylesheets/inline_forms/devise.scss +14 -13
- data/app/assets/stylesheets/inline_forms/foundation_and_overrides.scss +4 -0
- data/app/assets/stylesheets/inline_forms/inline_forms.scss +59 -68
- data/app/assets/stylesheets/inline_forms_fonts.css.erb +39 -0
- data/app/controllers/inline_forms_application_controller.rb +8 -4
- data/app/controllers/inline_forms_controller.rb +88 -14
- data/app/helpers/inline_forms_helper.rb +58 -15
- data/app/models/concerns/inline_forms/soft_deletable.rb +11 -12
- data/app/validators/curacao_id_number_validator.rb +5 -6
- data/app/validators/is_curacao_phone_validator.rb +2 -3
- data/app/validators/is_email_address_validator.rb +3 -3
- data/app/validators/must_be_a_value_validator.rb +6 -6
- data/app/views/inline_forms/_new.html.erb +4 -1
- data/app/views/inline_forms/_pending_migration_row.html.erb +15 -0
- data/app/views/inline_forms/_show.html.erb +5 -2
- data/app/views/inline_forms/field_pending.html.erb +10 -0
- data/app/views/layouts/application.html.erb +6 -3
- data/app/views/layouts/devise.html.erb +1 -0
- data/app/views/layouts/inline_forms.html.erb +7 -4
- data/archived/README.md +2 -0
- data/archived/form_elements/dns_records/README.md +25 -0
- data/archived/form_elements/question_list/README.md +25 -0
- data/inline_forms.gemspec +8 -7
- data/lib/generators/inline_forms_addto/USAGE +31 -0
- data/lib/generators/inline_forms_addto_generator.rb +198 -26
- data/lib/generators/inline_forms_attribute_overrides.rb +3 -2
- data/lib/generators/templates/application_record.rb +1 -1
- data/lib/inline_forms/archived_form_elements.rb +23 -10
- data/lib/inline_forms/attribute_list.rb +191 -0
- data/lib/inline_forms/form_element_from_callee.rb +1 -0
- data/lib/inline_forms/form_element_registry.rb +32 -32
- data/lib/inline_forms/form_elements/color_field_helper.rb +44 -0
- data/lib/inline_forms/form_elements/date_helper.rb +4 -1
- data/lib/inline_forms/form_elements/dropdown_with_other_helper.rb +25 -113
- data/lib/inline_forms/form_elements/month_year_picker_helper.rb +13 -2
- data/lib/inline_forms/form_elements/multi_image_field_helper.rb +18 -6
- data/lib/inline_forms/form_elements/slider_with_values_helper.rb +31 -64
- data/lib/inline_forms/form_elements/time_helper.rb +3 -1
- data/lib/inline_forms/gem_files.rb +27 -0
- data/lib/inline_forms/schema_apply.rb +85 -0
- data/lib/inline_forms/schema_intent.rb +76 -0
- data/lib/inline_forms/schema_label.rb +65 -0
- data/lib/inline_forms/schema_preview.rb +135 -0
- data/lib/inline_forms/tabs.rb +175 -0
- data/lib/inline_forms/turbo_tabs_builder.rb +20 -13
- data/lib/inline_forms/version.rb +2 -1
- data/lib/inline_forms.rb +145 -45
- data/lib/locales/inline_forms.en.yml +2 -0
- data/lib/locales/inline_forms.nl.yml +2 -0
- data/test/archived_form_elements_test.rb +34 -4
- data/test/attribute_list_test.rb +165 -0
- data/test/dummy/app/controllers/application_controller.rb +24 -0
- data/test/dummy/app/controllers/gizmos_controller.rb +4 -0
- data/test/dummy/app/controllers/machines_controller.rb +4 -0
- data/test/dummy/app/controllers/parts_controller.rb +4 -0
- data/test/dummy/app/controllers/widgets_controller.rb +4 -0
- data/test/dummy/app/helpers/application_helper.rb +13 -0
- data/test/dummy/app/models/application_record.rb +26 -0
- data/test/dummy/app/models/gizmo.rb +25 -0
- data/test/dummy/app/models/kind.rb +8 -0
- data/test/dummy/app/models/machine.rb +23 -0
- data/test/dummy/app/models/part.rb +16 -0
- data/test/dummy/app/models/widget.rb +39 -0
- data/test/dummy/app/views/_inline_forms_tabs.html.erb +40 -0
- data/test/dummy/config/application.rb +37 -0
- data/test/dummy/config/database.yml +3 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/initializers/inline_forms.rb +6 -0
- data/test/dummy/config/initializers/paper_trail_yaml_safe_load.rb +28 -0
- data/test/dummy/config/routes.rb +31 -0
- data/test/inline_forms_addto_generator_test.rb +220 -0
- data/test/integration/inline_forms_crud_test.rb +141 -0
- data/test/integration/legacy_elements_test.rb +42 -0
- data/test/integration/native_inputs_test.rb +138 -0
- data/test/integration/open_after_create_test.rb +85 -0
- data/test/integration/pending_migration_gate_test.rb +75 -0
- data/test/integration/schema_batch_pipeline_test.rb +189 -0
- data/test/integration/schema_edit_test.rb +141 -0
- data/test/integration/schema_preview_test.rb +65 -0
- data/test/integration_test_helper.rb +121 -0
- data/test/plain_text_configuration_test.rb +3 -3
- data/test/schema_apply_test.rb +73 -0
- data/test/schema_intent_test.rb +53 -0
- data/test/schema_label_test.rb +61 -0
- data/test/tabs_test.rb +98 -0
- data/test/user_model_config_test.rb +1 -0
- data/vendor/assets/javascripts/trix.min.js +7 -0
- data/vendor/assets/stylesheets/trix.css +470 -0
- metadata +91 -320
- data/app/assets/images/jquery-ui/animated-overlay.gif +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonal-maze_20_6e4f1c_10x10.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonal-maze_40_000000_10x10.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-medium_20_d34d17_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_0_aaaaaa_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_25_c5ddfc_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_40_db4865_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_50_262626_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_50_93c3cd_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_50_ff3853_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-small_75_ccd232_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_15_0b3e6f_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_15_444444_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_20_e69700_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_22_1484e6_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_26_2293f7_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_75_f3d8d8_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_8_333333_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_90_eeeeee_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diagonals-thick_95_ffdc2e_40x40.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_10_4f4221_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_20_372806_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_25_675423_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_25_d5ac5d_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_8_261803_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_diamond_8_443113_10x8.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-medium_30_0b58a2_4x4.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-medium_80_ffff38_4x4.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_20_333333_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_30_a32d00_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_35_35414f_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_40_00498f_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_dots-small_65_a6a6a6_2x2.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_10_eceadf_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_10_f8f7f6_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_15_eceadf_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_15_f7f3de_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_15_ffffff_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_65_654b24_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_fine-grain_68_b83400_60x60.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_303030_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_333333_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_4c4c4c_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_e69700_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_e6b900_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_0_eeeeee_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_15_cd0a0a_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_30_cccccc_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_40_292929_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_994d53_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_999999_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_c0402a_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_eeeeee_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_fafafa_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_fbec88_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_55_ffffff_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_65_ffffff_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_ba9217_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_ddd4b0_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_e4f1fb_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_f5f0e5_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_15_5f391b_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_20_555555_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_25_cb842e_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_35_dddddd_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_0078a3_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_0a0a0a_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_111111_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_40_ffc73d_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_45_0078ae_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_50_3baae3_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_1c1c1c_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_f1fbe5_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_f8da4e_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fbf5d0_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fbf8ee_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_55_fcf0ba_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_60_000000_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_60_eeeeee_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_70_ede4d4_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_79c9ec_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_80_d7ebf9_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_85_dfeffc_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_100_ece8da_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_16_121212_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_20_111111_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_20_1c160d_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_25_453326_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_30_3d3644_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_30_44372c_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_45_817865_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_55_000000_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_60_fece2f_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_70_ffdd57_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_85_9fda58_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_90_fff9e5_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_gloss-wave_95_f6ecd5_500x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f2f5f7_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f4f0ec_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f5f3e5_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f6f6f6_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_f9f9f9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_100_fafaf4_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_15_459e00_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_15_888888_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_20_0972a5_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_30_285c00_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_40_aaaaaa_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_55_555555_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_65_fee4bd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_70_000000_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_75_f5f5b5_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-hard_95_cccccc_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_dcd9de_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_deedf7_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_eae6ea_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_f9f9f9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_100_feeebd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_15_cc0000_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_20_201913_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_20_619226_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_30273a_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_67b021_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_25_ffef8f_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_33_003147_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_33_3a8104_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_35_222222_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_35_adadad_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_44_444444_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_45_5f5964_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_50_4eb305_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_50_aaaaaa_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_60_4ca20b_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_60_dddddd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_100_eeeeee_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_45_cd0a0a_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_55_ffeb80_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-hard_75_999999_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_100_f4f0ec_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_10_201913_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_10_285c00_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_15_121212_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_15_2b2922_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_25_000000_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_30_f58400_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_30_ffffff_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_loop_25_000000_21x21.png +0 -0
- data/app/assets/images/jquery-ui/ui-bg_white-lines_85_f7f7ba_40x100.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_000000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_004276_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_00498f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0073ea_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0078ae_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_056b93_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_070603_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0a82eb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_0b54d5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_1f1f1f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_217bc0_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_222222_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_2694e8_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_2e83ff_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3383bb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3572ac_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3d3d3d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_3d80b3_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_454545_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_469bdd_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_4b8e0b_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_4ca300_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_4eb305_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_5fa5e3_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_666666_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_6da8d5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_70b2e1_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_72a7cf_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_72b42d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_734d99_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_808080_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_847e71_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_888888_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_88a206_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_8DC262_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_8c291d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_8d78a5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_98d2fb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_999999_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_9bcc60_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_9ccdfc_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_9fda58_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_a83300_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_a8a3ae_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_aaaaaa_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_add978_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_b83400_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_b8ec79_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_bbbbbb_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_bd7b00_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_c02669_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_c47a23_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_c98000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cb672b_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cc0000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cccccc_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_cd0a0a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_d19405_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_d8e7f3_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e0fdff_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e1e463_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e3ddc9_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e8e2b5_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_e9cd86_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_eb990f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ebccce_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ed9f26_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ededed_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_eeeeee_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_efec9f_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f08000_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f1fd86_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f29a00_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f2ec64_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f35f07_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f5e175_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f7a50d_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f9bd01_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_f9f2bd_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fadc7a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fbc856_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fbdb93_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fcd113_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_fcdd4a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ff0084_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ff7519_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffcf29_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffe180_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffeb33_256x240.png +0 -0
- data/app/assets/images/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
- data/app/assets/stylesheets/jquery_ui/jquery.ui.accordion.css.scss +0 -39
- data/app/assets/stylesheets/jquery_ui/jquery.ui.all.css.scss +0 -14
- data/app/assets/stylesheets/jquery_ui/jquery.ui.autocomplete.css.scss +0 -17
- data/app/assets/stylesheets/jquery_ui/jquery.ui.base.css.scss +0 -27
- data/app/assets/stylesheets/jquery_ui/jquery.ui.button.css.scss +0 -115
- data/app/assets/stylesheets/jquery_ui/jquery.ui.core.css.scss +0 -92
- data/app/assets/stylesheets/jquery_ui/jquery.ui.datepicker.css.scss +0 -179
- data/app/assets/stylesheets/jquery_ui/jquery.ui.dialog.css.scss +0 -70
- data/app/assets/stylesheets/jquery_ui/jquery.ui.menu.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/jquery.ui.progressbar.css.scss +0 -29
- data/app/assets/stylesheets/jquery_ui/jquery.ui.resizable.css.scss +0 -79
- data/app/assets/stylesheets/jquery_ui/jquery.ui.selectable.css.scss +0 -16
- data/app/assets/stylesheets/jquery_ui/jquery.ui.slider.css.scss +0 -74
- data/app/assets/stylesheets/jquery_ui/jquery.ui.spinner.css.scss +0 -66
- data/app/assets/stylesheets/jquery_ui/jquery.ui.tabs.css.scss +0 -53
- data/app/assets/stylesheets/jquery_ui/jquery.ui.theme.css.scss +0 -408
- data/app/assets/stylesheets/jquery_ui/jquery.ui.tooltip.css.scss +0 -20
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.base.css.scss +0 -78
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.black-tie.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.blitzer.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.cupertino.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.dark-hive.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.dot-luv.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.eggplant.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.excite-bike.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.flick.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.hot-sneaks.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.humanity.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.le-frog.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.mint-choc.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.overcast.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.pepper-grinder.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.redmond.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.smoothness.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.south-street.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.start.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.sunny.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.swanky-purse.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.trontastic.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.ui-darkness.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.ui-lightness.css.scss +0 -80
- data/app/assets/stylesheets/jquery_ui/themes/_jquery.ui.vader.css.scss +0 -80
- /data/{lib → archived/form_elements/dns_records/lib}/inline_forms/form_elements/dns_records_helper.rb +0 -0
- /data/{lib → archived/form_elements/question_list/lib}/inline_forms/form_elements/question_list_helper.rb +0 -0
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,311 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [8.1.42] - 2026-07-22
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`gem build` no longer packages the `stuff/` scratch dir (and its secrets).**
|
|
12
|
+
`InlineFormsGemFiles.gem_files` sweeps untracked files, so it depended on
|
|
13
|
+
`stuff/` being git-ignored. That ignore lived only in the per-machine global
|
|
14
|
+
excludes file, which is absent on the release box — so `stuff/forgejo-token`
|
|
15
|
+
(mode 0600) leaked into the file list and `gem build` died with `Errno::EACCES`.
|
|
16
|
+
`stuff/` is now excluded in `gem_files` itself, independent of any ignore
|
|
17
|
+
config, and re-added to the repo `.gitignore` as a second line of defense.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Schema-change GUI extracted into its own gem** (`inline_forms_schema_edit`,
|
|
22
|
+
same repo, own gemspec; phase 0 of
|
|
23
|
+
`stuff/2026-07-11-schema-gui-gem-and-automated-pipeline-plan.md`).
|
|
24
|
+
`InlineForms::SchemaController`, its views and the `inline_forms_schema`
|
|
25
|
+
layout move out of the engine; the staging services (`SchemaIntent`,
|
|
26
|
+
`SchemaPreview`, `SchemaApply`, `SchemaLabel`) stay. The installer gains a
|
|
27
|
+
`--schema-edit` flag (default off, implied by `--example`) that adds the gem
|
|
28
|
+
to the generated Gemfile and wires the schema routes + "+ field" nav link;
|
|
29
|
+
apps created without it ship no schema-GUI surface at all.
|
|
30
|
+
|
|
31
|
+
## [8.1.41] - 2026-07-11
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **`inline_forms_addto` hardened** (see `stuff/2026-07-11-add-scalar-attribute-to-existing-model.md`). Adding a field to an existing model is now safer:
|
|
36
|
+
- **Smarter row placement.** New `inline_forms_attribute_list` rows land above the trailing metadata block (the first `:info` / `created_at` / `updated_at` row, and a `:header` directly above it) instead of at the very end, so an editable field no longer drops into the read-only info section. New `--before=ATTR` / `--after=ATTR` options place the row explicitly (warn + fall back to the default when the anchor is missing).
|
|
37
|
+
- **Robust model rewriting.** The greedy `]…end` regex is replaced by a bracket-depth scan from `@inline_forms_attribute_list ||= [` to its matching `]`, which survives `].freeze`, trailing comments, methods defined after the list, and nested `[ ]` in choice rows.
|
|
38
|
+
- **Value-bearing elements.** Choice elements (`dropdown_with_values`, `dropdown_with_integers`, `dropdown_with_values_with_stars`, `radio_button`, `check_box`, `scale_with_integers`, `scale_with_values`) now emit a placeholder `{ 1 => 'one', 2 => 'two' }` values hash and a warning instead of a bare 2-element row that raised at show time.
|
|
39
|
+
- **Collision-free migration timestamps.** Migration filenames use `max(now, highest_existing + 1)` so back-to-back runs (or a run right after another generator in the same second) never collide.
|
|
40
|
+
- **"Run db:migrate" reminder** printed after generation, since the attribute_list row is written immediately but its column only exists after migrating.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- Example app now exercises `inline_forms_addto` end to end: the installer adds `Apartment#internal_note` via `rails g inline_forms_addto` + `db:migrate`, and `example_app_apartment_addto_field_test.rb` asserts the column migrated, the row renders on the stock show panel, and an inline update round-trips.
|
|
45
|
+
- Generator unit tests for the above (smart/explicit placement, `].freeze` + trailing-method robustness, value-bearing placeholder, timestamp uniqueness, and applying the generated migration to an in-memory sqlite DB).
|
|
46
|
+
|
|
47
|
+
### Lockstep
|
|
48
|
+
|
|
49
|
+
- validation_hints 8.1.41, inline_forms_installer 8.1.41.
|
|
50
|
+
|
|
51
|
+
## [8.1.40] - 2026-07-10
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- **Example app demonstrates nesting-in-nesting** (Apartment → Photo → Comment): the installer now generates a `Comment` model (`body:text_area photo:belongs_to`, not accessible through top-level HTML, like Photo) and gives Photo `comments:has_many comments:associated`, so opening a photo row inside an apartment's photos panel exposes a second-level comments panel with its own nested new/create/open/close flows. The seed migration puts two comments on each seeded apartment's first photo so the panel is visibly populated out of the box (and removes them in `down`).
|
|
56
|
+
- Example-app test `example_app_photo_comments_test.rb`: comments blocked as a standalone HTML resource, comments panel + new link inside the opened nested photo row, panel lists existing comments, nested new/create with the photo FK, comment row open/close. Also documents that open-after-create does not fire for nested creates (Comment has no `:associated` panel; the nested flow keeps the plain frame response).
|
|
57
|
+
|
|
58
|
+
### Lockstep
|
|
59
|
+
|
|
60
|
+
- validation_hints 8.1.40, inline_forms_installer 8.1.40 (no changes of their own).
|
|
61
|
+
|
|
62
|
+
## [8.1.39] - 2026-07-10
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **"Open after create"** (Option A of `stuff/2026-07-10-nested-creation-options.md`): a successful *top-level* create of a model whose attribute list contains an `:associated` (has_many) panel now responds with Turbo Streams that refresh the list **and** open the freshly created record's row. The user lands directly where the nested panel — which only exists on a persisted record — is usable (e.g. create an Apartment, immediately add Photos), instead of hunting for the new row in the closed list. Nested creates, models without `:associated` panels, failed saves, and clients without a turbo-stream Accept header keep the existing list-frame HTML responses. If the new record sorts onto a different page of the list, the row-open stream finds no target and degrades silently to the old list-refresh behavior. (`InlineFormsController#open_created_row?` / `#render_created_row_open_streams`.)
|
|
67
|
+
- Engine test coverage: new dummy models `Machine`/`Part` (mirroring Apartment/Photo) plus `test/integration/open_after_create_test.rb` (stream response, html fallback, no-associated fallback, nested create unchanged, failed create unchanged). The dummy host app gained the minimal chrome the full `inline_forms` layout needs (current_user stub with `role?`, `application_name` helper, `_inline_forms_tabs` partial, empty `MODEL_TABS`, devise logout route stand-in), so create/new HTML flows are now testable in the fast engine suite at all.
|
|
68
|
+
- Example-app test: `example_app_apartment_top_level_new_test.rb` verifies the turbo-stream create response opens the new Apartment's row with the photos panel and its "new photo" link.
|
|
69
|
+
|
|
70
|
+
### Lockstep
|
|
71
|
+
|
|
72
|
+
- validation_hints 8.1.39, inline_forms_installer 8.1.39 (no changes of their own).
|
|
73
|
+
|
|
74
|
+
## [8.1.38] - 2026-07-07
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- **RuboCop todo shrunk from 590 to 196 offenses (54 → 40 files, all heredoc-bearing).** Every heredoc-free file was safe-autocorrected in reviewed batches (engine tests green after each): validators, gemspecs, Rakefile, dummy-app models, engine core (`lib/inline_forms.rb`, form-element registry, turbo tabs builder), controller/helpers, installer `creator.rb`/`user_model_config.rb`, and the archived-elements list — bracket spacing, hash syntax (`:a => 1` → `a: 1`), string quotes, comment spacing, `%q{}` → `%q()`. One manual fix: the `if/else` alignment in `turbo_tabs_builder.rb` that autocorrect mangled cosmetically (rewritten as an indented assignment).
|
|
79
|
+
- **Heredoc policy, made explicit:** files whose heredocs emit generated-app code (installer core, generators, form-element helpers, generator tests) are deliberately untouched — autocorrect near heredocs risks changing emitted code. `Layout/TrailingWhitespace` now runs with `AllowInHeredoc: true` (heredoc bodies are generated-file content); outside heredocs the tree is whitespace-clean. The remaining todo entries are per-file excludes on exactly those 40 heredoc files.
|
|
80
|
+
- Full example-app gate passed: MyApp generated from the 8.1.38 gems, 157 runs / 960 assertions / 0 failures.
|
|
81
|
+
|
|
82
|
+
### Lockstep
|
|
83
|
+
|
|
84
|
+
- validation_hints 8.1.38, inline_forms_installer 8.1.38 (no changes of their own).
|
|
85
|
+
|
|
86
|
+
## [8.1.37] - 2026-07-06
|
|
87
|
+
|
|
88
|
+
### Lockstep
|
|
89
|
+
|
|
90
|
+
- **validation_hints 8.1.37**: RuboCop todo eliminated — all 22 grandfathered offenses autocorrected (style-only: bracket spacing, magic-comment blank line, one trailing comma), `.rubocop_todo.yml` deleted. inline_forms and inline_forms_installer have no changes of their own. (inline_forms' own 590-offense todo remains; it shrinks incrementally as files get cleaned.)
|
|
91
|
+
|
|
92
|
+
## [8.1.36] - 2026-07-06
|
|
93
|
+
|
|
94
|
+
### Changed
|
|
95
|
+
|
|
96
|
+
- **Generated apps force SSL in production** (`config.assume_ssl = true` + `config.force_ssl = true`). `rails new` only enables these when Kamal is skipped; generated apps deploy through the shipped Capistrano/Unicorn setup behind an SSL-terminating proxy, and the injected Devise mailer config already assumed https. This was the **only finding of the first Brakeman baseline** (full-gate CI run 6 against the generated app: default check set 0 warnings, `--run-all-checks` exactly this one High/ForceSSL). Internal plain-HTTP apps can re-comment the two lines in their own `production.rb`.
|
|
97
|
+
- **full-gate CI: Brakeman's default check set is now enforcing** (baseline is clean); the pedantic `--run-all-checks` pass stays informational.
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
|
|
101
|
+
- Regression test `example_app_production_ssl_test.rb`: the generated `production.rb` must enable `assume_ssl`/`force_ssl` (guards the installer's gsub against Rails template drift).
|
|
102
|
+
|
|
103
|
+
### Lockstep
|
|
104
|
+
|
|
105
|
+
- validation_hints 8.1.36, inline_forms_installer 8.1.36 (no changes of their own).
|
|
106
|
+
|
|
107
|
+
## [8.1.35] - 2026-07-06
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
|
|
111
|
+
- **Example-app photo seeding no longer depends on a maintainer-only local folder.** The installer looked for gallery images in a *gitignored* `pics/` folder (falling back to the hardcoded `/home/code/inline_forms/pics`), which exists only on the maintainer's machine — any gem install elsewhere (first exposed by the Forgejo `full-gate` CI run) silently seeded **zero** photos and failed 12 gallery/pagination/revert tests. Nine CC0 placeholder PNGs (~4 KB each, solid pastel with an "Apt N / Room" label, generated with ImageMagick) now ship inside the installer under `lib/installer_templates/example_app_assets/seed_images/`, so every install gets the same gallery. `INLINE_FORMS_SEED_PICS` still overrides with a custom folder; the old `pics/` convention is retired.
|
|
112
|
+
- **`full-gate` CI workflow: git identity.** The installer's initial `git commit` in the generated app failed in the bare job container (`unable to auto-detect email address`); the workflow now sets a CI git identity first.
|
|
113
|
+
|
|
114
|
+
### Lockstep
|
|
115
|
+
|
|
116
|
+
- validation_hints 8.1.35, inline_forms_installer 8.1.35 (no changes of their own).
|
|
117
|
+
|
|
118
|
+
## [8.1.34] - 2026-07-06
|
|
119
|
+
|
|
120
|
+
### Added
|
|
121
|
+
|
|
122
|
+
- **CI moved to Forgejo Actions** (`.forgejo/workflows/`, plan: `stuff/2026-07-06-forgejo-ci-rubocop-brakeman.md`). `ci.yml` runs the engine suite, RuboCop, and bundler-audit per push on the dev02 runner (shared `papiamentu-ci:ruby-4.0.4-node20` image); `full-gate.yml` (manual + weekly) rebuilds all three gems, generates the example app — whose embedded 150+-test run is the release gate — and runs **Brakeman against the generated app** (report-only until the baseline is triaged). `.github/workflows/` was **deleted**: pushing to GitHub deliberately triggers nothing.
|
|
123
|
+
- **RuboCop** (Rails omakase preset, same recipe as Papiamentu) in the dev bundle, with all 590 pre-existing offenses grandfathered in `.rubocop_todo.yml` (delete entries as files get cleaned; new code is linted). Generated-app territory is excluded (`lib/installer_templates/`, `archived/`, …). `bundle exec rubocop`: 91 files, no offenses.
|
|
124
|
+
|
|
125
|
+
### Lockstep
|
|
126
|
+
|
|
127
|
+
- validation_hints 8.1.34 (same CI + RuboCop treatment: 12 files, 22 offenses grandfathered), inline_forms_installer 8.1.34.
|
|
128
|
+
|
|
129
|
+
## [8.1.33] - 2026-07-06
|
|
130
|
+
|
|
131
|
+
### Changed
|
|
132
|
+
|
|
133
|
+
- **README refresh** (docs only; the README ships inside the gem). Tabs sections now describe the vendored `InlineForms::Tabs` instead of the removed `tabs_on_rails` gem; the example-app model list includes `FormElementShowcase`; new sections document the native inputs (post-jQuery UI) and the per-user theme / custom colors / locale features with the host-app opt-in contract (`#inline_forms_theme`, `#inline_forms_color_overrides`).
|
|
134
|
+
|
|
135
|
+
### Lockstep
|
|
136
|
+
|
|
137
|
+
- validation_hints 8.1.33, inline_forms_installer 8.1.33 (no code changes in any gem).
|
|
138
|
+
|
|
139
|
+
## [8.1.32] - 2026-07-06
|
|
140
|
+
|
|
141
|
+
### Added
|
|
142
|
+
|
|
143
|
+
- **Theming Pattern 2: per-user color overrides** (completes the `stuff/user-preferences-and-theming.md` baseline of Pattern 1 + 2).
|
|
144
|
+
- New engine helper `inline_forms_user_color_overrides_style`, rendered in the layouts' `<head>`: when `current_user` responds to `#inline_forms_color_overrides` (a hash of `--if-color-` suffix => `"#rrggbb"`), it emits one scoped inline `<style>` (`body.theme-<name> { --if-color-primary: …; }`) so user colors win over the preset palette while the main CSS stays fully cached. Keys and values are strictly re-validated before interpolation; no style tag is emitted when there are no overrides.
|
|
145
|
+
- **New Tier 1 form element `:color_field`** — native `<input type="color">` editing a `"#rrggbb"` string column; show renders a color swatch + hex, update normalizes to lowercase and rejects anything that is not a 6-digit hex (stored as `nil`). Registered as `:string` in the generator registry.
|
|
146
|
+
- Installer: generated user models get `primary_color` / `accent_color` columns with format validations, `#inline_forms_color_overrides`, and two `color_field` rows on the user panel.
|
|
147
|
+
- Tests: dummy-harness color_field render/round-trip/junk-rejection; example-app tests for the scoped override style, the no-overrides case, and the user-panel rows.
|
|
148
|
+
|
|
149
|
+
### Lockstep
|
|
150
|
+
|
|
151
|
+
- validation_hints 8.1.32, inline_forms_installer 8.1.32.
|
|
152
|
+
|
|
153
|
+
## [8.1.31] - 2026-07-06
|
|
154
|
+
|
|
155
|
+
### Added
|
|
156
|
+
|
|
157
|
+
- **Per-user locale.** The user model has always carried a `locale` association (`[:locale, :dropdown]` on the user panel), but nothing read it. Generated apps' `ApplicationController` now wraps every request in `I18n.with_locale(current_user.locale.name)` (`around_action :switch_locale`): unknown/blank names fall back to `I18n.default_locale`, and `with_locale` restores afterwards so nothing leaks across requests. The old commented subdomain-based `set_locale` sample was replaced with an `I18n.with_locale`-based variant.
|
|
158
|
+
- Example-app regression tests (`example_app_user_locale_test.rb`): default `<html lang="en">`, `nl` switching, unknown-name fallback.
|
|
159
|
+
|
|
160
|
+
### Changed
|
|
161
|
+
|
|
162
|
+
- **Engine layout `<html lang>` follows `I18n.locale`** (was hardcoded `"en"` in `layouts/inline_forms.html.erb`).
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
|
|
166
|
+
- **`InlineFormsApplicationController` no longer clobbers `I18n.available_locales`.** It hard-assigned `[:en, :nl, :pp]` at class-load time — which in development happens *after* app initializers, silently stomping any `config.i18n.available_locales` the host configured. Hosts that relied on the implicit `[:en, :nl, :pp]` restriction should set it explicitly in `config/application.rb`.
|
|
167
|
+
|
|
168
|
+
### Lockstep
|
|
169
|
+
|
|
170
|
+
- validation_hints 8.1.31, inline_forms_installer 8.1.31.
|
|
171
|
+
|
|
172
|
+
## [8.1.30] - 2026-07-06
|
|
173
|
+
|
|
174
|
+
### Removed
|
|
175
|
+
|
|
176
|
+
- **App-specific form elements `:question_list` and `:dnsrecords` archived.** `question_list` hardcoded a host `Question` model with `subquestions` (survey app); `dnsrecords` called host `a_records` / `djbdns_line` APIs (DNS-admin app) and was never even in the generator registry (its helper methods were named `dnsrecords_*`). Neither had any example-app or test coverage, and neither can render outside its original host schema. Models still declaring the symbols raise `InlineForms::ArchivedFormElementError` at boot with restore instructions; source lives under `archived/form_elements/{question_list,dns_records}/` with per-element READMEs.
|
|
177
|
+
|
|
178
|
+
### Lockstep
|
|
179
|
+
|
|
180
|
+
- validation_hints 8.1.30, inline_forms_installer 8.1.30.
|
|
181
|
+
|
|
182
|
+
## [8.1.29] - 2026-07-06
|
|
183
|
+
|
|
184
|
+
### Added
|
|
185
|
+
|
|
186
|
+
- **Per-user preset themes (Pattern 1 of `stuff/user-preferences-and-theming.md`), built on the 8.1.24 CSS-variable bridge.**
|
|
187
|
+
- Engine `_theme.scss` ships three preset palettes — `theme-dark`, `theme-sepia`, `theme-high-contrast` — as `body.<class>` blocks overriding the `--if-color-*` custom properties (`theme-default` is the `:root` palette). Dark also patches input/textarea/trix backgrounds (Foundation compiles those from the light Sass palette); high-contrast underlines links.
|
|
188
|
+
- Engine layouts emit `<body class="theme-<name>">` via the new `inline_forms_body_theme_class` helper. The host opts in by having `current_user` respond to `#inline_forms_theme` (one of `default|dark|sepia|high-contrast`); anonymous users and non-opted hosts get `theme-default`, and the class name is validated against a safe pattern before interpolation.
|
|
189
|
+
- Installer: generated user models get an integer `theme` column (default 0), an `INLINE_FORMS_THEMES` map, `#inline_forms_theme`, and a `[:theme, :dropdown_with_values, …]` row on the user panel — so picking a theme is ordinary inline editing, stored on the user record (no localStorage; per the design doc's "Rejected" list).
|
|
190
|
+
- Example-app regression tests (`example_app_user_theme_test.rb`): default body class, dark/high-contrast switching, and the theme dropdown frame on the user panel.
|
|
191
|
+
|
|
192
|
+
### Lockstep
|
|
193
|
+
|
|
194
|
+
- validation_hints 8.1.29, inline_forms_installer 8.1.29.
|
|
195
|
+
|
|
196
|
+
## [8.1.28] - 2026-07-06
|
|
197
|
+
|
|
198
|
+
### Added
|
|
199
|
+
|
|
200
|
+
- **`multi_image_field` joins the FormElementShowcase** as `gallery` (deferred item from the original showcase plan): `mount_uploaders :gallery, ImageUploader` with the filename array JSON-serialized into a `text` column, a seeded one-image gallery on "Full demo", a `Gallery (multiple images)` label, and a new `example_app_showcase_gallery_test.rb` (array show render, `gallery[]` multiple file input, empty-state plus link).
|
|
201
|
+
- Dummy-harness render coverage for `simple_file_field` and `pdf_link` (`test/integration/legacy_elements_test.rb`) — first tests these two legacy elements have ever had.
|
|
202
|
+
|
|
203
|
+
### Fixed
|
|
204
|
+
|
|
205
|
+
- **`multi_image_field_show` crashed the moment the column actually held images.** A `mount_uploaders` (plural) reader returns an *array* of uploaders; the old code called `.url` on that array (`NoMethodError`). It now renders every image in the array (using the `palm` thumb version when defined) and still accepts a bare single uploader.
|
|
206
|
+
- **`multi_image_field_edit` lost all but the last chosen file.** The input was named `gallery` (no `[]`), so Rack kept only the final part of a multiple-file submission; it now submits `gallery[]` and the update assigns the full array (ignoring blank submissions instead of clearing).
|
|
207
|
+
- **`attribute_values`' error path raised the wrong error.** `raise t("fatal.no_values_defined_in", @Klass, attribute)` passed positional args to Rails' `translate` (key + kwargs API) and died with `ArgumentError (given 3, expected 1)` instead of the intended message. Now raises a plain descriptive RuntimeError naming the model and attribute.
|
|
208
|
+
|
|
209
|
+
### Lockstep
|
|
210
|
+
|
|
211
|
+
- validation_hints 8.1.28, inline_forms_installer 8.1.28.
|
|
212
|
+
|
|
213
|
+
## [8.1.27] - 2026-07-06
|
|
214
|
+
|
|
215
|
+
### Added
|
|
216
|
+
|
|
217
|
+
- **In-repo integration test harness (`test/dummy` + `test/integration/`).** A minimal host app (in-memory SQLite, will_paginate + paper_trail + turbo-rails from the dev bundle, no Devise/CanCanCan/Sprockets/ActionText) boots the engine so `InlineFormsController`, the Turbo-frame views, and the form-element helpers can be exercised in ~1.5 s via `bundle exec rake test` — previously every such regression needed the full release gate (build gems → `inline_forms create MyApp --example` → app test suite, minutes). 19 new tests cover list/search/show/edit/update, the 8.1.19 failed-save behavior, destroy + undo, 8.1.13 destroy-version targeting, 8.1.17 revert idempotency, the versions panel, and every 8.1.25/8.1.26 native input. The example-app gate remains the release check.
|
|
218
|
+
- **GitHub Actions workflow** (`.github/workflows/ci.yml`): engine tests + `bundler-audit` (checks out the `validation_hints` sibling for the path dependency).
|
|
219
|
+
|
|
220
|
+
### Fixed
|
|
221
|
+
|
|
222
|
+
Latent engine bugs on hosts without the full Devise+CanCanCan stack, found by the new harness (generated apps always bundle that stack, so they never hit these):
|
|
223
|
+
|
|
224
|
+
- `_show.html.erb` called `can?(:list_versions, …)` and `link_to_versions_list` called `can?` without the `cancan_disabled?` guard every other call site uses — `NoMethodError` when CanCanCan is absent.
|
|
225
|
+
- `destroy` and `revert` called `current_user.role?(:superadmin)` unguarded — `NoMethodError` on `nil.role?` for hosts without Devise/roles (or a signed-out replay). Both now use `destroy_permitted?`: superadmin-only when the host's user responds to `role?` (generated-app behavior unchanged), no extra gate otherwise (CanCan's `load_and_authorize_resource` still applies where enabled).
|
|
226
|
+
- `slider_with_values` show/edit crashed with `NoMethodError` on `nil[1]` when the stored value has no entry in the values hash (e.g. `1..5` scale with the column still `nil`/`0` — exactly the state a fresh row is in); it now falls back to the bare number.
|
|
227
|
+
- The engine's asset-precompile initializer assumed a Sprockets-style `config.assets`; it now skips hosts without one.
|
|
228
|
+
|
|
229
|
+
### Lockstep
|
|
230
|
+
|
|
231
|
+
- validation_hints 8.1.27, inline_forms_installer 8.1.27.
|
|
232
|
+
|
|
233
|
+
## [8.1.26] - 2026-07-06
|
|
234
|
+
|
|
235
|
+
### Changed
|
|
236
|
+
|
|
237
|
+
- **jQuery UI is fully removed** (follow-up to 8.1.25's native pickers; jQuery itself remains only because Foundation 6's JS requires it):
|
|
238
|
+
- **`dropdown_with_other`** now renders a native combobox — a text input backed by a `<datalist>` of the existing records — instead of a hidden `<select>` plus the jQuery UI autocomplete "custom.combobox" widget and its ~100-line inline `<script>` (the last inline script emitted by any form element). Typing a listed name picks that record; any other text becomes the free-form `<attribute>_other` value. The submitted field is unchanged (`_<model>[<attribute>_other]`) and `dropdown_with_other_update` is behaviorally identical (it never read the posted foreign key; it re-derives it by name lookup). Two stray `puts` debug lines removed from the update path.
|
|
239
|
+
- **`slider_with_values`** now renders a native `<input type="range">` on edit (labels ride in `data-slider-values`; an `<output>` shows the current label, kept in sync by `initSliderValueLabels` in `inline_forms.js`) and a non-interactive `<progress>` bar on show (a disabled range input would swallow the click-to-edit). No more jQuery UI slider or per-field scripts; the old hardcoded `max: 5` on edit now derives from the values hash.
|
|
240
|
+
- **Removed from the engine:** `//= require jquery.ui.all`, `//= require autocomplete-rails`, the vendored jQuery UI SCSS (`app/assets/stylesheets/jquery_ui/`, sunny theme) and theme images (`app/assets/images/jquery-ui/`, ~70 files), the `inline_forms.jquery_ui_stylesheet_path` initializer, and the dead `.custom-combobox` CSS.
|
|
241
|
+
- **Removed from generated Gemfiles:** `jquery-ui-rails`, `rails-jquery-autocomplete`.
|
|
242
|
+
|
|
243
|
+
### Lockstep
|
|
244
|
+
|
|
245
|
+
- validation_hints 8.1.26, inline_forms_installer 8.1.26.
|
|
246
|
+
|
|
247
|
+
## [8.1.25] - 2026-07-06
|
|
248
|
+
|
|
249
|
+
### Changed
|
|
250
|
+
|
|
251
|
+
- **Date/time/month pickers are native HTML inputs; jQuery UI datepicker and the jquery.timepicker plugin are gone.**
|
|
252
|
+
- `date_select` edit renders `<input type="date">` (was `text_field_tag class="datepicker"` + jQuery UI datepicker). The browser shows a locale-formatted picker with month/year dropdowns built in; the wire format is ISO 8601 (`YYYY-MM-DD`), which Active Record casts directly — sturdier than the old `dd-mm-yy` text parsing.
|
|
253
|
+
- `time_select` edit renders `<input type="time">` (was `class="timepicker"` + jquery.timepicker); submits 24h `HH:MM`. Value now pre-fills as `09:15` instead of `" 9:15am"`; the show format (`%l:%M%P`) is unchanged.
|
|
254
|
+
- `month_year_picker` edit renders `<input type="month">` (was the jQuery UI `MM yy` datepicker hack with the onClose month/year scrape); submits `YYYY-MM`. `month_year_picker_update` parses `YYYY-MM` via `Date.strptime` (Ruby's `Date.parse` raises on it) and still accepts the legacy `"September 2026"` display format as a fallback.
|
|
255
|
+
- Edit-input CSS classes renamed to match the form element names (`date_select`, `time_select`, `month_year_picker`); the old `datepicker`/`timepicker`/`datepicker-month-year` hooks are gone so host-app JS that still binds jQuery pickers to them will not double-bind against the native inputs.
|
|
256
|
+
- `initInlineFormsWidgets` now wires only validation-hint tooltips; `$.datepicker.setDefaults` and all picker init removed from `inline_forms.js`. `jquery.ui.all` stays in the bundle solely for the autocomplete widget (`dropdown_with_other`) and `slider_with_values`.
|
|
257
|
+
- Installer: **`jquery-timepicker-rails` removed** from generated Gemfiles.
|
|
258
|
+
|
|
259
|
+
### Added
|
|
260
|
+
|
|
261
|
+
- Example-app regression tests: native `type="date"`/`type="time"`/`type="month"` edits with ISO value prefill, plus round-trips for a native `HH:MM` time submission, a native `YYYY-MM` month submission, the legacy `"November 2027"` month fallback, and an ISO date submission.
|
|
262
|
+
|
|
263
|
+
### Lockstep
|
|
264
|
+
|
|
265
|
+
- validation_hints 8.1.25, inline_forms_installer 8.1.25.
|
|
266
|
+
|
|
267
|
+
## [8.1.24] - 2026-07-06
|
|
268
|
+
|
|
269
|
+
### Added
|
|
270
|
+
|
|
271
|
+
- **Theme bridge: the admin-chrome palette is now exposed as CSS custom properties** (new `_theme.scss`, emitted into both `inline_forms.css` and `devise.css`). Every hardcoded chrome color in `inline_forms.scss` / `devise.scss` (dark-red `#A3381E`, brick `#B94C32`, gold `#E1C150`, header band `rgb(239,202,75)`, zebra rows `#FBE38E`/`#FBEEC1`, input backgrounds, flash/error/success colors) moved to `var(--if-color-*)` with identical build-time values — the rendered UI is unchanged until a host app overrides a variable (e.g. `:root { --if-color-primary: #2563eb; }` or a `body.theme-dark` block). This is the prerequisite bridging layer for per-user theming (`stuff/user-preferences-and-theming.md`); Foundation's own components still compile from Sass settings.
|
|
272
|
+
- Body background/text and anchor color are bridged too (`--if-color-body-bg`, `--if-color-body-text`, `--if-color-anchor`), sourced from Foundation's `$body-background` / `$body-font-color` / `$anchor-color` at build time.
|
|
273
|
+
|
|
274
|
+
### Changed
|
|
275
|
+
|
|
276
|
+
- **Sass module-system status made explicit.** `foundation_icons` now loads via `@use`; `lighten()` calls replaced with `color.adjust` (kills the Dart Sass color-functions deprecation). The remaining `@import`s cannot convert while the stack sits on foundation-rails 6.9, whose Sass is `@import`-only and feeds globals (`$body-background`, `rem-calc`, …) into our overrides — documented in `inline_forms.scss` and `stuff/improvement-plan.md` §1. Remaining deprecation warnings (import/global-builtin/if-function) originate inside foundation-rails itself.
|
|
277
|
+
|
|
278
|
+
### Lockstep
|
|
279
|
+
|
|
280
|
+
- validation_hints 8.1.24, inline_forms_installer 8.1.24 (no changes of their own).
|
|
281
|
+
|
|
282
|
+
## [8.1.23] - 2026-07-06
|
|
283
|
+
|
|
284
|
+
### Changed
|
|
285
|
+
|
|
286
|
+
- **`tabs_on_rails` is no longer a dependency; tabs support is vendored.** The gem (last released 2017, unmaintained) provided four things inline_forms used: the controller `set_tab` DSL, the `current_tab` / `current_tab?` helpers, the `tabs_tag` view helper, and the `TabsBuilder` base class that `InlineForms::TurboTabsBuilder` subclasses. All four are now ported into the engine as `InlineForms::Tabs` (`lib/inline_forms/tabs.rb`, API-compatible; MIT attribution retained) and included into `ActionController::Base` by an engine initializer. It was also an *undeclared* dependency: the engine `require`d `tabs_on_rails` at load time but never listed it in the gemspec — only the installer-written app Gemfile made that work. The installer no longer writes `gem 'tabs_on_rails'`; apps generated before 8.1.23 keep working because the initializer skips the vendored controller include when the gem's own `TabsOnRails::ActionController` is present.
|
|
287
|
+
|
|
288
|
+
### Added
|
|
289
|
+
|
|
290
|
+
- **Unit tests** (`test/tabs_test.rb`) for the vendored default builder (active `current` class, `<span>` for the active tab), custom `active_class`, the `TurboTabsBuilder` contract (threads `link_options:`/`data-turbo-frame` onto the anchor, `aria-current`/`aria-selected` state, href-less active tab), and the `set_tab`/`current_tab?` namespace semantics.
|
|
291
|
+
|
|
292
|
+
### Lockstep
|
|
293
|
+
|
|
294
|
+
- validation_hints 8.1.23, inline_forms_installer 8.1.23.
|
|
295
|
+
|
|
296
|
+
## [8.1.22] - 2026-07-06
|
|
297
|
+
|
|
298
|
+
### Changed
|
|
299
|
+
|
|
300
|
+
- **Trix is vendored; unpkg CDN tags removed.** All layouts loaded Trix from `https://unpkg.com/trix@1.3.1/dist/trix.{css,js}` — a 2020-era version and a hard runtime dependency on a third-party CDN. Trix **2.1.19** now ships in the engine (`vendor/assets/javascripts/trix.min.js`, `vendor/assets/stylesheets/trix.css`) and is served through Sprockets (`javascript_include_tag "trix.min"` / `stylesheet_link_tag "trix"`). The Trix 1-era manual re-init in `initInlineFormsWidgets` (`new Trix.Editor(el)`) was dropped: Trix 2's `<trix-editor>` is a custom element the browser upgrades automatically after Turbo frame swaps.
|
|
301
|
+
- **Open Sans is self-hosted; no more `http://fonts.googleapis.com`.** `inline_forms.scss` and `devise.scss` imported Open Sans over plain HTTP at runtime. The latin 400/400-italic woff2 files (v44) now live in `app/assets/fonts/`, declared in a new Sprockets-served `inline_forms_fonts.css.erb` (ERB so `asset_path` emits digested URLs) linked from all three layouts.
|
|
302
|
+
- **Installer Gemfile: last floating gems pinned** — `cancancan '~> 3.6'`, `will_paginate '~> 4.0'` (the versions generated apps already resolve).
|
|
303
|
+
|
|
304
|
+
### Fixed
|
|
305
|
+
|
|
306
|
+
- **Foundation Icons `@font-face` 404.** The `@font-face` lived in the Dart Sass-built `inline_forms.css`, which is served from `/assets/inline_forms/…`; its relative `url("foundation-icons.woff")` therefore resolved to `/assets/inline_forms/foundation-icons.woff` — a 404 (the fonts' logical paths are flat: `/assets/foundation-icons.woff`). Icon glyphs (`fi-*`) silently fell back to the text font. The declaration moved into `inline_forms_fonts.css.erb` with proper `asset_path` URLs; the fonts (and Open Sans) are added to the precompile list.
|
|
307
|
+
|
|
308
|
+
### Lockstep
|
|
309
|
+
|
|
310
|
+
- validation_hints 8.1.22, inline_forms_installer 8.1.22 (no changes of their own).
|
|
311
|
+
|
|
7
312
|
## [8.1.21] - 2026-06-03
|
|
8
313
|
|
|
9
314
|
### Removed
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# CLAUDE.md — inline_forms
|
|
2
|
+
|
|
3
|
+
Instructions for any work in the inline_forms repo (`/home/code/inline_forms`).
|
|
4
|
+
These apply to all work here and take precedence over global defaults where they
|
|
5
|
+
conflict. Consolidated from the former `stuff/prompt/workflow.md` and
|
|
6
|
+
`stuff/prompt/test-the-example-app.md`.
|
|
7
|
+
|
|
8
|
+
## Workflow after any significant change
|
|
9
|
+
|
|
10
|
+
1. Run the full example-app test (see **Testing the example app** below). Keep
|
|
11
|
+
improving until all tests succeed.
|
|
12
|
+
2. Bump the **patch** version. Stay in the **8.1** line until further notice.
|
|
13
|
+
Never bump the minor version — even for big or breaking changes.
|
|
14
|
+
- Change the version in **all four gems** so they stay in lockstep, always,
|
|
15
|
+
even if nothing changed in some of them:
|
|
16
|
+
`validation_hints`, `inline_forms`, `inline_forms_installer`, and
|
|
17
|
+
`inline_forms_schema_edit` (in this repo under `inline_forms_schema_edit/`).
|
|
18
|
+
3. Update the Changelog of all four gems.
|
|
19
|
+
4. Commit everything.
|
|
20
|
+
5. After committing, push to the `forgejo` remote
|
|
21
|
+
(`ssh://forgejo@dev02:2222/ace/...`) in **both repos** (inline_forms and
|
|
22
|
+
validation_hints) so every commit runs through CI (Forgejo Actions on dev02).
|
|
23
|
+
- Check the run at http://dev02:3300/ace/inline_forms/actions and fix
|
|
24
|
+
failures.
|
|
25
|
+
6. Never push to `origin` (GitHub). Only Ace pushes there, and GitHub must not
|
|
26
|
+
run anything (no `.github/workflows`).
|
|
27
|
+
|
|
28
|
+
## Testing the example app
|
|
29
|
+
|
|
30
|
+
Goal: build the current gem, install it into `/home/code/testInline`, recreate
|
|
31
|
+
`MyApp` from scratch using `--example`, and verify it with Rails tests.
|
|
32
|
+
|
|
33
|
+
Do all steps end-to-end without asking for confirmation unless a command fails.
|
|
34
|
+
|
|
35
|
+
### Steps
|
|
36
|
+
|
|
37
|
+
1. In `/home/code/inline_forms`:
|
|
38
|
+
- Ensure the latest code is used.
|
|
39
|
+
- Run: `rvm use .`
|
|
40
|
+
- Build gems:
|
|
41
|
+
`gem build inline_forms.gemspec && gem build inline_forms_installer.gemspec && (cd inline_forms_schema_edit && gem build inline_forms_schema_edit.gemspec)`
|
|
42
|
+
- Confirm the built file names/versions
|
|
43
|
+
(`inline_forms-<version>.gem`, `inline_forms_installer-<version>.gem`,
|
|
44
|
+
`inline_forms_schema_edit/inline_forms_schema_edit-<version>.gem`).
|
|
45
|
+
|
|
46
|
+
2. In `/home/code/testInline`:
|
|
47
|
+
- Remove the old app if present: `/home/code/testInline/MyApp`
|
|
48
|
+
- Run: `rvm use .`
|
|
49
|
+
- Install the freshly built gems from
|
|
50
|
+
`/home/code/inline_forms/inline_forms-<version>.gem`,
|
|
51
|
+
`inline_forms_installer-<version>.gem`, and
|
|
52
|
+
`inline_forms_schema_edit/inline_forms_schema_edit-<version>.gem`.
|
|
53
|
+
|
|
54
|
+
3. Still in `/home/code/testInline`:
|
|
55
|
+
- Generate a fresh example app:
|
|
56
|
+
`inline_forms create MyApp -d sqlite --example`
|
|
57
|
+
|
|
58
|
+
4. In `/home/code/testInline/MyApp`:
|
|
59
|
+
- Run: `rvm use .`
|
|
60
|
+
- Run verification: `rails test`
|
|
61
|
+
|
|
62
|
+
### Output requirements
|
|
63
|
+
|
|
64
|
+
- Briefly report each phase result (build, install, app generation, test run).
|
|
65
|
+
- Include the exact commands run.
|
|
66
|
+
- Include the test summary (runs/assertions/failures/errors/skips).
|
|
67
|
+
- If anything fails, stop at the failing step and include the exact error and
|
|
68
|
+
the next corrective command you recommend.
|
data/Gemfile
CHANGED
|
@@ -5,5 +5,21 @@ gemspec name: "inline_forms"
|
|
|
5
5
|
# Local sibling until validation_hints 8.0.0 is on RubyGems (maintainer dev only).
|
|
6
6
|
gem "validation_hints", path: "../validation_hints"
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
8
|
+
# test/dummy host-app stand-ins: the engine expects the host to supply these
|
|
9
|
+
# (generated apps get them from the installer Gemfile). Used only by the
|
|
10
|
+
# integration tests under test/integration/.
|
|
11
|
+
group :test do
|
|
12
|
+
gem "sqlite3", ">= 2.1"
|
|
13
|
+
gem "will_paginate", "~> 4.0"
|
|
14
|
+
gem "paper_trail", "~> 17.0"
|
|
15
|
+
gem "turbo-rails"
|
|
16
|
+
# The schema-GUI engine gem (same repo, own gemspec). Test group so the
|
|
17
|
+
# dummy app's `Bundler.require(*Rails.groups)` loads it and the engine's
|
|
18
|
+
# schema_edit integration tests exercise the extracted controller/views.
|
|
19
|
+
gem "inline_forms_schema_edit", path: "inline_forms_schema_edit"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
group :development, :test do
|
|
23
|
+
# Rails omakase style; offenses grandfathered in .rubocop_todo.yml.
|
|
24
|
+
gem "rubocop-rails-omakase", require: false
|
|
25
|
+
end
|
data/README.rdoc
CHANGED
|
@@ -46,17 +46,18 @@ The installer emits +devise_for :users, class_name: "Member", path: "members"+ (
|
|
|
46
46
|
|
|
47
47
|
Then point your browser to http://localhost:3000/apartments and log in with admin@example.com / admin999. The example also adds integration and model tests; run +bundle exec rails test+ in +MyApp+, then start the server with +bundle exec rails s+ when you want the UI.
|
|
48
48
|
|
|
49
|
-
The example app
|
|
49
|
+
The example app ships four demo models (plus the +User+ / +Role+ / +Locale+ auth trio):
|
|
50
50
|
|
|
51
51
|
* +Apartment+ — top-level resource at +/apartments+ (root).
|
|
52
52
|
* +Photo+ — nested under Apartment (+has_many+ / +belongs_to+).
|
|
53
53
|
* +Owner+ — top-level resource at +/owners+. An Owner +has_many+ Apartments; an Apartment +belongs_to+ a single (optional) Owner. The Owner detail panel at +/owners/:id+ ships two sub-tabs, +NAW+ (name, birthdate, address, city, country) and +Apartments+ (name + the owned-apartments checklist). +name+ deliberately appears on both tabs.
|
|
54
|
+
* +FormElementShowcase+ — one row per kept Tier 1 form element (numbers, dates, choices, scales, uploads incl. a +multi_image_field+ gallery, rich text, HABTM checklist), seeded as "Full demo" / "Empty demo" so every show/edit branch renders and is regression-tested.
|
|
54
55
|
|
|
55
56
|
On the +Apartments+ tab, +Owner#apartments+ is rendered as a +:check_list+ of *existing* apartments rather than the default +:associated+ "build new nested row" panel, so the user re-assigns the +apartments.owner_id+ FK by ticking checkboxes (using Rails' built-in +apartment_ids=+ setter on +has_many+).
|
|
56
57
|
|
|
57
|
-
The tabs are wired with +
|
|
58
|
+
The tabs are wired with +InlineForms::Tabs+ (+set_tab+ / +current_tab?+ / +tabs_tag+ — vendored into the engine since 8.1.23, replacing the unmaintained +tabs_on_rails+ gem with the same API) and +InlineForms::TurboTabsBuilder+, a small subclass of +InlineForms::Tabs::TabsBuilder+ that threads HTML options through to the tab's +<a>+ (the classic builder can only annotate the +<li>+). Each tab link carries +data-turbo-frame+ targeting the surrounding row +<turbo-frame>+, so switching tabs is a single Turbo partial swap — no UJS, no +data-remote+. The active tab is emitted as an hrefless +<a aria-current="page" aria-selected="true">+ inside +<li class="tabs-title is-active">+ so Foundation 6's tabs CSS (+.tabs-title.is-active > a+ / +[aria-selected='true']+) styles it without needing custom overrides.
|
|
58
59
|
|
|
59
|
-
The example app also seeds three apartments (+Apt 1+, +Apt 2+, +Apt 3+, each with three CC0 placeholder photos
|
|
60
|
+
The example app also seeds three apartments (+Apt 1+, +Apt 2+, +Apt 3+, each with three CC0 placeholder photos shipped with the installer — labeled pastel PNGs like "Apt 1 / Living Room"; override with your own folder via +INLINE_FORMS_SEED_PICS+) and three owners — +Maria Martinez+ (owns +Apt 1+ + +Apt 2+), +Jean-Pierre Dupont+ (owns +Apt 3+), and +Akira Tanaka+ (owns none) — so the +has_many+ panel has at least one zero / one / many case to click through.
|
|
60
61
|
|
|
61
62
|
You can install the example application manually if you like:
|
|
62
63
|
|
|
@@ -78,9 +79,9 @@ Then point your browser to http://localhost:3000/apartments and log in with admi
|
|
|
78
79
|
|
|
79
80
|
== Per-resource Turbo tabs (+InlineForms::TurboTabsBuilder+)
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
The classic builder API (+tab_for(tab, name, url_options, item_options = {})+, inherited from the retired +tabs_on_rails+ gem and preserved verbatim in the vendored +InlineForms::Tabs::TabsBuilder+) only applies the 4th argument to the +<li>+ wrapper; nothing is forwarded to the +<a>+. That used to be fine under Rails UJS (every link with +data-remote="true"+ was hijacked into an XHR regardless), but Turbo needs the data attribute on the +<a>+ itself (typically +data-turbo-frame="..."+).
|
|
82
83
|
|
|
83
|
-
The old +acesuares/tabs_on_rails+ fork (+update_remote_before_action+) patched +tab_for+ to thread html options into +link_to+. That fork was retired in 7.13.5; +InlineForms::TurboTabsBuilder+ is its Turbo-shaped replacement. It accepts a new +:link_options+ key on the per-tab call and forwards it to +link_to+:
|
|
84
|
+
The old +acesuares/tabs_on_rails+ fork (+update_remote_before_action+) patched +tab_for+ to thread html options into +link_to+. That fork was retired in 7.13.5 (and the gem itself was vendored away in 8.1.23); +InlineForms::TurboTabsBuilder+ is its Turbo-shaped replacement. It accepts a new +:link_options+ key on the per-tab call and forwards it to +link_to+:
|
|
84
85
|
|
|
85
86
|
<%= tabs_tag builder: InlineForms::TurboTabsBuilder,
|
|
86
87
|
active_class: "is-active",
|
|
@@ -101,7 +102,7 @@ Active-tab highlighting is unchanged from upstream (still driven by +set_tab :fo
|
|
|
101
102
|
|
|
102
103
|
=== Where to put the +tabs_tag+ block (four patterns)
|
|
103
104
|
|
|
104
|
-
+
|
|
105
|
+
+InlineForms::Tabs+ and +InlineForms::TurboTabsBuilder+ don't care where you call +tabs_tag+ — they just produce the +<ul class="tabs">+ wherever you put the block. The example app's split into +show_with_tabs.html.erb+ + +_owner_tabs.html.erb+ is a stylistic choice; below are the four common shapes, from most-inline to most-decoupled. Pick whichever fits your app:
|
|
105
106
|
|
|
106
107
|
1. *Inlined in the show view* — drop the +tabs_tag+ block straight into +app/views/<resource>/show_with_tabs.html.erb+ (or similar) and skip the partial entirely.
|
|
107
108
|
|
|
@@ -282,6 +283,22 @@ For long text fields, use +:plain_text+ for a plain textarea backed by a DB +tex
|
|
|
282
283
|
|
|
283
284
|
Note: generated apps also depend on ActiveStorage transitively because the +:rich_text+ form element uses ActionText (+active_storage:install+ runs during +inline_forms create+). Image uploads still go through CarrierWave; ActiveStorage is only there to back ActionText embeds.
|
|
284
285
|
|
|
286
|
+
== Native inputs (no jQuery UI)
|
|
287
|
+
|
|
288
|
+
Since 8.1.25/8.1.26 the date/time widgets are native HTML inputs — +:date_select+ renders +<input type="date">+, +:time_select+ +<input type="time">+, +:month_year_picker+ +<input type="month">+, +:slider_with_values+ +<input type="range">+, +:dropdown_with_other+ an +<input list>+ + +<datalist>+ combobox, and the new +:color_field+ (8.1.32) +<input type="color">+. jQuery UI, its themes and the +jquery-ui-rails+ / +rails-jquery-autocomplete+ / +jquery-timepicker-rails+ gems are gone; jQuery itself remains only because Foundation 6's JS requires it.
|
|
289
|
+
|
|
290
|
+
== Per-user themes, colors and locale
|
|
291
|
+
|
|
292
|
+
Generated apps let each user pick, on their own user panel:
|
|
293
|
+
|
|
294
|
+
* a *preset theme* (+default+ / +dark+ / +sepia+ / +high-contrast+): an integer +theme+ column mapped to a +theme-<name>+ body class; palettes are CSS custom properties (+--if-color-*+) in the engine's +_theme.scss+ (8.1.29);
|
|
295
|
+
* *custom colors* (+primary_color+ / +accent_color+, edited with +:color_field+): rendered as one scoped inline +<style>+ of +--if-color-*+ overrides, so the main stylesheet stays fully cacheable (8.1.32);
|
|
296
|
+
* a *locale*: the existing +locale+ association now drives +I18n.with_locale+ per request via +around_action :switch_locale+ (8.1.31).
|
|
297
|
+
|
|
298
|
+
Host apps that are not generated by the installer opt in by making +current_user+ respond to +inline_forms_theme+ (String) and/or +inline_forms_color_overrides+ (Hash of +--if-color-+ suffix => +"#rrggbb"+). Everything is validated before interpolation. To re-theme an app globally instead, override the variables in your own CSS:
|
|
299
|
+
|
|
300
|
+
:root { --if-color-primary: #2563eb; }
|
|
301
|
+
|
|
285
302
|
= Build a vagrant virtualbox box for easier development
|
|
286
303
|
|
|
287
304
|
Go ahead and unzip lib/vagrant/vagrantbox-inline_forms.zip. Enter the created directory with
|
data/Rakefile
CHANGED
|
@@ -7,11 +7,18 @@ namespace :installer do
|
|
|
7
7
|
Bundler::GemHelper.install_tasks name: "inline_forms_installer"
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
namespace :schema_edit do
|
|
11
|
+
# The schema-GUI gem lives in its own subdirectory (own gemspec, own pkg/).
|
|
12
|
+
Bundler::GemHelper.install_tasks dir: File.expand_path("inline_forms_schema_edit", __dir__),
|
|
13
|
+
name: "inline_forms_schema_edit"
|
|
14
|
+
end
|
|
15
|
+
|
|
10
16
|
def inline_forms_pkg_gems
|
|
11
|
-
pkg = File.expand_path("pkg", __dir__)
|
|
12
17
|
version = InlineForms::VERSION
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
{ "inline_forms" => "pkg",
|
|
19
|
+
"inline_forms_installer" => "pkg",
|
|
20
|
+
"inline_forms_schema_edit" => "inline_forms_schema_edit/pkg" }.map do |name, pkg|
|
|
21
|
+
path = File.expand_path(File.join(pkg, "#{name}-#{version}.gem"), __dir__)
|
|
15
22
|
raise "Missing #{path}. Run rake build:all first." unless File.file?(path)
|
|
16
23
|
path
|
|
17
24
|
end
|
|
@@ -25,11 +32,11 @@ def validation_hints_pkg_gem
|
|
|
25
32
|
].find { |path| File.file?(path) }
|
|
26
33
|
end
|
|
27
34
|
|
|
28
|
-
desc "Build
|
|
29
|
-
task "build:all" => ["build", "installer:build"]
|
|
35
|
+
desc "Build inline_forms, inline_forms_installer and inline_forms_schema_edit"
|
|
36
|
+
task "build:all" => [ "build", "installer:build", "schema_edit:build" ]
|
|
30
37
|
|
|
31
38
|
desc "Install freshly built gems from pkg/ into the current gemset (required before inline_forms create)"
|
|
32
|
-
task "install:local" => ["build:all"] do
|
|
39
|
+
task "install:local" => [ "build:all" ] do
|
|
33
40
|
gems = inline_forms_pkg_gems
|
|
34
41
|
vh = validation_hints_pkg_gem
|
|
35
42
|
gems << vh if vh
|
|
@@ -38,16 +45,50 @@ task "install:local" => ["build:all"] do
|
|
|
38
45
|
puts "Verify: inline_forms --version 2>/dev/null || gem which inline_forms_installer"
|
|
39
46
|
end
|
|
40
47
|
|
|
41
|
-
# Release inline_forms + inline_forms_installer
|
|
42
|
-
# Does not run inline_forms create,
|
|
43
|
-
#
|
|
44
|
-
|
|
48
|
+
# Release inline_forms + inline_forms_installer + inline_forms_schema_edit
|
|
49
|
+
# (build, git tag/push, RubyGems push). Does not run inline_forms create,
|
|
50
|
+
# MyApp, or tests. validation_hints is a separate repo:
|
|
51
|
+
# cd ../validation_hints && rake release (same version number).
|
|
52
|
+
# Release git-push ALWAYS targets `origin` (GitHub) only.
|
|
53
|
+
#
|
|
54
|
+
# Do NOT use Bundler's stock `release:source_control_push`: it pushes to the
|
|
55
|
+
# CURRENT BRANCH's tracking remote (`git config branch.<branch>.remote`).
|
|
56
|
+
# Feature branches in this repo track `forgejo` (dev02) because that's where
|
|
57
|
+
# CI runs, so a release cut from a feature branch would push the release commit
|
|
58
|
+
# and version tag to forgejo instead of GitHub. `origin` is the only place
|
|
59
|
+
# release commits/tags belong; `forgejo` is CI-only. This task is also
|
|
60
|
+
# idempotent on the tag, so a re-run after a failed push still lands the tag on
|
|
61
|
+
# origin (Bundler's version skips entirely once the tag exists locally).
|
|
62
|
+
# Also override the bare `release` task (from install_tasks above) so a stray
|
|
63
|
+
# `rake release` can't push to a feature branch's forgejo tracking remote
|
|
64
|
+
# either. The intended entry point is `release:all`, but this closes the
|
|
65
|
+
# footgun on both.
|
|
66
|
+
Rake::Task["release"].clear if Rake::Task.task_defined?("release")
|
|
67
|
+
desc "Build inline_forms, tag, push to origin (GitHub) and push the gem to RubyGems"
|
|
68
|
+
task "release" => [ "build", "release:guard_clean",
|
|
69
|
+
"release:push_to_origin", "release:rubygem_push" ]
|
|
70
|
+
|
|
71
|
+
desc "Tag the release and push the commit + tag to origin (GitHub) only"
|
|
72
|
+
task "release:push_to_origin" do
|
|
73
|
+
version = InlineForms::VERSION
|
|
74
|
+
tag = "v#{version}"
|
|
75
|
+
branch = `git rev-parse --abbrev-ref HEAD`.strip
|
|
76
|
+
unless system("git", "rev-parse", "-q", "--verify", "refs/tags/#{tag}",
|
|
77
|
+
out: File::NULL, err: File::NULL)
|
|
78
|
+
sh "git", "tag", tag
|
|
79
|
+
end
|
|
80
|
+
sh "git", "push", "origin", "refs/heads/#{branch}"
|
|
81
|
+
sh "git", "push", "origin", "refs/tags/#{tag}"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
desc "Release inline_forms, inline_forms_installer and inline_forms_schema_edit to RubyGems (no app generation)"
|
|
45
85
|
task "release:all" => [
|
|
46
86
|
"build:all",
|
|
47
87
|
"release:guard_clean",
|
|
48
|
-
"release:
|
|
88
|
+
"release:push_to_origin",
|
|
49
89
|
"release:rubygem_push",
|
|
50
|
-
"installer:release:rubygem_push"
|
|
90
|
+
"installer:release:rubygem_push",
|
|
91
|
+
"schema_edit:release:rubygem_push"
|
|
51
92
|
]
|
|
52
93
|
|
|
53
94
|
require "rake/testtask"
|
|
Binary file
|
|
Binary file
|