├── .rbenv-gemsets ├── spec ├── dummy │ ├── log │ │ └── .keep │ ├── app │ │ ├── mailers │ │ │ └── .keep │ │ ├── models │ │ │ ├── .keep │ │ │ ├── application_record.rb │ │ │ ├── event_release.rb │ │ │ ├── jersey.rb │ │ │ ├── milestone.rb │ │ │ ├── release_selling_point.rb │ │ │ ├── varietal.rb │ │ │ ├── location.rb │ │ │ ├── cat.rb │ │ │ ├── team.rb │ │ │ ├── selling_point.rb │ │ │ ├── acclaim.rb │ │ │ ├── spirit.rb │ │ │ ├── sub_spirit.rb │ │ │ ├── event.rb │ │ │ ├── article_category.rb │ │ │ ├── concerns │ │ │ │ └── fae │ │ │ │ │ ├── file_concern.rb │ │ │ │ │ ├── image_concern.rb │ │ │ │ │ ├── role_concern.rb │ │ │ │ │ ├── user_concern.rb │ │ │ │ │ ├── option_concern.rb │ │ │ │ │ ├── text_area_concern.rb │ │ │ │ │ ├── text_field_concern.rb │ │ │ │ │ └── static_page_concern.rb │ │ │ ├── person.rb │ │ │ ├── sub_aroma.rb │ │ │ ├── beer.rb │ │ │ ├── article.rb │ │ │ ├── poly_thing.rb │ │ │ ├── player.rb │ │ │ ├── release_note.rb │ │ │ ├── coach.rb │ │ │ └── contact_us_page.rb │ │ ├── assets │ │ │ ├── images │ │ │ │ └── .keep │ │ │ ├── stylesheets │ │ │ │ ├── fae.scss │ │ │ │ └── global.scss │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ └── javascripts │ │ │ │ └── pages.js │ │ ├── views │ │ │ ├── admin │ │ │ │ ├── coaches │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── players │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── teams │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── beers │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── milestones │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── wines │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── new.html.slim │ │ │ │ ├── acclaims │ │ │ │ │ ├── new.html.erb │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ └── _form.html.erb │ │ │ │ ├── articles │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── events │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ └── new.html.erb │ │ │ │ ├── jerseys │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── locations │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── people │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ ├── new.html.erb │ │ │ │ │ └── _form.html.erb │ │ │ │ ├── releases │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── erb │ │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ │ └── new.html.erb │ │ │ │ ├── spirits │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── index.html.slim │ │ │ │ ├── validation_testers │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── varietals │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ ├── new.html.erb │ │ │ │ │ └── _form.html.erb │ │ │ │ ├── article_categories │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── selling_points │ │ │ │ │ ├── edit.html.erb │ │ │ │ │ ├── new.html.erb │ │ │ │ │ └── _form.html.erb │ │ │ │ ├── cats │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── index.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── aromas │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ └── table.html.slim │ │ │ │ ├── winemakers │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── _form.html.slim │ │ │ │ │ └── table.html.slim │ │ │ │ ├── poly_things │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── table.html.slim │ │ │ │ ├── sub_aromas │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ ├── table.html.slim │ │ │ │ │ └── _form.html.slim │ │ │ │ ├── sub_spirits │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── table.html.slim │ │ │ │ ├── release_notes │ │ │ │ │ ├── edit.html.slim │ │ │ │ │ ├── new.html.slim │ │ │ │ │ └── table.html.slim │ │ │ │ └── content_blocks │ │ │ │ │ └── about_us.html.slim │ │ │ └── pages │ │ │ │ └── home.html.erb │ │ ├── helpers │ │ │ ├── pages_helper.rb │ │ │ ├── application_helper.rb │ │ │ └── fae │ │ │ │ └── fae_helper.rb │ │ ├── controllers │ │ │ ├── admin │ │ │ │ ├── release_notes_controller.rb │ │ │ │ ├── sub_aromas_controller.rb │ │ │ │ ├── article_categories_controller.rb │ │ │ │ ├── locations_controller.rb │ │ │ │ ├── varietals_controller.rb │ │ │ │ ├── selling_points_controller.rb │ │ │ │ ├── jerseys_controller.rb │ │ │ │ ├── teams_controller.rb │ │ │ │ ├── milestones_controller.rb │ │ │ │ ├── validation_testers_controller.rb │ │ │ │ ├── articles_controller.rb │ │ │ │ ├── events_controller.rb │ │ │ │ ├── sub_spirits_controller.rb │ │ │ │ ├── people_controller.rb │ │ │ │ ├── content_blocks_controller.rb │ │ │ │ ├── aromas_controller.rb │ │ │ │ ├── spirits_controller.rb │ │ │ │ ├── acclaims_controller.rb │ │ │ │ ├── beers_controller.rb │ │ │ │ ├── poly_things_controller.rb │ │ │ │ └── releases_controller.rb │ │ │ ├── pages_controller.rb │ │ │ ├── application_controller.rb │ │ │ └── concerns │ │ │ │ └── fae │ │ │ │ └── application_controller_concern.rb │ │ └── decorators │ │ │ └── static_page_decorator.rb │ ├── lib │ │ ├── assets │ │ │ └── .keep │ │ ├── rails │ │ │ └── test_unit │ │ │ │ └── sub_test_task.rb │ │ └── tasks │ │ │ └── fae_tasks.rake │ ├── public │ │ ├── favicon.ico │ │ └── test.jpg │ ├── bin │ │ ├── rake │ │ ├── bundle │ │ └── rails │ ├── config │ │ ├── initializers │ │ │ ├── datadog.rb │ │ │ ├── cookies_serializer.rb │ │ │ ├── session_store.rb │ │ │ ├── mime_types.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── simple_form │ │ │ │ └── translation_component.rb │ │ │ ├── judge.rb │ │ │ ├── assets.rb │ │ │ ├── backtrace_silencers.rb │ │ │ ├── inflections.rb │ │ │ └── wrap_parameters.rb │ │ ├── storage.yml │ │ ├── environment.rb │ │ └── boot.rb │ ├── config.ru │ ├── db │ │ ├── migrate │ │ │ ├── 20150825231046_add_slug_to_aromas.rb │ │ │ ├── 20171102203717_add_color_to_teams.rb │ │ │ ├── 20160116015621_destroy_to_be_destroyed.rb │ │ │ ├── 20160311225043_add_aroma_id_to_cats.rb │ │ │ ├── 20140905232047_add_event_id_to_people.rb │ │ │ ├── 20141006185920_add_video_to_release.rb │ │ │ ├── 20141009200746_add_position_to_people.rb │ │ │ ├── 20150213170720_add_weight_to_releases.rb │ │ │ ├── 20151219002458_add_position_to_events.rb │ │ │ ├── 20170503080624_add_content_to_releases.rb │ │ │ ├── 20141223225922_add_featured_to_releases.rb │ │ │ ├── 20150213173312_add_release_id_to_aromas.rb │ │ │ ├── 20151125182540_add_description_to_releases.rb │ │ │ ├── 20171121212302_move_color.rb │ │ │ ├── 20140905231309_rename_column_in_events_table.rb │ │ │ ├── 20160419164359_add_region_type_to_winemaker.rb │ │ │ ├── 20141027234702_add_publication_date_to_acclaim.rb │ │ │ ├── 20221115162479_add_mfa_enabeled_to_fae_users.rb │ │ │ ├── 20160226000222_remove_foreign_key_for_rails_4_1_support.rb │ │ │ ├── 20160815163139_add_release_id_to_release_notes.rb │ │ │ ├── 20191211193749_add_is_something_to_releases.rb │ │ │ ├── 20230202161225_add_mfa_enabling_user_to_fae_options.rb │ │ │ ├── 20140905221727_create_people.rb │ │ │ ├── 20221027165831_add_devise_two_factor_backupable_to_users.rb │ │ │ ├── 20221111154088_add_mfa_enabeled_to_fae_options.rb │ │ │ ├── 20240730180416_create_spirits.rb │ │ │ ├── 20170714185443_add_seo_fields_to_release.rb │ │ │ ├── 20230908194606_add_french_canadian_to_wines.rb │ │ │ ├── 20150513172042_add_language_to_users.fae.rb │ │ │ ├── 20141009155137_add_on_env_to_people.rb │ │ │ ├── 20220128134117_rename_publish_hooks.fae.rb │ │ │ ├── 20230913192940_add_language_fields_to_poly_thing.rb │ │ │ ├── 20141019043832_add_file_size_to_fae_images.fae.rb │ │ │ ├── 20160116014913_create_to_be_destroyeds.rb │ │ │ ├── 20141123214713_change_fae_page_to_fae_static_page.fae.rb │ │ │ ├── 20160414221357_create_jerseys.rb │ │ │ ├── 20150305214314_create_teams.rb │ │ │ ├── 20141106223652_create_locations.rb │ │ │ ├── 20150213185222_add_date_fields_to_releases.rb │ │ │ ├── 20141126180655_change_field_in_fae_text_fields.fae.rb │ │ │ ├── 20160413202106_create_milestones.rb │ │ │ ├── 20230913145137_add_translate_language_to_fae_options.fae.rb │ │ │ ├── 20150909230658_create_cats.rb │ │ │ ├── 20170714052248_create_article_categories.rb │ │ │ ├── 20221111143428_create_sub_aromas.rb │ │ │ ├── 20220304182247_create_poly_things.rb │ │ │ ├── 20240730200356_create_sub_spirits.rb │ │ │ ├── 20141021161543_remove_faviconable_from_fae_image.fae.rb │ │ │ ├── 20140905223641_create_event_release.rb │ │ │ ├── 20150213172238_create_aromas.rb │ │ │ ├── 20160815162731_create_release_notes.rb │ │ │ ├── 20220202153906_add_position_to_deploy_hooks.fae.rb │ │ │ ├── 20221027164428_add_devise_two_factor_to_users.rb │ │ │ ├── 20241101145909_create_open_ai_api_calls.fae.rb │ │ │ ├── 20141019043830_create_fae_roles.fae.rb │ │ │ ├── 20151013225140_create_winemakers.rb │ │ │ ├── 20140902223650_create_wine.rb │ │ │ ├── 20140902230910_create_release_selling_point.rb │ │ │ ├── 20141120052810_add_required_to_images_and_files.fae.rb │ │ │ ├── 20170714052711_create_articles.rb │ │ │ ├── 20170714184925_create_beers.rb │ │ │ ├── 20150305215553_create_players.rb │ │ │ ├── 20150305215901_create_coaches.rb │ │ │ ├── 20140902225712_create_varietal.rb │ │ │ ├── 20220118195219_create_fae_publish_hooks.fae.rb │ │ │ ├── 20140902231710_create_selling_points.rb │ │ │ ├── 20140905221522_create_events.rb │ │ │ ├── 20240705141148_create_fae_sites.fae.rb │ │ │ ├── 20240708133519_create_fae_site_deploy_hooks.fae.rb │ │ │ ├── 20141021184641_create_fae_pages.fae.rb │ │ │ ├── 20191010130931_create_fae_form_managers.fae.rb │ │ │ ├── 20140902233505_create_acclaim.rb │ │ │ ├── 20240730152108_create_fae_ctas.fae.rb │ │ │ ├── 20150925190110_create_validation_testers.rb │ │ │ ├── 20221118192940_create_fae_seo_sets.fae.rb │ │ │ ├── 20141019043833_create_fae_options.fae.rb │ │ │ ├── 20141021183653_create_fae_text_areas.fae.rb │ │ │ ├── 20150929195433_add_extra_fields_to_validation_testers.rb │ │ │ ├── 20150508224216_add_languages_to_wines.rb │ │ │ ├── 20140827225157_create_releases.rb │ │ │ ├── 20141021181927_create_fae_files.fae.rb │ │ │ ├── 20151001210315_create_fae_changes.fae.rb │ │ │ └── 20141105221151_create_fae_text_fields.fae.rb │ │ └── seeds.rb │ ├── Rakefile │ └── README.rdoc ├── rails_helper.rb ├── support │ ├── assets │ │ ├── test.jpg │ │ ├── test.pdf │ │ └── test-2.jpg │ ├── async_helper.rb │ └── database_cleaner.rb ├── factories │ ├── selling_point_factory.rb │ ├── sequences.rb │ ├── fae │ │ ├── role_factory.rb │ │ ├── text_area_factory.rb │ │ ├── text_field_factory.rb │ │ ├── change_factory.rb │ │ ├── static_page_factory.rb │ │ ├── site.rb │ │ ├── file_factory.rb │ │ ├── deploy_hook_factory.rb │ │ ├── site_deploy_hook.rb │ │ ├── option_factory.rb │ │ ├── image_factory.rb │ │ └── user_factory.rb │ ├── beer_factory.rb │ ├── cat_factory.rb │ ├── milestone_factory.rb │ ├── home_page_factory.rb │ ├── team_factory.rb │ ├── person_factory.rb │ ├── winemaker_factory.rb │ ├── location_factory.rb │ ├── varietal_factory.rb │ ├── acclaim_factory.rb │ ├── aroma_factory.rb │ ├── contact_us_page_factory.rb │ ├── event_factory.rb │ ├── sub_aroma_factory.rb │ ├── release_note_factory.rb │ ├── validation_tester.rb │ ├── release_factory.rb │ ├── coach_factory.rb │ └── wine_factory.rb ├── models │ └── fae │ │ ├── deploy_hook_spec.rb │ │ ├── file_spec.rb │ │ ├── image_spec.rb │ │ ├── text_area_spec.rb │ │ ├── text_field_spec.rb │ │ └── change_spec.rb ├── helpers │ └── fae_helper_spec.rb ├── requests │ ├── fae │ │ ├── kaminari_spec.rb │ │ ├── devise_spec.rb │ │ ├── changes_spec.rb │ │ └── images_spec.rb │ ├── content_blocks_spec.rb │ └── fae_nested_table_spec.rb ├── services │ └── netlify_api_spec.rb ├── features │ ├── form_helpers │ │ ├── fae_file_form_spec.rb │ │ ├── fae_suffix_spec.rb │ │ ├── fae_prefix_spec.rb │ │ ├── fae_image_form_spec.rb │ │ ├── fae_color_picker_spec.rb │ │ ├── fae_datepicker_spec.rb │ │ └── fae_daterange_spec.rb │ ├── custom_assets_spec.rb │ ├── markdown_binding_spec.rb │ └── sign_out_spec.rb └── controllers │ └── fae │ └── application_controller_spec.rb ├── app ├── assets │ ├── images │ │ └── fae │ │ │ ├── .keep │ │ │ ├── error_bg.jpg │ │ │ ├── error_sad_face.png │ │ │ ├── youtube_helper.jpg │ │ │ ├── tutorial_model_location.png │ │ │ └── icons │ │ │ ├── arrow_down.svg │ │ │ ├── arrow_up.svg │ │ │ ├── chevron_down.svg │ │ │ ├── chevron_up.svg │ │ │ ├── plus.svg │ │ │ ├── check.svg │ │ │ ├── sort.svg │ │ │ ├── arrow_left.svg │ │ │ ├── arrow_right.svg │ │ │ ├── delete_x.svg │ │ │ ├── pulldown.svg │ │ │ ├── chevron_left.svg │ │ │ ├── chevron_right.svg │ │ │ └── menu.svg │ ├── config │ │ └── fae │ │ │ └── manifest.js │ ├── fonts │ │ └── fae │ │ │ ├── icons.eot │ │ │ ├── icons.ttf │ │ │ ├── icons.woff │ │ │ ├── lato-bold-webfont.eot │ │ │ ├── lato-bold-webfont.ttf │ │ │ ├── lato-bold-webfont.woff │ │ │ ├── lato-light-webfont.eot │ │ │ ├── lato-light-webfont.ttf │ │ │ ├── lato-light-webfont.woff │ │ │ ├── lato-regular-webfont.eot │ │ │ ├── lato-regular-webfont.ttf │ │ │ └── lato-regular-webfont.woff │ ├── stylesheets │ │ └── fae │ │ │ ├── globals │ │ │ ├── imports │ │ │ │ └── finescss │ │ │ │ │ └── _fine.scss │ │ │ ├── _icons.scss │ │ │ └── navigation │ │ │ │ └── _base.scss │ │ │ ├── pages │ │ │ ├── _mfa.scss │ │ │ ├── _home.scss │ │ │ └── _help.scss │ │ │ ├── modules │ │ │ ├── tables │ │ │ │ ├── _sticky.scss │ │ │ │ ├── _image.scss │ │ │ │ ├── _alt_text_manager.scss │ │ │ │ └── _tooltips.scss │ │ │ ├── forms │ │ │ │ └── _textarea.scss │ │ │ ├── _errors-bar.scss │ │ │ └── _deploy.scss │ │ │ └── application.css │ └── javascripts │ │ └── fae │ │ ├── fae_init.js │ │ ├── vendor │ │ └── trumbowyg.js.erb │ │ └── admin.js.erb ├── views │ ├── fae │ │ ├── options │ │ │ └── edit.html.slim │ │ ├── sites │ │ │ ├── edit.html.slim │ │ │ └── new.html.slim │ │ ├── users │ │ │ ├── edit.html.slim │ │ │ ├── new.html.slim │ │ │ ├── settings.html.slim │ │ │ └── _form.html.slim │ │ ├── shared │ │ │ └── _errors.slim │ │ ├── application │ │ │ ├── _flash_messages.slim │ │ │ └── _seo_set_form.html.slim │ │ ├── deploy_hooks │ │ │ ├── new.html.slim │ │ │ ├── edit.html.slim │ │ │ └── _form.html.slim │ │ ├── site_deploy_hooks │ │ │ ├── new.html.slim │ │ │ ├── edit.html.slim │ │ │ └── _form.html.slim │ │ ├── pages │ │ │ ├── disabled_environment.html.slim │ │ │ └── error404.html.slim │ │ ├── setup │ │ │ └── first_user.html.slim │ │ ├── static_pages │ │ │ └── index.html.slim │ │ └── two_factor_settings │ │ │ └── edit.html.slim │ ├── devise │ │ ├── mailer │ │ │ ├── confirmation_instructions.html.slim │ │ │ ├── unlock_instructions.html.slim │ │ │ └── reset_password_instructions.html.slim │ │ ├── unlocks │ │ │ └── new.html.slim │ │ ├── registrations │ │ │ └── new.html.slim │ │ ├── confirmations │ │ │ └── new.html.slim │ │ ├── passwords │ │ │ ├── new.html.slim │ │ │ └── edit.html.slim │ │ └── sessions │ │ │ └── new.html.slim │ ├── layouts │ │ └── fae │ │ │ └── error.html.slim │ └── kaminari │ │ └── fae │ │ ├── _gap.html.slim │ │ ├── _next_page.html.slim │ │ ├── _prev_page.html.slim │ │ └── _page.html.slim ├── models │ ├── concerns │ │ └── fae │ │ │ ├── cta_concern.rb │ │ │ ├── file_concern.rb │ │ │ ├── role_concern.rb │ │ │ ├── change_concern.rb │ │ │ ├── image_concern.rb │ │ │ ├── option_concern.rb │ │ │ ├── seo_set_concern.rb │ │ │ ├── text_area_concern.rb │ │ │ ├── text_field_concern.rb │ │ │ ├── static_page_concern.rb │ │ │ ├── open_ai_api_call_concern.rb │ │ │ ├── paper_trailer.rb │ │ │ ├── navigation_concern.rb │ │ │ ├── user_concern.rb │ │ │ ├── authorization_concern.rb │ │ │ └── assets_validatable.rb │ └── fae │ │ ├── open_ai_api_call.rb │ │ ├── authorization.rb │ │ ├── deploy_hook.rb │ │ ├── text_area.rb │ │ ├── text_field.rb │ │ ├── seo_set.rb │ │ ├── site_deploy_hook.rb │ │ ├── cta.rb │ │ ├── site.rb │ │ ├── role.rb │ │ ├── file.rb │ │ └── form_manager.rb ├── controllers │ ├── concerns │ │ └── fae │ │ │ └── application_controller_concern.rb │ └── fae │ │ ├── sessions_controller.rb │ │ └── site_deploy_hooks_controller.rb ├── helpers │ └── fae │ │ ├── fae_helper.rb │ │ └── qr_code_helper.rb ├── inputs │ ├── symbol_input.rb │ └── radio_collection_input.rb └── validators │ └── fae │ └── cross_model_uniqueness_validator.rb ├── .rspec ├── lib ├── fae │ ├── version.rb │ └── concerns │ │ └── models │ │ └── base.rb ├── generators │ └── fae │ │ ├── templates │ │ ├── views │ │ │ ├── edit.html.slim │ │ │ ├── new.html.slim │ │ │ ├── edit_nested.html.slim │ │ │ ├── new_nested.html.slim │ │ │ ├── table_nested.html.slim │ │ │ └── index_nested.html.slim │ │ ├── assets │ │ │ ├── fae.scss │ │ │ └── fae.js │ │ ├── initializers │ │ │ └── judge.rb │ │ ├── controllers │ │ │ └── static_pages_controller.rb │ │ ├── models │ │ │ └── pages_model.rb │ │ ├── graphql │ │ │ ├── graphql_type.rb │ │ │ └── graphql_page_type.rb │ │ └── tasks │ │ │ └── fae_tasks.rake │ │ ├── model_generator.rb │ │ ├── controller_generator.rb │ │ └── scaffold_generator.rb ├── fae-rails.rb └── components │ ├── translate_component.rb │ └── generate_alt_component.rb ├── docs ├── images │ ├── file.png │ ├── image.png │ ├── prefix.png │ ├── radio.png │ ├── suffix.png │ ├── checkbox.png │ ├── pulldown.gif │ ├── slugger.gif │ ├── toggles.gif │ ├── collapsible.gif │ ├── colorpicker.gif │ ├── datepicker.gif │ ├── filter_form.png │ ├── form_header.png │ ├── multiselect.gif │ ├── navigation.png │ ├── video_url.gif │ ├── fae_paginate.png │ ├── filter_select.png │ ├── nested_table.png │ ├── daterange_picker.gif │ ├── pulldown_search.gif │ ├── recent_changes.png │ ├── length_validation.gif │ └── two_pane_multiselect.gif ├── contributing │ ├── share_your_creation.md │ └── standards.md ├── topics │ └── root_settings.md ├── tutorials │ └── landing_page.md └── features │ ├── disable_envs.md │ └── search.md ├── config └── initializers │ ├── assets.rb │ ├── fae_judge.rb │ ├── time_formats.rb │ ├── kaminari_config.rb │ └── two_factor_backupable_patch.rb ├── db └── migrate │ ├── 20220128133730_rename_publish_hooks.rb │ ├── 20221115162441_add_mfa_enabeled_to_fae_users.rb │ ├── 20230202161225_add_mfa_enabling_user_to_fae_options.rb │ ├── 20221111154032_add_mfa_enabeled_to_fae_options.rb │ ├── 20221027165833_add_devise_two_factor_backupable_to_users.rb │ ├── 20230913144458_add_translate_language_to_fae_options.rb │ ├── 20220202153607_add_position_to_deploy_hooks.rb │ ├── 20140822224029_create_fae_roles.rb │ ├── 20220118192729_create_fae_publish_hooks.rb │ ├── 20221027164701_add_devise_two_factor_to_users.rb │ ├── 20240705135709_create_fae_sites.rb │ ├── 20241101145909_create_open_ai_api_calls.rb │ ├── 20190925153222_create_fae_form_managers.rb │ ├── 20240708133519_create_fae_site_deploy_hooks.rb │ ├── 20240730152108_create_fae_ctas.rb │ ├── 20141021184311_create_fae_pages.rb │ ├── 20221118161833_create_fae_seo_sets.rb │ ├── 20141017194616_create_fae_options.rb │ ├── 20150930224821_create_fae_changes.rb │ ├── 20141105214814_create_fae_text_fields.rb │ ├── 20141021181327_create_fae_files.rb │ ├── 20141021183047_create_fae_text_areas.rb │ └── 20141008180718_create_fae_images_table.rb ├── Appraisals ├── bin ├── render-build.sh └── rails ├── .devcontainer └── devcontainer.json ├── Dockerfile.dev ├── .gitignore └── .codeclimate.yml /.rbenv-gemsets: -------------------------------------------------------------------------------- 1 | fae 2 | -------------------------------------------------------------------------------- /spec/dummy/log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/fae/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --require rails_helper 2 | --color -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | -------------------------------------------------------------------------------- /app/views/fae/options/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/views/fae/sites/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/views/fae/sites/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/views/fae/users/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/views/fae/users/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/views/fae/users/settings.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/coaches/new.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/players/new.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/teams/new.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' -------------------------------------------------------------------------------- /app/views/fae/shared/_errors.slim: -------------------------------------------------------------------------------- 1 | == render 'flash_messages' 2 | -------------------------------------------------------------------------------- /lib/fae/version.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | VERSION = '3.1.0' 3 | end 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/beers/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/beers/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/milestones/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/teams/edit.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/wines/edit.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/wines/new.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/cta_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::CtaConcern; end 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/file_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::FileConcern; end 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/role_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::RoleConcern; end 2 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/views/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/views/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/helpers/pages_helper.rb: -------------------------------------------------------------------------------- 1 | module PagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/acclaims/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/articles/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/articles/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/coaches/edit.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/events/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/events/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jerseys/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jerseys/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/locations/edit.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/locations/new.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/milestones/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/people/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/people/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/players/edit.html.slim: -------------------------------------------------------------------------------- 1 | = render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/releases/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/releases/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/spirits/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/spirits/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/change_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::ChangeConcern; end 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/image_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::ImageConcern; end 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/option_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::OptionConcern; end 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/seo_set_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::SeoSetConcern; end 2 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/fae.scss: -------------------------------------------------------------------------------- 1 | // Add custom SCSS to this file 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/acclaims/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/validation_testers/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/varietals/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/varietals/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/text_area_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::TextAreaConcern; end 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/text_field_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::TextFieldConcern; end 2 | -------------------------------------------------------------------------------- /spec/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/article_categories/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/article_categories/new.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/selling_points/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/selling_points/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/validation_testers/edit.html.slim: -------------------------------------------------------------------------------- 1 | == render 'form' 2 | -------------------------------------------------------------------------------- /app/models/concerns/fae/static_page_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::StaticPageConcern; end 2 | -------------------------------------------------------------------------------- /app/assets/config/fae/manifest.js: -------------------------------------------------------------------------------- 1 | //= link fae/application.css 2 | //= link fae/application.js -------------------------------------------------------------------------------- /app/models/concerns/fae/open_ai_api_call_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::OpenAiApiCallConcern; end 2 | -------------------------------------------------------------------------------- /docs/images/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/file.png -------------------------------------------------------------------------------- /docs/images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/image.png -------------------------------------------------------------------------------- /docs/images/prefix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/prefix.png -------------------------------------------------------------------------------- /docs/images/radio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/radio.png -------------------------------------------------------------------------------- /docs/images/suffix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/suffix.png -------------------------------------------------------------------------------- /docs/images/checkbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/checkbox.png -------------------------------------------------------------------------------- /docs/images/pulldown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/pulldown.gif -------------------------------------------------------------------------------- /docs/images/slugger.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/slugger.gif -------------------------------------------------------------------------------- /docs/images/toggles.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/toggles.gif -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/cats/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New Cat 3 | == render 'form' -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/releases/erb/edit.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'admin/releases/erb/form' %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/releases/erb/new.html.erb: -------------------------------------------------------------------------------- 1 | <%= render 'admin/releases/erb/form' %> 2 | -------------------------------------------------------------------------------- /docs/images/collapsible.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/collapsible.gif -------------------------------------------------------------------------------- /docs/images/colorpicker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/colorpicker.gif -------------------------------------------------------------------------------- /docs/images/datepicker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/datepicker.gif -------------------------------------------------------------------------------- /docs/images/filter_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/filter_form.png -------------------------------------------------------------------------------- /docs/images/form_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/form_header.png -------------------------------------------------------------------------------- /docs/images/multiselect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/multiselect.gif -------------------------------------------------------------------------------- /docs/images/navigation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/navigation.png -------------------------------------------------------------------------------- /docs/images/video_url.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/video_url.gif -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/aromas/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New Aroma 3 | = render 'form' -------------------------------------------------------------------------------- /spec/dummy/public/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/spec/dummy/public/test.jpg -------------------------------------------------------------------------------- /docs/images/fae_paginate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/fae_paginate.png -------------------------------------------------------------------------------- /docs/images/filter_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/filter_select.png -------------------------------------------------------------------------------- /docs/images/nested_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/nested_table.png -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/aromas/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit Aroma 3 | = render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/cats/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit Cat 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/support/assets/test.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/spec/support/assets/test.jpg -------------------------------------------------------------------------------- /spec/support/assets/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/spec/support/assets/test.pdf -------------------------------------------------------------------------------- /app/assets/fonts/fae/icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/icons.eot -------------------------------------------------------------------------------- /app/assets/fonts/fae/icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/icons.ttf -------------------------------------------------------------------------------- /app/assets/fonts/fae/icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/icons.woff -------------------------------------------------------------------------------- /app/controllers/concerns/fae/application_controller_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae::ApplicationControllerConcern; end 2 | -------------------------------------------------------------------------------- /docs/images/daterange_picker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/daterange_picker.gif -------------------------------------------------------------------------------- /docs/images/pulldown_search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/pulldown_search.gif -------------------------------------------------------------------------------- /docs/images/recent_changes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/recent_changes.png -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/winemakers/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New Winemaker 3 | == render 'form' -------------------------------------------------------------------------------- /spec/support/assets/test-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/spec/support/assets/test-2.jpg -------------------------------------------------------------------------------- /app/assets/images/fae/error_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/images/fae/error_bg.jpg -------------------------------------------------------------------------------- /app/views/fae/application/_flash_messages.slim: -------------------------------------------------------------------------------- 1 | - flash.each do |name, msg| 2 | .flash-message class=name = msg 3 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.assets.precompile += %w( html5shiv.js html5shiv-printshiv.js ) -------------------------------------------------------------------------------- /docs/images/length_validation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/length_validation.gif -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/poly_things/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit Poly Thing 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/poly_things/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New Poly Thing 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_aromas/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit Sub Aroma 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_aromas/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New Sub Aroma 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_spirits/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit Sub Spirit 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_spirits/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New Sub Spirit 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/winemakers/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit Winemaker 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /app/views/fae/deploy_hooks/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 = t('fae.deploy_hook.new_deploy_hook') 3 | == render 'form' -------------------------------------------------------------------------------- /docs/images/two_pane_multiselect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/docs/images/two_pane_multiselect.gif -------------------------------------------------------------------------------- /lib/fae-rails.rb: -------------------------------------------------------------------------------- 1 | require "fae/engine" 2 | require "fae/options" 3 | require 'carrierwave' 4 | 5 | module Fae 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/release_notes/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit ReleaseNote 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/release_notes/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New ReleaseNote 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /spec/factories/selling_point_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :selling_point do 4 | end 5 | 6 | end -------------------------------------------------------------------------------- /spec/factories/sequences.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | sequence :email do |n| 3 | "test#{n}@test.com" 4 | end 5 | end -------------------------------------------------------------------------------- /app/views/fae/deploy_hooks/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 = t('fae.deploy_hook.edit_deploy_hook') 3 | == render 'form' -------------------------------------------------------------------------------- /app/views/fae/site_deploy_hooks/new.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 = t('fae.deploy_hook.new_deploy_hook') 3 | == render 'form' -------------------------------------------------------------------------------- /spec/dummy/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-bold-webfont.eot -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-bold-webfont.ttf -------------------------------------------------------------------------------- /app/assets/images/fae/error_sad_face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/images/fae/error_sad_face.png -------------------------------------------------------------------------------- /app/assets/images/fae/youtube_helper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/images/fae/youtube_helper.jpg -------------------------------------------------------------------------------- /app/views/fae/site_deploy_hooks/edit.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 = t('fae.deploy_hook.edit_deploy_hook') 3 | == render 'form' -------------------------------------------------------------------------------- /spec/dummy/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /spec/factories/fae/role_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_role, class: 'Fae::Role' do 4 | end 5 | 6 | end -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-bold-webfont.woff -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-light-webfont.eot -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-light-webfont.ttf -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-light-webfont.woff -------------------------------------------------------------------------------- /lib/generators/fae/templates/views/edit_nested.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 Edit <%= class_name.titleize %> 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/views/new_nested.html.slim: -------------------------------------------------------------------------------- 1 | .nested-form 2 | h2 New <%= class_name.titleize %> 3 | == render 'form' 4 | -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-regular-webfont.eot -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-regular-webfont.ttf -------------------------------------------------------------------------------- /app/assets/fonts/fae/lato-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/fonts/fae/lato-regular-webfont.woff -------------------------------------------------------------------------------- /app/assets/images/fae/tutorial_model_location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wearefine/fae/HEAD/app/assets/images/fae/tutorial_model_location.png -------------------------------------------------------------------------------- /spec/factories/beer_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :beer do 4 | sequence(:name) { |n| "Beer #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/factories/cat_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :cat do 4 | sequence(:name) { |n| "Cat Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/factories/milestone_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :milestone do 4 | sequence(:year) { |n| n } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /config/initializers/fae_judge.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.to_prepare do 2 | Judge.configure do 3 | expose Fae::User, :email 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/home_page_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :home_page do 4 | title 'Home' 5 | slug 'home' 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /spec/factories/team_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :team do 4 | sequence(:name) { |n| "Team Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /app/views/fae/pages/disabled_environment.html.slim: -------------------------------------------------------------------------------- 1 | .center 2 | .sad_face 3 | h1 = t('fae.page.disabled_title') 4 | p = t('fae.page.disabled_text') 5 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link fae/application.css 2 | //= link fae/application.js 3 | //= link application.css 4 | //= link application.js -------------------------------------------------------------------------------- /spec/factories/person_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :person do 4 | sequence(:name) { |n| "Person Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/factories/winemaker_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :winemaker do 4 | sequence(:name) { |n| "Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /docs/contributing/share_your_creation.md: -------------------------------------------------------------------------------- 1 | # Share your creation 2 | 3 | If Fae helped build your site, share your creation with us at share@faecms.com 4 | 5 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/assets/fae.scss: -------------------------------------------------------------------------------- 1 | // Do Not Delete this page! FAE depends on it in order to set its highlight color. 2 | // $c-custom-highlight: #9aa142; -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/release_notes_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class ReleaseNotesController < Fae::NestedBaseController 3 | 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/sub_aromas_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class SubAromasController < Fae::NestedBaseController 3 | 4 | 5 | 6 | end 7 | end -------------------------------------------------------------------------------- /spec/dummy/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /spec/factories/location_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :location do 4 | sequence(:name) { |n| "Location Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/factories/varietal_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :varietal do 4 | sequence(:name) { |n| "Varietal Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/article_categories_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class ArticleCategoriesController < Fae::BaseController 3 | 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/pages_controller.rb: -------------------------------------------------------------------------------- 1 | class PagesController < ApplicationController 2 | def home 3 | @home_page = HomePage.instance 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_aromas/table.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/nested_table', 2 | assoc: :sub_aromas, 3 | parent_item: @parent_item, 4 | cols: [:name] 5 | -------------------------------------------------------------------------------- /spec/factories/acclaim_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :acclaim do 4 | sequence(:publication) { |n| "Publication Name #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/event_release.rb: -------------------------------------------------------------------------------- 1 | class EventRelease < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :release 5 | belongs_to :event 6 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/jersey.rb: -------------------------------------------------------------------------------- 1 | class Jersey < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | name 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/poly_things/table.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/nested_table', 2 | assoc: :poly_things, 3 | parent_item: @parent_item, 4 | cols: [:name] 5 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_spirits/table.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/nested_table', 2 | assoc: :sub_spirits, 3 | parent_item: @parent_item, 4 | cols: [:name] 5 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/datadog.rb: -------------------------------------------------------------------------------- 1 | Datadog.configure do |c| 2 | c.tracing.enabled = Rails.env.production? 3 | c.service = 'FAE Dummy' 4 | c.env = 'production' 5 | end -------------------------------------------------------------------------------- /spec/dummy/lib/rails/test_unit/sub_test_task.rb: -------------------------------------------------------------------------------- 1 | # monkey patch deprecated `sub_test_task` 2 | require 'rake/testtask' 3 | class Rails::SubTestTask < Rake::TestTask 4 | end 5 | -------------------------------------------------------------------------------- /spec/factories/aroma_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :aroma do 4 | sequence(:name) { |n| "Aroma Name #{n}" } 5 | 6 | release 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /spec/factories/contact_us_page_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :contact_us_page do 4 | title 'Contact Us' 5 | slug 'contact_us' 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /spec/factories/event_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :event do 4 | sequence(:name) { |n| "Event Name #{n}" } 5 | city 'Portland' 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /config/initializers/time_formats.rb: -------------------------------------------------------------------------------- 1 | Date::DATE_FORMATS[:default] = "%b %d, %Y" 2 | Time::DATE_FORMATS[:default] = "%b %d, %Y %I:%M%P" 3 | Time::DATE_FORMATS[:filename] = "%Y%m%d%H%M%S" -------------------------------------------------------------------------------- /spec/dummy/app/helpers/fae/fae_helper.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module FaeHelper 3 | 4 | def method_from_dummy 5 | 'it works!' 6 | end 7 | 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/app/models/milestone.rb: -------------------------------------------------------------------------------- 1 | class Milestone < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | year 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json -------------------------------------------------------------------------------- /spec/dummy/config/storage.yml: -------------------------------------------------------------------------------- 1 | local: 2 | service: Disk 3 | root: <%= Rails.root.join("storage") %> 4 | 5 | test: 6 | service: Disk 7 | root: <%= Rails.root.join("tmp/storage") %> -------------------------------------------------------------------------------- /spec/factories/sub_aroma_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :sub_aroma do 4 | sequence(:name) { |n| "Sub Aroma Name #{n}" } 5 | 6 | aroma 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /app/helpers/fae/fae_helper.rb: -------------------------------------------------------------------------------- 1 | # DO NOT add methods to this helper 2 | # this empty helper is meant to be overridden in the parent app 3 | module Fae 4 | module FaeHelper 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/models/fae/open_ai_api_call.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class OpenAiApiCall < ActiveRecord::Base 3 | include Fae::BaseModelConcern 4 | include Fae::OpenAiApiCallConcern 5 | end 6 | end -------------------------------------------------------------------------------- /spec/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150825231046_add_slug_to_aromas.rb: -------------------------------------------------------------------------------- 1 | class AddSlugToAromas < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :aromas, :slug, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20171102203717_add_color_to_teams.rb: -------------------------------------------------------------------------------- 1 | class AddColorToTeams < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :teams, :color, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/fae/text_area_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_text_area, class: 'Fae::TextArea' do 4 | sequence(:label) { |n| "Text Area #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/factories/release_note_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :release_note do 4 | sequence(:title) { |n| "Release Note #{n}" } 5 | 6 | release 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /app/models/concerns/fae/paper_trailer.rb: -------------------------------------------------------------------------------- 1 | module Fae::PaperTrailer 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | has_paper_trail ignore: [:updated_at] 6 | end 7 | 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/pages.js: -------------------------------------------------------------------------------- 1 | // Place all the behaviors and hooks related to the matching controller here. 2 | // All this logic will automatically be available in application.js. 3 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/locations_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::LocationsController < Fae::BaseController 2 | 3 | private 4 | 5 | def use_pagination 6 | true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_dummy_session' 4 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160116015621_destroy_to_be_destroyed.rb: -------------------------------------------------------------------------------- 1 | class DestroyToBeDestroyed < ActiveRecord::Migration[4.2] 2 | def change 3 | drop_table :to_be_destroyeds 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/fae/text_field_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_text_field, class: 'Fae::TextField' do 4 | sequence(:label) { |n| "Text Field #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /db/migrate/20220128133730_rename_publish_hooks.rb: -------------------------------------------------------------------------------- 1 | class RenamePublishHooks < ActiveRecord::Migration[5.2] 2 | def change 3 | rename_table :fae_publish_hooks, :fae_deploy_hooks 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/varietals_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::VarietalsController < Fae::BaseController 2 | 3 | private 4 | 5 | def use_pagination 6 | true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/app/models/release_selling_point.rb: -------------------------------------------------------------------------------- 1 | class ReleaseSellingPoint < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :release 5 | belongs_to :selling_point 6 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160311225043_add_aroma_id_to_cats.rb: -------------------------------------------------------------------------------- 1 | class AddAromaIdToCats < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :cats, :aroma_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/fae/change_factory.rb: -------------------------------------------------------------------------------- 1 | # Read about factories at https://github.com/thoughtbot/factory_girl 2 | 3 | FactoryBot.define do 4 | factory :fae_change, class: 'Fae::Change' do 5 | end 6 | end -------------------------------------------------------------------------------- /spec/factories/fae/static_page_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_static_page, class: 'Fae::StaticPage' do 4 | sequence(:title) { |n| "Page Title #{n}" } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140905232047_add_event_id_to_people.rb: -------------------------------------------------------------------------------- 1 | class AddEventIdToPeople < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :people, :event_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141006185920_add_video_to_release.rb: -------------------------------------------------------------------------------- 1 | class AddVideoToRelease < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :releases, :video_url, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141009200746_add_position_to_people.rb: -------------------------------------------------------------------------------- 1 | class AddPositionToPeople < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :people, :position, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150213170720_add_weight_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddWeightToReleases < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :releases, :weight, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20151219002458_add_position_to_events.rb: -------------------------------------------------------------------------------- 1 | class AddPositionToEvents < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :events, :position, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20170503080624_add_content_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddContentToReleases < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :releases, :content, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/globals/imports/finescss/_fine.scss: -------------------------------------------------------------------------------- 1 | // scss-lint:disable Indentation, TrailingSemicolon 2 | 3 | @import 4 | 'fine_variables', 5 | 'fine_functions', 6 | 'fine_mixins' 7 | ; 8 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/selling_points_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::SellingPointsController < Fae::BaseController 2 | 3 | private 4 | 5 | def use_pagination 6 | true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/app/models/varietal.rb: -------------------------------------------------------------------------------- 1 | class Varietal < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | name 6 | end 7 | 8 | has_many :release 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141223225922_add_featured_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddFeaturedToReleases < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :releases, :featured, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/models/concerns/fae/navigation_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module NavigationConcern 3 | extend ActiveSupport::Concern 4 | 5 | def structure 6 | [] 7 | end 8 | 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20221115162441_add_mfa_enabeled_to_fae_users.rb: -------------------------------------------------------------------------------- 1 | class AddMfaEnabeledToFaeUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_users, :user_mfa_enabled, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150213173312_add_release_id_to_aromas.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseIdToAromas < ActiveRecord::Migration[4.2] 2 | def change 3 | add_reference :aromas, :release, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20151125182540_add_description_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddDescriptionToReleases < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :releases, :description, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/fae/site.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :fae_site, class: 'Fae::Site' do 3 | sequence(:name) { |n| "Site #{n}" } 4 | netlify_site 'site' 5 | netlify_site_id 'abc123' 6 | end 7 | end -------------------------------------------------------------------------------- /spec/factories/validation_tester.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :validation_tester do 4 | sequence(:name) { |n| "Validation Tester Name #{n}" } 5 | second_slug 'valid-slug' 6 | end 7 | 8 | end -------------------------------------------------------------------------------- /spec/models/fae/deploy_hook_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::DeployHook do 4 | 5 | it { should validate_presence_of(:url) } 6 | it { should validate_presence_of(:environment) } 7 | 8 | end -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/release_notes/table.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/nested_table', 2 | assoc: :release_notes, 3 | parent_item: @parent_item, 4 | hide_delete_button: true, 5 | cols: [:title, :body] 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20171121212302_move_color.rb: -------------------------------------------------------------------------------- 1 | class MoveColor < ActiveRecord::Migration[5.0] 2 | def change 3 | remove_column :teams, :color 4 | add_column :releases, :color, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise 'rails_5_0' do 2 | gem 'rails', '~> 5.0' 3 | end 4 | 5 | appraise 'rails_5_1' do 6 | gem 'rails', '~> 5.1' 7 | end 8 | 9 | appraise 'rails_5_2' do 10 | gem 'rails', '~> 5.2' 11 | end 12 | -------------------------------------------------------------------------------- /app/models/fae/authorization.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class Authorization 3 | include Fae::AuthorizationConcern 4 | 5 | # `self.access_map` is defined in Fae::AuthorizationConcern on the parent app 6 | 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/jerseys_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class JerseysController < Fae::BaseController 3 | private 4 | 5 | def use_pagination 6 | true 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/teams_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class TeamsController < Fae::BaseController 3 | 4 | private 5 | 6 | def use_pagination 7 | true 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/article_categories/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | main.content 5 | = fae_input f, :name 6 | 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140905231309_rename_column_in_events_table.rb: -------------------------------------------------------------------------------- 1 | class RenameColumnInEventsTable < ActiveRecord::Migration[4.2] 2 | def change 3 | rename_column :events, :people_id, :person_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160419164359_add_region_type_to_winemaker.rb: -------------------------------------------------------------------------------- 1 | class AddRegionTypeToWinemaker < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :winemakers, :region_type, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/fae/file_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_file, class: 'Fae::File' do 4 | asset { Rack::Test::UploadedFile.new(File.join('spec', 'support', 'assets', 'test.pdf')) } 5 | end 6 | 7 | end -------------------------------------------------------------------------------- /spec/factories/release_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :release do 4 | sequence(:name) { |n| "Release Name #{n}" } 5 | release_date { 10.days.ago } 6 | 7 | wine 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /db/migrate/20230202161225_add_mfa_enabling_user_to_fae_options.rb: -------------------------------------------------------------------------------- 1 | class AddMfaEnablingUserToFaeOptions < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_options, :mfa_enabling_user, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141027234702_add_publication_date_to_acclaim.rb: -------------------------------------------------------------------------------- 1 | class AddPublicationDateToAcclaim < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :acclaims, :publication_date, :date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20221115162479_add_mfa_enabeled_to_fae_users.rb: -------------------------------------------------------------------------------- 1 | class AddMfaEnabeledToFaeUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_users, :user_mfa_enabled, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/coach_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :coach do 4 | sequence(:first_name) { |n| "First#{n}" } 5 | sequence(:last_name) { |n| "Last#{n}" } 6 | 7 | team 8 | end 9 | 10 | end -------------------------------------------------------------------------------- /spec/factories/fae/deploy_hook_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :fae_deploy_hook, :class => 'Fae::DeployHook' do 3 | url "https://api.netlify.com/build_hooks/1234" 4 | environment "Production" 5 | end 6 | end -------------------------------------------------------------------------------- /spec/helpers/fae_helper_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::FaeHelper do 4 | 5 | it 'should allow parent app to add methods' do 6 | expect(helper.method_from_dummy).to eq('it works!') 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /lib/generators/fae/templates/initializers/judge.rb: -------------------------------------------------------------------------------- 1 | # expose uniqueness attributes in Judge in here with the following syntax 2 | # 3 | # Judge.configure do 4 | # expose Model1, :attr 5 | # expose Model2, :attr1, :attr2 6 | # end 7 | -------------------------------------------------------------------------------- /spec/dummy/app/decorators/static_page_decorator.rb: -------------------------------------------------------------------------------- 1 | class StaticPageDecorator 2 | 3 | Fae::StaticPage.class_eval do 4 | def instance_is_decorated 5 | "Fae::StaticPage instance is decorated" 6 | end 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/location.rb: -------------------------------------------------------------------------------- 1 | class Location < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | name 6 | end 7 | 8 | belongs_to :contact, class_name: 'Person' 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160226000222_remove_foreign_key_for_rails_4_1_support.rb: -------------------------------------------------------------------------------- 1 | class RemoveForeignKeyForRails41Support < ActiveRecord::Migration[4.2] 2 | def change 3 | remove_foreign_key :winemakers, :wines 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160815163139_add_release_id_to_release_notes.rb: -------------------------------------------------------------------------------- 1 | class AddReleaseIdToReleaseNotes < ActiveRecord::Migration[4.2] 2 | def change 3 | add_reference :release_notes, :release, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20191211193749_add_is_something_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddIsSomethingToReleases < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :releases, :is_something, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/fae/fae_init.js: -------------------------------------------------------------------------------- 1 | /* global Fae, FCH */ 2 | 3 | // This is a separate file to keep application.js pure 4 | ;(function() { 5 | window.FCH = new FrobCoreHelpers(Fae, { 6 | mobile_fps: false 7 | }); 8 | })(); 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/pages/_mfa.scss: -------------------------------------------------------------------------------- 1 | .mfa-section-content { 2 | display: flex; 3 | } 4 | 5 | .mfa-or { 6 | padding-left: 30px; 7 | padding-top: 20px; 8 | } 9 | 10 | .mfa-backup-codes { 11 | min-width: 7%; 12 | } 13 | -------------------------------------------------------------------------------- /app/views/fae/pages/error404.html.slim: -------------------------------------------------------------------------------- 1 | .center 2 | .sad_face 3 | h1 Oops! 4 | p 5 | = t('fae.page.error_start') 6 | |  7 | a href=fae.root_path = t('fae.page.click') 8 | |   9 | = t('fae.page.error_end') 10 | -------------------------------------------------------------------------------- /db/migrate/20221111154032_add_mfa_enabeled_to_fae_options.rb: -------------------------------------------------------------------------------- 1 | class AddMfaEnabeledToFaeOptions < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_options, :site_mfa_enabled, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/views/table_nested.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/nested_table', 2 | assoc: :<%= file_name.pluralize %>, 3 | parent_item: @parent_item, 4 | cols: [<%= @form_attrs.map {|attr| ":#{attr}"}.join(', ') %>] 5 | -------------------------------------------------------------------------------- /app/views/devise/mailer/confirmation_instructions.html.slim: -------------------------------------------------------------------------------- 1 | p Welcome #{@email}! 2 | p You can confirm your account email through the link below: 3 | p = link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @token) 4 | -------------------------------------------------------------------------------- /bin/render-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # exit on error 3 | set -o errexit 4 | 5 | ls -la 6 | cd spec/dummy 7 | bundle install 8 | bundle exec rake assets:precompile 9 | bundle exec rake assets:clean 10 | bundle exec rake db:migrate -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/milestones_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class MilestonesController < Fae::BaseController 3 | 4 | private 5 | 6 | def use_pagination 7 | true 8 | end 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/validation_testers_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class ValidationTestersController < Fae::BaseController 3 | private 4 | 5 | def use_pagination 6 | true 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jerseys/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | main.content 5 | = fae_input f, :name 6 | = fae_input f, :color 7 | 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20230202161225_add_mfa_enabling_user_to_fae_options.rb: -------------------------------------------------------------------------------- 1 | class AddMfaEnablingUserToFaeOptions < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_options, :mfa_enabling_user, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/factories/wine_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :wine do 4 | sequence(:name_en) { |n| "English Name #{n}" } 5 | sequence(:name_zh) { |n| "中国名字 #{n}" } 6 | sequence(:name_ja) { |n| "和名 #{n}" } 7 | end 8 | 9 | end -------------------------------------------------------------------------------- /app/assets/javascripts/fae/vendor/trumbowyg.js.erb: -------------------------------------------------------------------------------- 1 | //= require fae/vendor/trumbowyg/trumbowyg 2 | //= require fae/vendor/trumbowyg/plugins/upload/trumbowyg.upload 3 | 4 | jQuery.trumbowyg.svgPath = "<%= image_path('fae/icons/trumbowyg.svg') %>" 5 | -------------------------------------------------------------------------------- /app/models/concerns/fae/user_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module UserConcern 3 | extend ActiveSupport::Concern 4 | module ClassMethods 5 | def available_languages 6 | [:en] 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20221027165833_add_devise_two_factor_backupable_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddDeviseTwoFactorBackupableToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_users, :otp_backup_codes, :text, array: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/generators/fae/model_generator.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class ModelGenerator < Fae::BaseGenerator 3 | source_root ::File.expand_path('../templates', __FILE__) 4 | 5 | def go 6 | generate_model 7 | end 8 | 9 | end 10 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/cat.rb: -------------------------------------------------------------------------------- 1 | class Cat < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :aroma 5 | 6 | def fae_display_field 7 | name 8 | end 9 | 10 | def lives 11 | 9 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/milestones/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | section.content 5 | = fae_input f, :year 6 | = fae_input f, :description 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140905221727_create_people.rb: -------------------------------------------------------------------------------- 1 | class CreatePeople < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :people do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20221027165831_add_devise_two_factor_backupable_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddDeviseTwoFactorBackupableToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_users, :otp_backup_codes, :json 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20221111154088_add_mfa_enabeled_to_fae_options.rb: -------------------------------------------------------------------------------- 1 | class AddMfaEnabeledToFaeOptions < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_options, :site_mfa_enabled, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20230913144458_add_translate_language_to_fae_options.rb: -------------------------------------------------------------------------------- 1 | class AddTranslateLanguageToFaeOptions < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_options, :translate_language, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20240730180416_create_spirits.rb: -------------------------------------------------------------------------------- 1 | class CreateSpirits < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :spirits do |t| 4 | t.string :name 5 | 6 | t.timestamps 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20220202153607_add_position_to_deploy_hooks.rb: -------------------------------------------------------------------------------- 1 | class AddPositionToDeployHooks < ActiveRecord::Migration[5.2] 2 | def change 3 | add_column :fae_deploy_hooks, :position, :integer 4 | add_index :fae_deploy_hooks, :position 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/articles_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class ArticlesController < Fae::BaseController 3 | 4 | def index 5 | @article_categories = ArticleCategory.joins(:articles).uniq 6 | end 7 | 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/tables/_sticky.scss: -------------------------------------------------------------------------------- 1 | // sticky table header 2 | .sticky-table-header { 3 | @include stack($fae-nav-stack); 4 | position: fixed; 5 | top: 70px; 6 | display: none; 7 | border-top: 0; 8 | border-bottom: 0; 9 | } 10 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/aromas/table.html.slim: -------------------------------------------------------------------------------- 1 | = render 'fae/shared/nested_table', 2 | assoc: :aromas, 3 | parent_item: @parent_item, 4 | cols: [{ attr: :name, title: 'Pew Pew' }, :live, :image, { attr: :cat_size, title: 'Kitten Count' }], 5 | ordered: true -------------------------------------------------------------------------------- /spec/dummy/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /app/models/concerns/fae/authorization_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module AuthorizationConcern 3 | extend ActiveSupport::Concern 4 | module ClassMethods 5 | 6 | def access_map 7 | {} 8 | end 9 | 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/teams/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | section.content 5 | = fae_input f, :name 6 | = fae_input f, :city 7 | = fae_input f, :history 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20170714185443_add_seo_fields_to_release.rb: -------------------------------------------------------------------------------- 1 | class AddSeoFieldsToRelease < ActiveRecord::Migration[5.0] 2 | def change 3 | add_column :releases, :seo_title, :string 4 | add_column :releases, :seo_description, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20230908194606_add_french_canadian_to_wines.rb: -------------------------------------------------------------------------------- 1 | class AddFrenchCanadianToWines < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :wines, :name_frca, :string 4 | add_column :wines, :description_frca, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/cats/index.html.slim: -------------------------------------------------------------------------------- 1 | section.js-index-addedit-form 2 | == render 'fae/shared/index_header', nested: true 3 | 4 | = render 'fae/shared/nested_table', 5 | assoc: :cats, 6 | index: true, 7 | cols: [:name, :friendly, :description, :lives] -------------------------------------------------------------------------------- /spec/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | 7 | ActiveRecord::Migrator.migrations_paths = '../spec/dummy/db/migrate' -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150513172042_add_language_to_users.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20150513170213) 2 | class AddLanguageToUsers < ActiveRecord::Migration[4.2] 3 | def change 4 | add_column :fae_users, :language, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20140822224029_create_fae_roles.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeRoles < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_roles do |t| 4 | t.string :name 5 | t.integer :position 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/app/models/team.rb: -------------------------------------------------------------------------------- 1 | class Team < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | has_many :coaches 5 | has_many :players 6 | 7 | validates :name, presence: true 8 | 9 | def fae_display_field 10 | name 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/simple_form/translation_component.rb: -------------------------------------------------------------------------------- 1 | module Translation 2 | def translation 3 | if options[:translate].present? 4 | options[:translate].html_safe 5 | end 6 | end 7 | end 8 | 9 | SimpleForm.include_component(Translation) 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141009155137_add_on_env_to_people.rb: -------------------------------------------------------------------------------- 1 | class AddOnEnvToPeople < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :people, :on_stage, :boolean, default: true 4 | add_column :people, :on_prod, :boolean, default: false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20220128134117_rename_publish_hooks.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20220128133730) 2 | class RenamePublishHooks < ActiveRecord::Migration[5.2] 3 | def change 4 | rename_table :fae_publish_hooks, :fae_deploy_hooks 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20230913192940_add_language_fields_to_poly_thing.rb: -------------------------------------------------------------------------------- 1 | class AddLanguageFieldsToPolyThing < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :poly_things, :name_frca, :string 4 | rename_column :poly_things, :name, :name_en 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/events_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::EventsController < Fae::BaseController 2 | 3 | before_action do 4 | set_class_variables "special event" 5 | end 6 | 7 | private 8 | 9 | def use_pagination 10 | true 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/varietals/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= simple_form_for([:admin, @item]) do |f| %> 2 | <%= render 'fae/shared/form_header', header: @klass_name, f: f, item: @item %> 3 | 4 |
5 | <%= f.input :name %> 6 |
7 | <% end %> 8 | -------------------------------------------------------------------------------- /spec/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) 6 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141019043832_add_file_size_to_fae_images.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141013212642) 2 | class AddFileSizeToFaeImages < ActiveRecord::Migration[4.2] 3 | def change 4 | add_column :fae_images, :file_size, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/factories/fae/site_deploy_hook.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :fae_site_deploy_hook, class: 'Fae::SiteDeployHook' do 3 | sequence(:environment) { |n| "Env#{n}" } 4 | sequence(:url) { |n| "Url#{n}" } 5 | 6 | association :site, factory: :fae_site 7 | end 8 | end -------------------------------------------------------------------------------- /app/models/fae/deploy_hook.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class DeployHook < ApplicationRecord 3 | include Fae::BaseModelConcern 4 | 5 | acts_as_list add_new_at: :top 6 | default_scope { order(:position) } 7 | 8 | validates :url, :environment, presence: true 9 | end 10 | end -------------------------------------------------------------------------------- /spec/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/selling_points/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= simple_form_for([:admin, @item]) do |f| %> 2 | <%= render 'fae/shared/form_header', header: @klass_name, f: f, item: @item %> 3 | 4 |
5 | <%= f.input :name %> 6 |
7 | <% end %> 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160116014913_create_to_be_destroyeds.rb: -------------------------------------------------------------------------------- 1 | class CreateToBeDestroyeds < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :to_be_destroyeds do |t| 4 | t.string :name 5 | 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/controllers/fae/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class SessionsController < Devise::SessionsController 3 | 4 | protected 5 | 6 | def sign_in_params 7 | devise_parameter_sanitizer.permit(:sign_in, keys: [:otp_attempt]) 8 | end 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/sub_spirits_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class SubSpiritsController < Fae::NestedBaseController 3 | 4 | 5 | 6 | private 7 | 8 | def build_assets 9 | @item.build_tout_cta if @item.tout_cta.blank? 10 | end 11 | 12 | end 13 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/selling_point.rb: -------------------------------------------------------------------------------- 1 | class SellingPoint < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | name 6 | end 7 | 8 | has_many :release_selling_points 9 | has_many :releases, through: :release_selling_points 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/articles/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | main.content 5 | = fae_association f, :article_category 6 | 7 | = fae_input f, :title 8 | = fae_input f, :body 9 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141123214713_change_fae_page_to_fae_static_page.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141123080842) 2 | class ChangeFaePageToFaeStaticPage < ActiveRecord::Migration[4.2] 3 | def change 4 | rename_table :fae_pages, :fae_static_pages 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160414221357_create_jerseys.rb: -------------------------------------------------------------------------------- 1 | class CreateJerseys < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :jerseys do |t| 4 | t.string :name 5 | t.string :color 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /docs/topics/root_settings.md: -------------------------------------------------------------------------------- 1 | # Root Settings 2 | 3 | After your Fae admin has been created, you may log in and configure your settings in the "Root Settings" area. 4 | 5 | Here you can replace the default "My Fae Admin" with your own project's name, time zone, favicon, and visit site URLs. 6 | 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150305214314_create_teams.rb: -------------------------------------------------------------------------------- 1 | class CreateTeams < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :teams do |t| 4 | t.string :name 5 | t.string :city 6 | t.text :history 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/requests/fae/kaminari_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe 'kaminari settings' do 4 | 5 | it 'should load from Fae initializer' do 6 | super_admin_login 7 | get fae_path 8 | 9 | expect(Kaminari.config.default_per_page).to eq(5) 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /spec/services/netlify_api_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::NetlifyApi, type: :model do 4 | 5 | describe '#get_deploys' do 6 | it 'should return deploys' do 7 | expect(Fae::NetlifyApi.new().get_deploys).not_to be_nil 8 | end 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/controllers/static_pages_controller.rb: -------------------------------------------------------------------------------- 1 | module <%= options.namespace.capitalize %> 2 | class ContentBlocksController < Fae::StaticPagesController 3 | 4 | private 5 | 6 | def fae_pages 7 | [<%= "#{class_name}Page" %>] 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/app/models/acclaim.rb: -------------------------------------------------------------------------------- 1 | class Acclaim < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | has_fae_file :pdf 5 | 6 | def fae_display_field 7 | publication 8 | end 9 | 10 | def self.for_release_filter 11 | where('acclaims.score IS NOT NULL') 12 | end 13 | end -------------------------------------------------------------------------------- /spec/dummy/config/initializers/judge.rb: -------------------------------------------------------------------------------- 1 | Rails.application.config.to_prepare do 2 | Judge.configure do |config| 3 | expose Release, :name 4 | expose Fae::Site, :name 5 | expose ValidationTester, :slug, :second_slug 6 | 7 | config.use_association_name_for_validations true 8 | end 9 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141106223652_create_locations.rb: -------------------------------------------------------------------------------- 1 | class CreateLocations < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :locations do |t| 4 | t.string :name 5 | t.references :contact, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150213185222_add_date_fields_to_releases.rb: -------------------------------------------------------------------------------- 1 | class AddDateFieldsToReleases < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :releases, :release_date, :date 4 | add_column :releases, :show, :date 5 | add_column :releases, :hide, :date 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20220118192729_create_fae_publish_hooks.rb: -------------------------------------------------------------------------------- 1 | class CreateFaePublishHooks < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :fae_publish_hooks do |t| 4 | t.string :url 5 | t.string :environment, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/spirit.rb: -------------------------------------------------------------------------------- 1 | class Spirit < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | has_fae_cta :some_other_cta 5 | has_fae_cta :website_cta 6 | 7 | has_many :sub_spirits, dependent: :destroy 8 | 9 | def fae_display_field 10 | name 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141126180655_change_field_in_fae_text_fields.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141126180534) 2 | class ChangeFieldInFaeTextFields < ActiveRecord::Migration[4.2] 3 | def change 4 | rename_column :fae_text_fields, :attatched_as, :attached_as 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160413202106_create_milestones.rb: -------------------------------------------------------------------------------- 1 | class CreateMilestones < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :milestones do |t| 4 | t.integer :year 5 | t.string :description 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/views/devise/mailer/unlock_instructions.html.slim: -------------------------------------------------------------------------------- 1 | p Hello #{@resource.email}! 2 | p Your account has been locked due to an excessive number of unsuccessful sign in attempts. 3 | p Click the link below to unlock your account: 4 | p = link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @token) 5 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/people_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::PeopleController < Fae::BaseController 2 | 3 | private 4 | 5 | def build_assets 6 | @item.build_image if @item.respond_to?(:image) && @item.image.blank? 7 | end 8 | 9 | def use_pagination 10 | true 11 | end 12 | 13 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20230913145137_add_translate_language_to_fae_options.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20230913144458) 2 | class AddTranslateLanguageToFaeOptions < ActiveRecord::Migration[7.0] 3 | def change 4 | add_column :fae_options, :translate_language, :boolean 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/factories/fae/option_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_option, class: 'Fae::Option' do 4 | title 'My FINE Admin' 5 | singleton_guard 0 6 | time_zone 'Pacific Time (US & Canada)' 7 | live_url 'http://google.com' 8 | translate_language true 9 | end 10 | 11 | end -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/application.css: -------------------------------------------------------------------------------- 1 | /** 2 | *= require fae/vendor/reset 3 | *= require fae/vendor/chosen 4 | *= require fae/vendor/daterangepicker 5 | *= require fae/vendor/simplemde.min 6 | *= require fae/vendor/trumbowyg 7 | *= require fae/base 8 | *= require fae/simplemde_override 9 | */ 10 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/global.scss: -------------------------------------------------------------------------------- 1 | #dummy_content { 2 | margin: 30px auto; 3 | width: 500px; 4 | 5 | section { 6 | margin-bottom: 30px; 7 | } 8 | 9 | h2 { 10 | font-size: 30px; 11 | color: #2B2B2B; 12 | padding: 5px 0; 13 | font-weight: bold; 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /spec/dummy/app/models/sub_spirit.rb: -------------------------------------------------------------------------------- 1 | class SubSpirit < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | has_fae_cta :tout_cta 5 | 6 | belongs_to :spirit 7 | 8 | def fae_display_field 9 | name 10 | end 11 | 12 | def fae_nested_parent 13 | :spirit 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150909230658_create_cats.rb: -------------------------------------------------------------------------------- 1 | class CreateCats < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :cats do |t| 4 | t.string :name 5 | t.boolean :friendly 6 | t.text :description 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20170714052248_create_article_categories.rb: -------------------------------------------------------------------------------- 1 | class CreateArticleCategories < ActiveRecord::Migration[5.0] 2 | def change 3 | create_table :article_categories do |t| 4 | t.string :name 5 | t.integer :position 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20221111143428_create_sub_aromas.rb: -------------------------------------------------------------------------------- 1 | class CreateSubAromas < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :sub_aromas do |t| 4 | t.string :name, index: true 5 | t.integer :aroma_id, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/generators/fae/controller_generator.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class ControllerGenerator < Fae::BaseGenerator 3 | source_root ::File.expand_path('../templates', __FILE__) 4 | 5 | def go 6 | generate_controller_file 7 | generate_view_files 8 | add_route 9 | end 10 | 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/locations/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name, f: f, item: @item 3 | 4 | section.content 5 | = fae_input f, :name 6 | 7 | = fae_association f, :contact, collection: Person.all, include_blank: 'None' 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20220304182247_create_poly_things.rb: -------------------------------------------------------------------------------- 1 | class CreatePolyThings < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :poly_things do |t| 4 | t.string :name 5 | t.references :poly_thingable, polymorphic: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20240730200356_create_sub_spirits.rb: -------------------------------------------------------------------------------- 1 | class CreateSubSpirits < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :sub_spirits do |t| 4 | t.string :name, index: true 5 | t.integer :spirit_id, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141021161543_remove_faviconable_from_fae_image.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141021161414) 2 | class RemoveFaviconableFromFaeImage < ActiveRecord::Migration[4.2] 3 | def change 4 | remove_reference :fae_images, :faviconable, polymorphic: true, index: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/views/layouts/fae/error.html.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | html 3 | head 4 | title = @page_title 5 | meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" 6 | = stylesheet_link_tag "fae/application", media: "all" 7 | = csrf_meta_tags 8 | 9 | body.error-page 10 | section 11 | == yield 12 | -------------------------------------------------------------------------------- /config/initializers/kaminari_config.rb: -------------------------------------------------------------------------------- 1 | Kaminari.configure do |config| 2 | config.default_per_page = 25 3 | # config.max_per_page = nil 4 | config.window = 3 5 | # config.outer_window = 0 6 | config.left = 1 7 | config.right = 1 8 | # config.page_method_name = :page 9 | # config.param_name = :page 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20221027164701_add_devise_two_factor_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddDeviseTwoFactorToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_users, :otp_secret, :string 4 | add_column :fae_users, :consumed_timestep, :integer 5 | add_column :fae_users, :otp_required_for_login, :boolean 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20240705135709_create_fae_sites.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeSites < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_sites do |t| 4 | t.string :name, index: true 5 | t.string :netlify_site 6 | t.string :netlify_site_id 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20241101145909_create_open_ai_api_calls.rb: -------------------------------------------------------------------------------- 1 | class CreateOpenAiApiCalls < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_open_ai_api_calls do |t| 4 | t.string :call_type, index: true 5 | t.integer :tokens, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/content_blocks_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::ContentBlocksController < Fae::StaticPagesController 2 | 3 | private 4 | 5 | def fae_pages 6 | [HomePage, AboutUsPage, ContactUsPage, GlobalContentPage, PrivacyPage] 7 | end 8 | 9 | def use_pagination 10 | true 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/cats/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item], html: {multipart: true, novalidate: true, class: 'js-file-form'}, remote: true, data: {type: "html"}) do |f| 2 | = fae_input f, :name 3 | = fae_input f, :friendly 4 | = fae_input f, :description 5 | = f.hidden_field :aroma_id 6 | 7 | = f.submit -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140905223641_create_event_release.rb: -------------------------------------------------------------------------------- 1 | class CreateEventRelease < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :event_releases do |t| 4 | t.references :release, index: true 5 | t.references :event, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150213172238_create_aromas.rb: -------------------------------------------------------------------------------- 1 | class CreateAromas < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :aromas do |t| 4 | t.string :name 5 | t.text :description 6 | t.integer :position 7 | t.boolean :live 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160815162731_create_release_notes.rb: -------------------------------------------------------------------------------- 1 | class CreateReleaseNotes < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :release_notes do |t| 4 | t.string :title 5 | t.text :body 6 | t.integer :position 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20220202153906_add_position_to_deploy_hooks.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20220202153607) 2 | class AddPositionToDeployHooks < ActiveRecord::Migration[5.2] 3 | def change 4 | add_column :fae_deploy_hooks, :position, :integer 5 | add_index :fae_deploy_hooks, :position 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_file_form_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_file_form' do 4 | 5 | scenario 'should display uploader', js: true do 6 | admin_login 7 | visit new_admin_release_path 8 | 9 | expect(page).to have_css('.release_label_pdf_asset button.button') 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/aromas_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class AromasController < Fae::NestedBaseController 3 | 4 | private 5 | 6 | def build_assets 7 | @item.build_image if @item.image.blank? 8 | end 9 | 10 | def use_pagination 11 | true 12 | end 13 | 14 | 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/requests/fae/devise_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe 'devise settings' do 4 | 5 | it 'should load from Fae initializer' do 6 | super_admin_login 7 | get fae_path 8 | 9 | expect(Devise.secret_key).to_not eq(nil) 10 | expect(Devise.mailer_sender).to eq('test@test.com') 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/models/concerns/fae/assets_validatable.rb: -------------------------------------------------------------------------------- 1 | module Fae::AssetsValidatable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | validate :asset_exists 6 | end 7 | 8 | def asset_exists 9 | errors.add(:asset, "#{self.class.to_s.gsub('Fae::','')} can't be empty") if required && asset.blank? 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/assets/fae.js: -------------------------------------------------------------------------------- 1 | // This file is compiled into fae/application.js 2 | // use this as another manifest file if you have a lot of javascript to add 3 | // or just add your javascript directly to this file 4 | 5 | // Uncomment the following line if you want to use Trumbowyg HTML Editor 6 | // //= require fae/vendor/trumbowyg -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/spirits_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class SpiritsController < Fae::BaseController 3 | 4 | private 5 | 6 | def build_assets 7 | @item.build_website_cta if @item.website_cta.blank? 8 | @item.build_some_other_cta if @item.some_other_cta.blank? 9 | end 10 | 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/models/event.rb: -------------------------------------------------------------------------------- 1 | class Event < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | name 6 | end 7 | 8 | validates :city, inclusion: ["Los Angeles", "San Francisco", "Portland"]; 9 | validates :name, presence: true 10 | 11 | belongs_to :release 12 | has_many :people 13 | end -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/players/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @parent_item, @item]) do |f| 2 | == render 'fae/shared/form_header', header: "New #{@parent_item.name} Player" 3 | 4 | section.content 5 | = fae_input f, :first_name 6 | = fae_input f, :last_name 7 | = fae_input f, :number 8 | = fae_input f, :bio 9 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20221027164428_add_devise_two_factor_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddDeviseTwoFactorToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :fae_users, :otp_secret, :string 4 | add_column :fae_users, :consumed_timestep, :integer 5 | add_column :fae_users, :otp_required_for_login, :boolean 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20241101145909_create_open_ai_api_calls.fae.rb: -------------------------------------------------------------------------------- 1 | class CreateOpenAiApiCalls < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_open_ai_api_calls do |t| 4 | t.string :call_type, index: true 5 | t.integer :tokens, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/models/fae/text_area.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class TextArea < ActiveRecord::Base 3 | 4 | include Fae::BaseModelConcern 5 | include Fae::TextAreaConcern 6 | include Fae::PageValidatable 7 | 8 | belongs_to :contentable, polymorphic: true, touch: true 9 | 10 | def readonly? 11 | false 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/models/fae/text_field.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class TextField < ActiveRecord::Base 3 | 4 | include Fae::BaseModelConcern 5 | include Fae::TextFieldConcern 6 | include Fae::PageValidatable 7 | 8 | belongs_to :contentable, polymorphic: true, touch: true 9 | 10 | def readonly? 11 | false 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/app/models/article_category.rb: -------------------------------------------------------------------------------- 1 | class ArticleCategory < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | acts_as_list add_new_at: :top 5 | default_scope { order(:position) } 6 | 7 | has_many :articles 8 | 9 | validates :name, presence: true 10 | 11 | def fae_display_field 12 | name 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141019043830_create_fae_roles.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20140822224029) 2 | class CreateFaeRoles < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_roles do |t| 5 | t.string :name 6 | t.integer :position 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/helpers/fae/qr_code_helper.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module QrCodeHelper 3 | def qr_code_as_svg(uri) 4 | RQRCode::QRCode.new(uri).as_svg( 5 | offset: 0, 6 | color: '000', 7 | shape_rendering: 'crispEdges', 8 | module_size: 4, 9 | standalone: true 10 | ).html_safe 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /docs/tutorials/landing_page.md: -------------------------------------------------------------------------------- 1 | # Overriding The Landing Page 2 | 3 | If you want to ignore the default dashboard and make one of your views the landing page you can add a redirect route in your Fae namespace. 4 | 5 | `config/routes.rb` 6 | ```ruby 7 | # ... 8 | namespace :admin do 9 | get '/', to: redirect('/admin/people') 10 | # ... 11 | ``` 12 | --- -------------------------------------------------------------------------------- /lib/fae/concerns/models/base.rb: -------------------------------------------------------------------------------- 1 | # TODO - can we remove this/do we need backwards compaitibility? 2 | 3 | # moved to app/models/concerns/fae/base_model_concern.rb 4 | # keep for backwards compatibility 5 | module Fae::Concerns::Models::Base 6 | extend ActiveSupport::Concern 7 | included do 8 | include Fae::BaseModelConcern 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_suffix_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_suffix' do 4 | 5 | scenario 'should have suffix' do 6 | admin_login 7 | visit new_admin_release_path 8 | 9 | within('div.release_weight .input-symbol--suffix') do 10 | expect(page).to have_content('lbs') 11 | end 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/views/index_nested.html.slim: -------------------------------------------------------------------------------- 1 | section.js-index-addedit-form 2 | == render 'fae/shared/index_header', nested: true 3 | 4 | == render 'fae/shared/nested_table', 5 | assoc: :<%= file_name.pluralize %>, 6 | index: true, 7 | ordered: <%= @has_position %>, 8 | cols: [<%= @form_attrs.map {|attr| ":#{attr}"}.join(', ') %>] 9 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20151013225140_create_winemakers.rb: -------------------------------------------------------------------------------- 1 | class CreateWinemakers < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :winemakers do |t| 4 | t.string :name 5 | t.integer :position 6 | t.references :wine, index: true, foreign_key: true 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/file_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module FileConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::File instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::File class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/image_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module ImageConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::Image instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::Image class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/role_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module RoleConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::Role instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::Role class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/user_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module UserConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::User instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::User class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140902223650_create_wine.rb: -------------------------------------------------------------------------------- 1 | class CreateWine < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :wines do |t| 4 | t.string :name 5 | 6 | t.boolean :on_stage, default: true 7 | t.boolean :on_prod, default: false 8 | t.integer :position 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140902230910_create_release_selling_point.rb: -------------------------------------------------------------------------------- 1 | class CreateReleaseSellingPoint < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :release_selling_points do |t| 4 | t.references :release 5 | t.references :selling_point 6 | t.integer :position 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_prefix_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_prefix' do 4 | 5 | scenario 'should have prefix and placeholder' do 6 | admin_login 7 | visit new_admin_release_path 8 | 9 | within('div.release_price .input-symbol--prefix') do 10 | expect(page).to have_content('$') 11 | end 12 | end 13 | 14 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/option_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module OptionConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::Option instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::Option class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141120052810_add_required_to_images_and_files.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141120051309) 2 | class AddRequiredToImagesAndFiles < ActiveRecord::Migration[4.2] 3 | def change 4 | add_column :fae_files, :required, :boolean, default: false 5 | add_column :fae_images, :required, :boolean, default: false 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20170714052711_create_articles.rb: -------------------------------------------------------------------------------- 1 | class CreateArticles < ActiveRecord::Migration[5.0] 2 | def change 3 | create_table :articles do |t| 4 | t.string :title 5 | t.text :body 6 | t.integer :position 7 | t.references :article_category, foreign_key: true 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20170714184925_create_beers.rb: -------------------------------------------------------------------------------- 1 | class CreateBeers < ActiveRecord::Migration[5.0] 2 | def change 3 | create_table :beers do |t| 4 | t.string :name 5 | t.string :seo_title 6 | t.string :seo_description 7 | t.boolean :on_stage 8 | t.boolean :on_prod 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/tables/_image.scss: -------------------------------------------------------------------------------- 1 | th { 2 | &.-image { 3 | width: 120px; 4 | } 5 | 6 | &.-thumb { 7 | width: 150px; 8 | } 9 | } 10 | 11 | .image-mat { 12 | width: 100px; 13 | background-color: white; 14 | 15 | img { 16 | display: block; 17 | max-width: 100%; 18 | height: auto; 19 | margin: auto; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/models/fae/seo_set.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class SeoSet < ActiveRecord::Base 3 | include Fae::BaseModelConcern 4 | include Fae::SeoSetConcern 5 | 6 | has_fae_image :social_media_image 7 | belongs_to :seo_setable, polymorphic: true, touch: true, optional: true 8 | 9 | def fae_display_field 10 | seo_title 11 | end 12 | 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20190925153222_create_fae_form_managers.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeFormManagers < ActiveRecord::Migration[5.2] 2 | def change 3 | create_table :fae_form_managers do |t| 4 | t.string :form_manager_model_name, index: true 5 | t.integer :form_manager_model_id, index: true 6 | t.text :fields 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/winemakers/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item], html: {multipart: true, novalidate: true, class: 'js-file-form'}, remote: true, data: {type: "html"}) do |f| 2 | 3 | = fae_input f, :name 4 | = fae_image_form f, :winemaker_image 5 | = f.hidden_field :wine_id 6 | = f.hidden_field :region_type, value: @item.region_type 7 | 8 | = f.submit -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150305215553_create_players.rb: -------------------------------------------------------------------------------- 1 | class CreatePlayers < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :players do |t| 4 | t.string :first_name 5 | t.string :last_name 6 | t.string :number 7 | t.text :bio 8 | t.references :team, index: true 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150305215901_create_coaches.rb: -------------------------------------------------------------------------------- 1 | class CreateCoaches < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :coaches do |t| 4 | t.string :first_name 5 | t.string :last_name 6 | t.string :role 7 | t.text :bio 8 | t.references :team, index: true 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/text_area_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module TextAreaConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::TextArea instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::TextArea class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/coaches/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @parent_item, @item]) do |f| 2 | == render 'fae/shared/form_header', header: "New #{@parent_item.name} Coach" 3 | 4 | section.content 5 | = fae_input f, :first_name 6 | = fae_input f, :last_name 7 | = fae_input f, :role 8 | = fae_input f, :bio 9 | = fae_image_form f, :image 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140902225712_create_varietal.rb: -------------------------------------------------------------------------------- 1 | class CreateVarietal < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :varietals do |t| 4 | t.string :name 5 | 6 | t.boolean :on_stage, default: true 7 | t.boolean :on_prod, default: false 8 | t.integer :position 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20220118195219_create_fae_publish_hooks.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20220118192729) 2 | class CreateFaePublishHooks < ActiveRecord::Migration[5.2] 3 | def change 4 | create_table :fae_publish_hooks do |t| 5 | t.string :url 6 | t.string :environment, index: true 7 | 8 | t.timestamps 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /app/inputs/symbol_input.rb: -------------------------------------------------------------------------------- 1 | class SymbolInput < SimpleForm::Inputs::Base 2 | def input(wrapper_options) 3 | "#{@builder.text_field(attribute_name, "data-validate" => input_html_options['data-validate'], placeholder: input_html_options[:placeholder])}".html_safe 4 | end 5 | end -------------------------------------------------------------------------------- /app/views/kaminari/fae/_gap.html.slim: -------------------------------------------------------------------------------- 1 | / Non-link tag that stands for skipped pages... 2 | / - available local variables 3 | / current_page: a page object for the currently displayed page 4 | / total_pages: total number of pages 5 | / per_page: number of items to fetch per page 6 | / remote: data-remote 7 | span.page.gap 8 | == t('views.pagination.truncate').html_safe 9 | -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/text_field_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module TextFieldConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::TextField instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::TextField class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/tables/_alt_text_manager.scss: -------------------------------------------------------------------------------- 1 | .js-alt-text-label { 2 | margin-bottom: 10px; 3 | } 4 | 5 | .js-alt-text-input { 6 | display:none; 7 | } 8 | 9 | .js-alt-text-input { 10 | min-width: 100px; 11 | } 12 | 13 | .edit-alt { 14 | margin: 0 10px 5px 0; 15 | } 16 | 17 | @media (min-width: 768px) { 18 | th.-alt-text { 19 | width: 300px; 20 | } 21 | } -------------------------------------------------------------------------------- /db/migrate/20240708133519_create_fae_site_deploy_hooks.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeSiteDeployHooks < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_site_deploy_hooks do |t| 4 | t.string :environment 5 | t.string :url 6 | t.integer :position, index: true 7 | t.integer :site_id, index: true 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/fae/static_page_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module StaticPageConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::StaticPage instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::StaticPage class: what?' 12 | end 13 | end 14 | 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/person.rb: -------------------------------------------------------------------------------- 1 | class Person < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | def fae_display_field 5 | name 6 | end 7 | 8 | has_one :image, as: :imageable, class_name: '::Fae::Image', dependent: :destroy 9 | accepts_nested_attributes_for :image, allow_destroy: true 10 | 11 | validates_presence_of :name 12 | 13 | belongs_to :event 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/app/models/sub_aroma.rb: -------------------------------------------------------------------------------- 1 | class SubAroma < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :aroma, touch: true 5 | 6 | def fae_nested_parent 7 | :aroma 8 | end 9 | 10 | def fae_display_field 11 | name 12 | end 13 | 14 | class << self 15 | 16 | def for_fae_index 17 | order(:name) 18 | end 19 | 20 | end 21 | 22 | end 23 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140902231710_create_selling_points.rb: -------------------------------------------------------------------------------- 1 | class CreateSellingPoints < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :selling_points do |t| 4 | t.string :name 5 | 6 | t.boolean :on_stage, default: true 7 | t.boolean :on_prod, default: false 8 | t.integer :position 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140905221522_create_events.rb: -------------------------------------------------------------------------------- 1 | class CreateEvents < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :events do |t| 4 | t.string :name 5 | t.date :start_date 6 | t.date :end_date 7 | t.string :event_type 8 | t.string :city 9 | 10 | t.integer :people_id 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/dummy/db/seeds.rb: -------------------------------------------------------------------------------- 1 | (1..4).each do |i| 2 | 3 | Wine.create(name_en: "wine #{i}") 4 | 5 | Acclaim.create(score: "#{100-(2*1)}", publication: "The #{i.ordinalize} publication for an acclaim", description: "description"*i ) 6 | 7 | Varietal.create(name: "varietal #{i}") 8 | 9 | SellingPoint.create(name: "selling point #{i}") 10 | 11 | Person.create(name: "host ##{i}") 12 | 13 | end -------------------------------------------------------------------------------- /spec/features/custom_assets_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'Custom assets' do 4 | 5 | scenario 'should allow custom JS from main app', js: true do 6 | FactoryBot.create(:fae_role, name: 'super admin') 7 | visit fae.root_path 8 | # custom JS adds 'test-class' to '.login-body' 9 | expect(page).to have_selector('.login-body.test-class') 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20240705141148_create_fae_sites.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20240705135709) 2 | class CreateFaeSites < ActiveRecord::Migration[7.0] 3 | def change 4 | create_table :fae_sites do |t| 5 | t.string :name, index: true 6 | t.string :netlify_site 7 | t.string :netlify_site_id 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20240708133519_create_fae_site_deploy_hooks.fae.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeSiteDeployHooks < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_site_deploy_hooks do |t| 4 | t.string :environment 5 | t.string :url 6 | t.integer :position, index: true 7 | t.integer :site_id, index: true 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/acclaims_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::AcclaimsController < Fae::BaseController 2 | before_action do 3 | # sets custom titles 4 | set_class_variables 'Reviews' 5 | end 6 | 7 | def build_assets 8 | @item.build_pdf if @item.respond_to?(:pdf) && @item.pdf.blank? 9 | end 10 | 11 | private 12 | 13 | def use_pagination 14 | true 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/people/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= simple_form_for([:admin, @item]) do |f| %> 2 | <%= render 'fae/shared/form_header', header: @klass_name %> 3 | 4 |
5 | <%= fae_input f, :name, {helper_text: "this is some helper text"} %> 6 | <%= fae_input f, :on_prod, disabled: true %> 7 | 8 | <%= fae_image_form f, :image %> 9 |
10 | <% end %> 11 | -------------------------------------------------------------------------------- /db/migrate/20240730152108_create_fae_ctas.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeCtas < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_ctas do |t| 4 | t.string :cta_label 5 | t.text :cta_link 6 | t.string :cta_alt_text 7 | t.references :ctaable, polymorphic: true, index: true 8 | t.string :attached_as, index: true 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20141021184311_create_fae_pages.rb: -------------------------------------------------------------------------------- 1 | class CreateFaePages < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_static_pages do |t| 4 | t.string :title 5 | t.integer :position, default: 0 6 | t.boolean :on_stage, default: true 7 | t.boolean :on_prod, default: false 8 | t.string :slug, index: true 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/app/models/beer.rb: -------------------------------------------------------------------------------- 1 | class Beer < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | has_fae_image :image 5 | has_fae_seo_set :seo 6 | has_fae_cta :test_cta 7 | has_many :poly_things, as: :poly_thingable 8 | 9 | validates :name, presence: true 10 | 11 | def fae_display_field 12 | name 13 | end 14 | 15 | def fae_redirect_to_form_on_create 16 | true 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/forms/_textarea.scss: -------------------------------------------------------------------------------- 1 | textarea { 2 | @include transition(border-color .2s); 3 | padding: 10px 15px 0; 4 | border: 1px solid $c-border; 5 | font-size: 14px; 6 | min-height: 125px; 7 | width: 100%; 8 | min-width: 223px; 9 | font-family: $f-content; 10 | outline: none; 11 | border-radius: 2px; 12 | 13 | &:focus { 14 | border-color: $c-focus-border; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/pages/_home.scss: -------------------------------------------------------------------------------- 1 | .tutorial { 2 | div { 3 | background-image: image-url('fae/tutorial_model_location.png'); 4 | height: 11em; 5 | margin-left: 2em; 6 | background-size: 60%; 7 | background-position: left; 8 | background-repeat: no-repeat; 9 | } 10 | 11 | @media (max-width: 800px){ 12 | height: 8em; 13 | } 14 | 15 | p { 16 | margin: 2em; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/views/devise/unlocks/new.html.slim: -------------------------------------------------------------------------------- 1 | .login-form 2 | h2 Resend unlock instructions 3 | 4 | = simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, id: 'login_form' }) do |f| 5 | 6 | = f.input :email, :required => true, :autofocus => true 7 | 8 | .login-form-actions 9 | = f.button :submit, "Resend unlock instructions", class: "login-form-actions-submit" 10 | -------------------------------------------------------------------------------- /lib/components/translate_component.rb: -------------------------------------------------------------------------------- 1 | module TranslateComponent 2 | # To avoid deprecation warning, you need to make the wrapper_options explicit 3 | # even when they won't be used. 4 | def translate(wrapper_options = nil) 5 | @translate ||= begin 6 | options[:translate].to_s.html_safe if options[:translate].present? 7 | end 8 | end 9 | end 10 | 11 | SimpleForm.include_component(TranslateComponent) 12 | -------------------------------------------------------------------------------- /app/assets/javascripts/fae/admin.js.erb: -------------------------------------------------------------------------------- 1 | // This file is named Admin because child-project asset folders should have a fae.js file to override or add functionality to the admin 2 | /** 3 | * Fae 4 | * @module Fae 5 | * @namespace Fae 6 | */ 7 | var Fae = { 8 | path: '<%= Rails.application.routes.url_helpers.fae_path %>', 9 | }; 10 | 11 | judge.enginePath = '<%= Rails.application.routes.url_helpers.fae_path %>/judge'; 12 | -------------------------------------------------------------------------------- /app/views/devise/mailer/reset_password_instructions.html.slim: -------------------------------------------------------------------------------- 1 | p Hello #{@resource.email}! 2 | p Someone has requested a link to change your password. You can do this through the link below. 3 | p = link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @token) 4 | p If you didn't request this, please ignore this email. 5 | p Your password won't change until you access the link above and create a new one. 6 | -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_image_form_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_image_form' do 4 | 5 | scenario 'should display updloader with alt by default', js: true do 6 | admin_login 7 | visit new_admin_release_path 8 | 9 | expect(page).to have_css('.release_bottle_shot_asset button.button') 10 | expect(page).to have_css('#release_bottle_shot_attributes_alt') 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /spec/requests/fae/changes_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe 'before_filter' do 4 | 5 | it 'should update Fae::Change.current_user with current_user' do 6 | user = create_super_user 7 | post fae.user_session_path, params: { user: { 'email' => user.email, 'password' => user.password } } 8 | 9 | get fae.root_path 10 | 11 | expect(Fae::Change.current_user).to eq(user.id) 12 | end 13 | 14 | end -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/beers_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class BeersController < Fae::BaseController 3 | 4 | private 5 | 6 | def build_assets 7 | @item.build_test_cta if @item.test_cta.blank? 8 | @item.build_image if @item.image.blank? 9 | if @item.seo.blank? 10 | @item.build_seo 11 | @item.seo.build_social_media_image 12 | end 13 | end 14 | 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/globals/_icons.scss: -------------------------------------------------------------------------------- 1 | [class^="icon-"], [class*=" icon-"] { 2 | @include icon-stuff; 3 | } 4 | 5 | // Adding more? Use this handy find/replace regex 6 | // \.icon\-([\w\-]+):before \{\n\s*content:\s\"\\([\w\d]+)\";\n\} 7 | // '$1': '$2', 8 | 9 | .icon { 10 | @each $icon in $fae-required-icons { 11 | &-#{nth($icon, 1)}:before { 12 | content: fae-icon(nth($icon, 1)); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/models/fae/site_deploy_hook.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class SiteDeployHook < ApplicationRecord 3 | include Fae::BaseModelConcern 4 | 5 | belongs_to :site, class_name: 'Fae::Site' 6 | 7 | acts_as_list add_new_at: :top, scope: :site 8 | default_scope { order(:position) } 9 | 10 | validates :url, :environment, presence: true 11 | 12 | def fae_nested_parent 13 | :site 14 | end 15 | 16 | end 17 | end -------------------------------------------------------------------------------- /db/migrate/20221118161833_create_fae_seo_sets.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeSeoSets < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :fae_seo_sets do |t| 4 | t.string :seo_title 5 | t.text :seo_description 6 | t.string :social_media_title 7 | t.text :social_media_description 8 | t.references :seo_setable, polymorphic: true, index: true 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/components/generate_alt_component.rb: -------------------------------------------------------------------------------- 1 | module GenerateAltComponent 2 | # To avoid deprecation warning, you need to make the wrapper_options explicit 3 | # even when they won't be used. 4 | def generate_alt(wrapper_options = nil) 5 | @generate_alt ||= begin 6 | options[:generate_alt].to_s.html_safe if options[:generate_alt].present? 7 | end 8 | end 9 | end 10 | 11 | SimpleForm.include_component(GenerateAltComponent) -------------------------------------------------------------------------------- /spec/dummy/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Precompile additional assets. 7 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 8 | # Rails.application.config.assets.precompile += %w( search.js ) 9 | -------------------------------------------------------------------------------- /app/models/fae/cta.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class Cta < ActiveRecord::Base 3 | include Fae::BaseModelConcern 4 | include Fae::CtaConcern 5 | 6 | # Rails' inflector does not attempt to pluralize 'cta' for the table name 7 | self.table_name = 'fae_ctas' 8 | 9 | belongs_to :ctaable, polymorphic: true, touch: true, optional: true 10 | 11 | def fae_display_field 12 | cta_label 13 | end 14 | 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/models/fae/site.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class Site < ApplicationRecord 3 | include Fae::BaseModelConcern 4 | 5 | default_scope { order(:name) } 6 | 7 | has_many :site_deploy_hooks, dependent: :destroy, class_name: 'Fae::SiteDeployHook' 8 | 9 | validates :name, presence: true 10 | validates :netlify_site, :netlify_site_id, presence: true 11 | 12 | def fae_display_field 13 | name 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/controllers/concerns/fae/application_controller_concern.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | module ApplicationControllerConcern 3 | extend ActiveSupport::Concern 4 | 5 | def instance_says_what 6 | 'Fae::ApplicationController instance: what?' 7 | end 8 | 9 | module ClassMethods 10 | def class_says_what 11 | 'Fae::ApplicationController class: what?' 12 | end 13 | end 14 | 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/models/fae/role.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class Role < ActiveRecord::Base 3 | 4 | include Fae::BaseModelConcern 5 | include Fae::RoleConcern 6 | 7 | has_many :users 8 | 9 | acts_as_list add_new_at: :bottom 10 | default_scope { order(Arel.sql('-position DESC')) } 11 | 12 | scope :public_roles, -> {where.not(name: 'super admin')} 13 | 14 | def fae_tracker_blacklist 15 | 'all' 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/_errors-bar.scss: -------------------------------------------------------------------------------- 1 | .errors-bar-wrapper { 2 | border-color: $c-error-content; 3 | background: $c-error-bg; 4 | color: $c-error-content; 5 | width: 100%; 6 | padding: 20px; 7 | display: none; 8 | 9 | .errors-bar { 10 | display: flex; 11 | margin-top: 20px; 12 | flex-direction: column; 13 | } 14 | 15 | .error-jump-link { 16 | margin-right: 20px; 17 | font-size: 14px; 18 | } 19 | } -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141021184641_create_fae_pages.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141021184311) 2 | class CreateFaePages < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_pages do |t| 5 | t.string :title 6 | t.integer :position, default: 0 7 | t.boolean :on_stage, default: true 8 | t.boolean :on_prod, default: false 9 | 10 | t.timestamps 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20191010130931_create_fae_form_managers.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20190925153222) 2 | class CreateFaeFormManagers < ActiveRecord::Migration[5.2] 3 | def change 4 | create_table :fae_form_managers do |t| 5 | t.string :form_manager_model_name, index: true 6 | t.integer :form_manager_model_id, index: true 7 | t.text :fields 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/generators/fae/scaffold_generator.rb: -------------------------------------------------------------------------------- 1 | require_relative 'base_generator' 2 | module Fae 3 | class ScaffoldGenerator < Fae::BaseGenerator 4 | source_root ::File.expand_path('../templates', __FILE__) 5 | 6 | def go 7 | generate_model 8 | generate_graphql_type 9 | generate_controller_file 10 | generate_view_files 11 | add_route 12 | inject_nav_item 13 | inject_livable 14 | end 15 | 16 | end 17 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/article.rb: -------------------------------------------------------------------------------- 1 | class Article < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | acts_as_list add_new_at: :top 5 | default_scope { order(:position) } 6 | 7 | belongs_to :article_category 8 | 9 | validates :title, presence: true 10 | validates :article_category, presence: true 11 | 12 | def fae_display_field 13 | title 14 | end 15 | 16 | def fae_redirect_to_form_on_create 17 | true 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/acclaims/_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= simple_form_for([:admin, @item]) do |f| %> 2 | <%= render 'fae/shared/form_header', header: @klass_name, f: f, item: @item %> 3 | 4 |
5 | <%= f.input :score %> 6 | <%= f.input :publication %> 7 | <%= fae_datepicker f, :publication_date %> 8 | <%= fae_file_form f, :pdf %> 9 | <%= fae_input f, :description, markdown: true %> 10 |
11 | <% end %> 12 | -------------------------------------------------------------------------------- /db/migrate/20141017194616_create_fae_options.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeOptions < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_options do |t| 4 | t.string :title 5 | t.string :time_zone 6 | t.string :colorway 7 | t.string :stage_url 8 | t.string :live_url 9 | t.integer :singleton_guard 10 | 11 | t.timestamps 12 | end 13 | 14 | add_index :fae_options, :singleton_guard, unique: true 15 | end 16 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/poly_thing.rb: -------------------------------------------------------------------------------- 1 | class PolyThing < ApplicationRecord 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :poly_thingable, polymorphic: true 5 | 6 | validates :name_en, presence: true 7 | 8 | def fae_nested_parent 9 | :poly_thingable 10 | end 11 | 12 | def fae_display_field 13 | name 14 | end 15 | 16 | class << self 17 | 18 | def for_fae_index 19 | order(:name) 20 | end 21 | 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Existing Docker Compose", 3 | "dockerComposeFile": ["../docker-compose.yml", "../docker-compose.override.yml"], 4 | "service": "app", 5 | "workspaceFolder": "/app", 6 | "forwardPorts": [3000, 3307], 7 | "customizations": { 8 | "vscode": { 9 | "extensions": [ 10 | "Shopify.ruby-lsp", 11 | "rubocop.vscode-rubocop", 12 | "GraphQL.vscode-graphql" 13 | ] 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /app/controllers/fae/site_deploy_hooks_controller.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class SiteDeployHooksController < Fae::NestedBaseController 3 | 4 | 5 | private 6 | 7 | def table_template_path 8 | "fae/site_deploy_hooks/_table" 9 | end 10 | 11 | def set_class_variables 12 | @klass_name = params[:controller].split('/').last 13 | @klass = Fae::SiteDeployHook 14 | @klass_singular = @klass_name.singularize 15 | end 16 | 17 | end 18 | end -------------------------------------------------------------------------------- /spec/dummy/app/models/player.rb: -------------------------------------------------------------------------------- 1 | class Player < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :team 5 | 6 | validates :first_name, presence: true 7 | validates :last_name, presence: true 8 | validates :team_id, presence: true 9 | 10 | def fae_display_field 11 | full_name 12 | end 13 | 14 | def fae_parent 15 | team 16 | end 17 | 18 | def full_name 19 | "#{first_name} #{last_name}" 20 | end 21 | 22 | end 23 | -------------------------------------------------------------------------------- /spec/dummy/app/models/release_note.rb: -------------------------------------------------------------------------------- 1 | class ReleaseNote < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :release, touch: true 5 | 6 | def fae_nested_parent 7 | :release 8 | end 9 | 10 | def fae_display_field 11 | title 12 | end 13 | 14 | def fae_tracker_parent 15 | # has to be an AR object 16 | release 17 | end 18 | 19 | acts_as_list add_new_at: :top 20 | default_scope { order(:position) } 21 | 22 | end 23 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140902233505_create_acclaim.rb: -------------------------------------------------------------------------------- 1 | class CreateAcclaim < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :acclaims do |t| 4 | t.string :score 5 | t.string :publication 6 | t.text :description 7 | 8 | t.boolean :on_stage, default: true 9 | t.boolean :on_prod, default: false 10 | t.integer :position 11 | 12 | t.integer :release_id 13 | t.timestamps 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/views/kaminari/fae/_next_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link to the "Next" page 2 | / - available local variables 3 | / url: url to the next page 4 | / current_page: a page object for the currently displayed page 5 | / total_pages: total number of pages 6 | / per_page: number of items to fetch per page 7 | / remote: data-remote 8 | span.next 9 | a href=url rel="next" remote=remote data-page=(current_page + 1) = t('views.pagination.next').html_safe 10 | -------------------------------------------------------------------------------- /app/views/fae/deploy_hooks/_form.html.slim: -------------------------------------------------------------------------------- 1 | ruby: 2 | form_options = { 3 | html: { 4 | multipart: true, 5 | novalidate: true, 6 | class: 'js-file-form', 7 | remote: true, 8 | data: { 9 | type: "html" 10 | } 11 | } 12 | } 13 | = simple_form_for(@deploy_hook, form_options) do |f| 14 | = fae_input f, :environment 15 | = fae_input f, :url, label: 'URL' 16 | 17 | = f.submit 18 | = button_tag 'Cancel', type: 'button', class: 'js-cancel-nested cancel-nested-button' -------------------------------------------------------------------------------- /app/views/kaminari/fae/_prev_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link to the "Previous" page 2 | / - available local variables 3 | / url: url to the previous page 4 | / current_page: a page object for the currently displayed page 5 | / total_pages: total number of pages 6 | / per_page: number of items to fetch per page 7 | / remote: data-remote 8 | span.prev 9 | a href=url rel="prev" remote=remote data-page=(current_page - 1) = t('views.pagination.previous').html_safe 10 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20240730152108_create_fae_ctas.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20240730152108) 2 | class CreateFaeCtas < ActiveRecord::Migration[7.0] 3 | def change 4 | create_table :fae_ctas do |t| 5 | t.string :cta_label 6 | t.text :cta_link 7 | t.string :cta_alt_text 8 | t.references :ctaable, polymorphic: true, index: true 9 | t.string :attached_as, index: true 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/models/pages_model.rb: -------------------------------------------------------------------------------- 1 | class <%= class_name %>Page < Fae::StaticPage 2 | 3 | @slug = '<%= file_name %>' 4 | 5 | # required to set the has_one associations, Fae::StaticPage will build these associations dynamically 6 | def self.fae_fields 7 | { 8 | <% @attributes.each_with_index do |(attr, type), index| -%> 9 | <%= attr %>: { type: <%= type %> }<%= index + 1 != @attributes.length ? ",\n" : "\n" -%> 10 | <% end -%> 11 | } 12 | end 13 | 14 | end 15 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/winemakers/table.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/nested_table', 2 | assoc: @item.association_type, 3 | parent_item: @parent_item, 4 | assoc_name: 'winemakers', 5 | assoc_name_singular: 'winemaker', 6 | cols: [:name, :winemaker_image, :table_image], 7 | ordered: true, 8 | edit_column: true, 9 | new_path: "/admin/winemakers/new?region_type=#{@item.region_type}", 10 | header: 'Winemaker', 11 | title: "#{@item.association_type.to_s.humanize.titleize}" 12 | -------------------------------------------------------------------------------- /spec/requests/content_blocks_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe 'content_blocks#index' do 4 | 5 | it 'should return found' do 6 | admin_login 7 | get fae.pages_path 8 | 9 | expect(response.status).to eq(200) 10 | end 11 | 12 | end 13 | 14 | describe 'content_blocks#edit' do 15 | 16 | it 'should return found' do 17 | admin_login 18 | get fae.edit_content_block_path('home') 19 | 20 | expect(response.status).to eq(200) 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /app/views/devise/registrations/new.html.slim: -------------------------------------------------------------------------------- 1 | h2 Sign up 2 | 3 | = simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| 4 | 5 | = f.error_notification 6 | 7 | .form-inputs 8 | = f.input :email, :required => true, :autofocus => true 9 | = f.input :password, :required => true 10 | = f.input :password_confirmation, :required => true 11 | 12 | .form-actions 13 | = f.button :submit, "Sign up" 14 | 15 | == render "devise/shared/links" 16 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/graphql/graphql_type.rb: -------------------------------------------------------------------------------- 1 | class Types::<%= class_name %>Type < Types::BaseObject 2 | 3 | graphql_name '<%= class_name %>' 4 | 5 | field :id, ID, null: false 6 | <% if @graphql_attributes.present? -%> 7 | <% @graphql_attributes.each do |graphql_object| -%> 8 | field :<%= graphql_object[:attr] %>, <%= graphql_object[:type] %>, null: true 9 | <% end -%> 10 | <% end -%> 11 | field :created_at, String, null: false 12 | field :updated_at, String, null: false 13 | end 14 | -------------------------------------------------------------------------------- /spec/dummy/app/models/coach.rb: -------------------------------------------------------------------------------- 1 | class Coach < ActiveRecord::Base 2 | include Fae::BaseModelConcern 3 | 4 | belongs_to :team 5 | 6 | validates :first_name, presence: true 7 | validates :last_name, presence: true 8 | validates :team_id, presence: true 9 | 10 | has_fae_image :image 11 | 12 | def fae_display_field 13 | full_name 14 | end 15 | 16 | def fae_parent 17 | team 18 | end 19 | 20 | def full_name 21 | "#{first_name} #{last_name}" 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /spec/requests/fae/images_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe 'images#create_html_embedded' do 4 | 5 | before do 6 | allow_any_instance_of(CarrierWave::Uploader::Base) 7 | .to receive(:store!) 8 | end 9 | 10 | it 'should return a json' do 11 | user_login 12 | post fae.html_embedded_image_path, 13 | params: { asset: Rails.root.join('/spec/support/images/test.jpeg') } 14 | 15 | expect(response.body).to eq '{"success":true,"file":null}' 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /Dockerfile.dev: -------------------------------------------------------------------------------- 1 | FROM ruby:3.1.1 2 | 3 | RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 4 | RUN apt-get update -y 5 | RUN apt-get install -y \ 6 | libqt5webkit5-dev \ 7 | build-essential \ 8 | qtbase5-dev \ 9 | qtchooser \ 10 | qt5-qmake \ 11 | qtbase5-dev-tools \ 12 | xvfb 13 | 14 | ENV app /app 15 | ENV BUNDLE_PATH /gems 16 | ENV GEM_HOME /gems 17 | 18 | COPY Gemfile* $app/ 19 | 20 | ENV PATH="$PATH:$BUNDLE_PATH/bin" 21 | 22 | COPY . $app/ 23 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/pages/_help.scss: -------------------------------------------------------------------------------- 1 | .help-section { 2 | .content { 3 | &:first-child { 4 | padding-top: 0; 5 | 6 | h2 { 7 | border-top: 0; 8 | } 9 | } 10 | } 11 | 12 | h3 { 13 | color: $c-text-heavy; 14 | font-size: 20px; 15 | padding-top: 10px; 16 | } 17 | 18 | p { 19 | color: $c-text-heavy; 20 | font-size: 15px; 21 | line-height: 1.4; 22 | margin: 0; 23 | } 24 | 25 | strong { 26 | font-weight: bold; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/views/devise/confirmations/new.html.slim: -------------------------------------------------------------------------------- 1 | h2 Resend confirmation instructions 2 | 3 | = simple_form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| 4 | = f.error_notification 5 | = f.full_error :confirmation_token 6 | 7 | .form-inputs 8 | = f.input :email, :required => true, :autofocus => true 9 | 10 | .form-actions 11 | = f.button :submit, "Resend confirmation instructions" 12 | 13 | == render "devise/shared/links" 14 | -------------------------------------------------------------------------------- /app/views/fae/setup/first_user.html.slim: -------------------------------------------------------------------------------- 1 | .first_user-form 2 | p = t('fae.setup.prompt') 3 | 4 | = simple_form_for(@user, html: { multipart: true, novalidate: true }, url: fae.first_user_path) do |f| 5 | = fae_input f, :first_name 6 | = fae_input f, :last_name 7 | = fae_input f, :email 8 | = fae_input f, :password, helper_text: t('fae.setup.password') 9 | = fae_input f, :password_confirmation 10 | .login-form-actions 11 | input name="commit" type="submit" value=t('fae.form.save') 12 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150925190110_create_validation_testers.rb: -------------------------------------------------------------------------------- 1 | class CreateValidationTesters < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :validation_testers do |t| 4 | t.string :name 5 | t.string :slug 6 | t.string :second_slug 7 | t.string :email 8 | t.string :url 9 | t.string :phone 10 | t.string :zip 11 | t.string :canadian_zip 12 | t.string :youtube_url 13 | 14 | t.timestamps null: false 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20221118192940_create_fae_seo_sets.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20221118161833) 2 | class CreateFaeSeoSets < ActiveRecord::Migration[7.0] 3 | def change 4 | create_table :fae_seo_sets do |t| 5 | t.string :seo_title 6 | t.text :seo_description 7 | t.string :social_media_title 8 | t.text :social_media_description 9 | t.references :seo_setable, polymorphic: true, index: true 10 | 11 | t.timestamps 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/views/fae/site_deploy_hooks/_form.html.slim: -------------------------------------------------------------------------------- 1 | ruby: 2 | form_options = { 3 | html: { 4 | multipart: true, 5 | novalidate: true, 6 | class: 'js-file-form', 7 | remote: true, 8 | data: { 9 | type: "html" 10 | } 11 | } 12 | } 13 | = simple_form_for(@item, form_options) do |f| 14 | = fae_input f, :environment 15 | = fae_input f, :url, label: 'URL' 16 | = f.hidden_field :site_id 17 | 18 | = f.submit 19 | = button_tag 'Cancel', type: 'button', class: 'js-cancel-nested cancel-nested-button' -------------------------------------------------------------------------------- /spec/models/fae/file_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::File do 4 | 5 | describe 'concerns' do 6 | it 'should allow instance methods through Fae::FileConcern' do 7 | file = FactoryBot.build_stubbed(:fae_file) 8 | expect(file.instance_says_what).to eq('Fae::File instance: what?') 9 | end 10 | 11 | it 'should allow class methods through Fae::FileConcern' do 12 | expect(Fae::File.class_says_what).to eq('Fae::File class: what?') 13 | end 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/globals/navigation/_base.scss: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////// 2 | // Shared styles b/w mobilenav and sidenav // 3 | ///////////////////////////////////////////// 4 | 5 | .nav { 6 | top: 0; 7 | left: 0; 8 | width: $sidenav-width - 30px; 9 | height: 100%; 10 | font-size: 15px; 11 | overflow: auto; 12 | 13 | a { 14 | display: block; 15 | color: $c-text; 16 | position: relative; 17 | 18 | &:hover { 19 | color: $c-dark-grey; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /spec/models/fae/image_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::Image do 4 | 5 | describe 'concerns' do 6 | it 'should allow instance methods through Fae::ImageConcern' do 7 | image = FactoryBot.build_stubbed(:fae_image) 8 | expect(image.instance_says_what).to eq('Fae::Image instance: what?') 9 | end 10 | 11 | it 'should allow class methods through Fae::ImageConcern' do 12 | expect(Fae::Image.class_says_what).to eq('Fae::Image class: what?') 13 | end 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /app/views/fae/static_pages/index.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/index_header', title: t('fae.page.title'), breadcrumbs: false, new_button: false 2 | 3 | main.content 4 | table.js-sort-column 5 | thead 6 | tr 7 | th = t('fae.common.name') 8 | th.-action-wide Modified 9 | tbody 10 | - @items.each do |item| 11 | tr id="fae_content_block_#{item.id}" 12 | td = link_to item.title.titleize, fae.edit_content_block_path(item.slug) 13 | td = fae_date_format item.updated_at 14 | -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_color_picker_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_color_picker' do 4 | scenario 'opens color picker', js: true do 5 | admin_login 6 | visit new_admin_release_path 7 | 8 | expect(page).to_not have_selector('.cp-color-picker') 9 | page.find('#release_color').click 10 | expect(page).to have_selector('.cp-color-picker', visible: true) 11 | page.find('#attributes').click 12 | expect(page).to have_selector('.cp-color-picker', visible: false) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application. 3 | 4 | ENGINE_ROOT = File.expand_path('../..', __FILE__) 5 | ENGINE_PATH = File.expand_path('../../lib/fae/engine', __FILE__) 6 | 7 | # Set up gems listed in the Gemfile. 8 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 9 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 10 | 11 | require 'rails/all' 12 | require 'rails/engine/commands' 13 | -------------------------------------------------------------------------------- /docs/contributing/standards.md: -------------------------------------------------------------------------------- 1 | # JavaScript Standards 2 | 3 | ## Functions 4 | 5 | camelCase 6 | 7 | ### Access 8 | 9 | Methods used only within the namespace should be preceeded by an underscore. This denotes the equivalent of Ruby's `private` even those these functions are still publicly exposed. 10 | 11 | ## Variables 12 | 13 | snake_case 14 | 15 | ### References 16 | 17 | When referencing upper namespace, always use `_this`. `that` will not be tolerated. 18 | 19 | ### jQuery objects 20 | 21 | Preceed all things jQuery with a `$`. -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/tables/_tooltips.scss: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | @include transition(opacity 0.2s); 3 | @include triangle(bottom, $c-darkest-grey, 4px); 4 | background: $c-darkest-grey; 5 | color: $c-white; 6 | opacity: 0; 7 | position: absolute; 8 | top: -25px; 9 | left: 0; 10 | border-radius: 2px; 11 | font-size: 10px; 12 | padding: 5px; 13 | width: 100%; 14 | } 15 | 16 | .tooltip-parent { 17 | position: relative; 18 | 19 | &:hover { 20 | .tooltip { 21 | opacity: 1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /db/migrate/20150930224821_create_fae_changes.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeChanges < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_changes do |t| 4 | t.integer :changeable_id 5 | t.string :changeable_type 6 | t.integer :user_id 7 | t.string :change_type 8 | t.text :updated_attributes 9 | 10 | t.timestamps null: false 11 | end 12 | 13 | add_index :fae_changes, :changeable_id 14 | add_index :fae_changes, :changeable_type 15 | add_index :fae_changes, :user_id 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141019043833_create_fae_options.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141017194616) 2 | class CreateFaeOptions < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_options do |t| 5 | t.string :title 6 | t.string :time_zone 7 | t.string :colorway 8 | t.string :stage_url 9 | t.string :live_url 10 | t.integer :singleton_guard 11 | 12 | t.timestamps 13 | end 14 | 15 | add_index :fae_options, :singleton_guard, unique: true 16 | end 17 | end -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/poly_things_controller.rb: -------------------------------------------------------------------------------- 1 | module Admin 2 | class PolyThingsController < Fae::NestedBaseController 3 | 4 | 5 | def new 6 | @item = @klass.new 7 | raise_undefined_parent if @item.fae_nested_foreign_key.blank? 8 | 9 | item_id = params[:item_id].to_i || nil 10 | item_class = params[:item_class] || nil 11 | @item.send("poly_thingable_id=", item_id) 12 | @item.send("poly_thingable_type=", item_class) 13 | build_assets 14 | end 15 | 16 | 17 | 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/features/markdown_binding_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'Rebinding Markdown' do 4 | 5 | scenario 'should only bind new markdown elements when nested add is clicked', js: true do 6 | release = FactoryBot.create(:release, name: 'Ima Release', vintage: '2012', price: 13, varietal_id: 2, show: Date.today) 7 | admin_login 8 | visit edit_admin_release_path(release) 9 | click_link 'Add Aroma' 10 | click_link 'Add Aroma' 11 | 12 | expect(page).to have_selector('.CodeMirror', count: 2) 13 | end 14 | 15 | end -------------------------------------------------------------------------------- /app/views/fae/application/_seo_set_form.html.slim: -------------------------------------------------------------------------------- 1 | ruby: 2 | require_locals ['f'], local_assigns 3 | item ||= f.object 4 | seo_set_name ||= :seo_set 5 | the_seo_set = item.send(seo_set_name) 6 | 7 | = f.simple_fields_for seo_set_name do |i| 8 | = fae_input i, :seo_title, label: 'SEO Title' 9 | = fae_input i, :seo_description, label: 'SEO Description' 10 | = fae_input i, :social_media_title 11 | = fae_input i, :social_media_description 12 | = fae_image_form i, :social_media_image, helper_text: '1200 x 630 px., JPG' 13 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141021183653_create_fae_text_areas.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141021183047) 2 | class CreateFaeTextAreas < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_text_areas do |t| 5 | t.integer :contentable, polymorphic: true, index: true 6 | t.string :label 7 | t.text :content 8 | t.integer :position, default: 0 9 | t.boolean :on_stage, default: true 10 | t.boolean :on_prod, default: false 11 | 12 | t.timestamps 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | log/*.log 3 | pkg/ 4 | spec/dummy/db/*.sqlite3 5 | spec/dummy/db/*.sqlite3-journal 6 | spec/dummy/log/*.log 7 | spec/dummy/tmp/ 8 | spec/dummy/.sass-cache 9 | spec/dummy/public/system/uploads/* 10 | spec/dummy/public/uploads/* 11 | 12 | spec/dummy/public/system/uploads/* 13 | spec/dummy/public/uploads/* 14 | 15 | /tmp 16 | 17 | .rvmrc 18 | .ruby-gemset 19 | .ruby-version 20 | .rbenv-gemsets 21 | .DS_Store 22 | 23 | .rubocop.yml 24 | 25 | *.gem 26 | 27 | /vendor 28 | docker-compose.override.yml 29 | .env 30 | mysql 31 | node_modules 32 | -------------------------------------------------------------------------------- /db/migrate/20141105214814_create_fae_text_fields.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeTextFields < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_text_fields do |t| 4 | t.references :contentable, polymorphic: true, index: true 5 | t.string :attached_as, index: true 6 | t.string :label 7 | t.string :content 8 | t.integer :position, default: 0, index: true 9 | t.boolean :on_stage, default: true, index: true 10 | t.boolean :on_prod, default: false, index: true 11 | 12 | t.timestamps 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/beers/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | main.content 5 | = fae_input f, :name 6 | = fae_image_form f, :image 7 | = fae_cta_form f, :test_cta 8 | section.content 9 | h2 SEO 10 | = fae_seo_set_form f, :seo 11 | 12 | - if params[:action] == 'edit' 13 | section.content#poly_things 14 | = render 'fae/shared/nested_table', 15 | assoc: :poly_things, 16 | parent_item: @item, 17 | cols: [:name] 18 | 19 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150929195433_add_extra_fields_to_validation_testers.rb: -------------------------------------------------------------------------------- 1 | class AddExtraFieldsToValidationTesters < ActiveRecord::Migration[4.2] 2 | def change 3 | add_column :validation_testers, :second_email, :string 4 | add_column :validation_testers, :unique_email, :string 5 | add_column :validation_testers, :second_url, :string 6 | add_column :validation_testers, :second_phone, :string 7 | add_column :validation_testers, :second_zip, :string 8 | add_column :validation_testers, :second_youtube_url, :string 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/requests/fae_nested_table_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe 'custom columns' do 4 | 5 | before do 6 | def edit_admin_release_path(release) 7 | Rails.application.routes.url_helpers.edit_admin_release_path(release) 8 | end 9 | end 10 | 11 | it 'should get correct title and attr' do 12 | release = FactoryBot.create(:release) 13 | admin_login 14 | get edit_admin_release_path(release) 15 | 16 | expect(response.body).to include('Pew Pew') 17 | expect(response.body).to include('Kitten Count') 18 | end 19 | end -------------------------------------------------------------------------------- /spec/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_datepicker_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_datepicker' do 4 | 5 | scenario 'should open and select date', js: true do 6 | admin_login 7 | visit new_admin_release_path 8 | 9 | release_date_input = page.find('#release_release_date') 10 | release_date_input.click 11 | within('.ui-datepicker-calendar') do 12 | click_link('10') 13 | end 14 | 15 | today = Date.today 16 | expect(release_date_input.value).to eq("#{today.strftime('%b')} 10, #{today.year}") 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /spec/models/fae/text_area_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::TextArea do 4 | 5 | describe 'concerns' do 6 | it 'should allow instance methods through Fae::TextAreaConcern' do 7 | text_area = FactoryBot.build_stubbed(:fae_text_area) 8 | 9 | expect(text_area.instance_says_what).to eq('Fae::TextArea instance: what?') 10 | end 11 | 12 | it 'should allow class methods through Fae::TextAreaConcern' do 13 | expect(Fae::TextArea.class_says_what).to eq('Fae::TextArea class: what?') 14 | end 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /spec/models/fae/text_field_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::TextField do 4 | 5 | describe 'concerns' do 6 | it 'should allow instance methods through Fae::TextFieldConcern' do 7 | text_field = FactoryBot.build_stubbed(:fae_text_field) 8 | expect(text_field.instance_says_what).to eq('Fae::TextField instance: what?') 9 | end 10 | 11 | it 'should allow class methods through Fae::TextFieldConcern' do 12 | expect(Fae::TextField.class_says_what).to eq('Fae::TextField class: what?') 13 | end 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /app/models/fae/file.rb: -------------------------------------------------------------------------------- 1 | require 'file_size_validator' 2 | 3 | module Fae 4 | class File < ActiveRecord::Base 5 | 6 | include Fae::BaseModelConcern 7 | include Fae::FileConcern 8 | include Fae::AssetsValidatable 9 | 10 | mount_uploader :asset, Fae::FileUploader 11 | 12 | validates :asset, 13 | file_size: { 14 | maximum: Fae.max_file_upload_size.megabytes.to_i 15 | } 16 | 17 | belongs_to :fileable, polymorphic: true, touch: true, optional: true 18 | 19 | def readonly? 20 | false 21 | end 22 | 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/support/async_helper.rb: -------------------------------------------------------------------------------- 1 | # eventually usage: 2 | # it "should return a result of 5" do 3 | # eventually { long_running_thing.result.should eq(5) } 4 | # end 5 | def eventually(options = {}) 6 | timeout = options[:timeout] || 10 7 | interval = options[:interval] || 0.2 8 | time_limit = Time.now + timeout 9 | loop do 10 | begin 11 | yield 12 | rescue *[RSpec::Expectations::ExpectationNotMetError, StandardError] => error 13 | end 14 | return if error.nil? 15 | raise error if Time.now >= time_limit 16 | sleep interval 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.slim: -------------------------------------------------------------------------------- 1 | .login-form-password 2 | = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| 3 | = f.error_notification 4 | = f.label :email, "We'll Send Your Password." 5 | = f.label :email, "What Email Do You Use To Sign In?" 6 | = f.input :email, required: true, autofocus: true, label: false 7 | .login-form-actions 8 | = f.button :submit, 'Submit' 9 | - if controller_name != 'sessions' 10 | = link_to "Back to Sign In", new_session_path(resource_name) 11 | -------------------------------------------------------------------------------- /db/migrate/20141021181327_create_fae_files.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeFiles < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_files do |t| 4 | t.string :name 5 | t.string :asset 6 | t.references :fileable, polymorphic: true, index: true 7 | t.integer :file_size 8 | t.integer :position, default: 0 9 | t.string :attached_as, index: true 10 | t.boolean :on_stage, default: true 11 | t.boolean :on_prod, default: false 12 | t.boolean :required, default: false 13 | 14 | t.timestamps 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/controllers/fae/application_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::ApplicationController do 4 | 5 | describe 'concerns' do 6 | it 'should allow instance methods through Fae::ApplicationControllerConcern' do 7 | expect(described_class.new.instance_says_what).to eq('Fae::ApplicationController instance: what?') 8 | end 9 | 10 | it 'should allow class methods through Fae::ApplicationController' do 11 | expect(described_class.class_says_what).to eq('Fae::ApplicationController class: what?') 12 | end 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/fae/modules/_deploy.scss: -------------------------------------------------------------------------------- 1 | .deploying-heading.running:after { 2 | overflow: hidden; 3 | display: inline-block; 4 | vertical-align: bottom; 5 | -webkit-animation: ellipsis steps(4,end) 900ms infinite; 6 | animation: ellipsis steps(4,end) 900ms infinite; 7 | content: "\2026"; /* ascii code for the ellipsis character */ 8 | width: 0px; 9 | } 10 | 11 | @keyframes ellipsis { 12 | to { 13 | width: 20px; 14 | } 15 | } 16 | 17 | @-webkit-keyframes ellipsis { 18 | to { 19 | width: 20px; 20 | } 21 | } 22 | 23 | .hidden { 24 | display: none; 25 | } -------------------------------------------------------------------------------- /app/validators/fae/cross_model_uniqueness_validator.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class CrossModelUniquenessValidator < ActiveModel::EachValidator 3 | def validate_each(record, attribute, value) 4 | if options[:model].where(attribute => value).present? 5 | record.errors[attribute] << (options[:message] || "has already been taken in #{articlize(options[:model].to_s.downcase)}") 6 | end 7 | end 8 | 9 | private 10 | def articlize(params_word) 11 | %w(a e i o u).include?(params_word[0].downcase) ? "an #{params_word}" : "a #{params_word}" 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /db/migrate/20141021183047_create_fae_text_areas.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeTextAreas < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :fae_text_areas do |t| 4 | t.string :label 5 | t.text :content 6 | t.integer :position, default: 0, index: true 7 | t.boolean :on_stage, default: true, index: true 8 | t.boolean :on_prod, default: false, index: true 9 | t.integer :contentable_id, index: true 10 | t.string :contentable_type, index: true 11 | t.string :attached_as, index: true 12 | 13 | t.timestamps 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/dummy/app/views/pages/home.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

Live Demo

3 |

4 | <%= link_to 'View the live demo', '/admin' %>
5 | username: demo@wearefine.com
6 | password: demofine 7 |

8 |
9 | 10 |
11 |

Form UI Menu

12 |

Available form elements can be viewed on the demo's <%= link_to 'release form', new_admin_release_path %>.

13 |
14 | 15 |
16 |

Documentation

17 |

<%= link_to 'Technical Doumentation', 'https://github.com/wearefine/fae', target: '_blank' %>

18 |
19 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20150508224216_add_languages_to_wines.rb: -------------------------------------------------------------------------------- 1 | class AddLanguagesToWines < ActiveRecord::Migration[4.2] 2 | def change 3 | rename_column :wines, :name, :name_en 4 | add_column :wines, :name_zh, :string 5 | add_column :wines, :name_ja, :string 6 | add_column :wines, :description_en, :text 7 | add_column :wines, :description_zh, :text 8 | add_column :wines, :description_ja, :text 9 | add_column :wines, :food_pairing_en, :text 10 | add_column :wines, :food_pairing_zh, :text 11 | add_column :wines, :food_pairing_ja, :text 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/models/fae/change_spec.rb: -------------------------------------------------------------------------------- 1 | require 'rails_helper' 2 | 3 | describe Fae::Change do 4 | 5 | describe '#unique_changeable_types' do 6 | it 'should collect all unique models and order them' do 7 | release = FactoryBot.create(:release) 8 | FactoryBot.create(:cat) 9 | FactoryBot.create(:team) 10 | FactoryBot.create(:fae_user) 11 | release.update(name: 'something') 12 | 13 | expect(Fae::Change.unique_changeable_types).to eq([['Cat','Cat'], ['User','Fae::User'], ['Release','Release'], ['Team','Team'], ['Wine','Wine']]) 14 | end 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20140827225157_create_releases.rb: -------------------------------------------------------------------------------- 1 | class CreateReleases < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table :releases do |t| 4 | t.string :name 5 | t.string :slug 6 | t.text :intro 7 | t.text :body 8 | t.string :vintage 9 | t.string :price 10 | t.string :tasting_notes_pdf 11 | t.integer :wine_id 12 | t.integer :varietal_id 13 | t.boolean :on_stage, default: true 14 | t.boolean :on_prod, default: false 15 | t.integer :position 16 | 17 | t.timestamps 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/arrow_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/arrow_up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/views/devise/passwords/edit.html.slim: -------------------------------------------------------------------------------- 1 | .login-form-password 2 | = simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| 3 | = f.error_notification 4 | = f.input :reset_password_token, :as => :hidden 5 | = f.full_error :reset_password_token 6 | .form-inputs 7 | = f.input :password, :label => "New password", :required => true, :autofocus => true 8 | = f.input :password_confirmation, :label => "Confirm your new password", :required => true 9 | .form-actions 10 | = f.button :submit, "Change my password" 11 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141021181927_create_fae_files.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141021181327) 2 | class CreateFaeFiles < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_files do |t| 5 | t.string :name 6 | t.string :asset 7 | t.references :fileable, polymorphic: true, index: true 8 | t.integer :file_size 9 | t.integer :position, default: 0 10 | t.string :attached_as, index: true 11 | t.boolean :on_stage, default: true 12 | t.boolean :on_prod, default: false 13 | 14 | t.timestamps 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/factories/fae/image_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_image, class: 'Fae::Image' do 4 | # https://github.com/docker/for-mac/issues/5570 5 | file = File.open(File.join('spec', 'support', 'assets', 'test.jpg')) 6 | asset { Rack::Test::UploadedFile.new(file, 'image/jpeg', true, original_filename: 'test.jpg') } 7 | end 8 | 9 | factory :fae_image_svg, class: 'Fae::Image' do 10 | file = File.open(File.join('spec', 'support', 'assets', 'test.svg')) 11 | asset { Rack::Test::UploadedFile.new(file, 'image/svg+xml', true, original_filename: 'test.svg') } 12 | end 13 | 14 | end -------------------------------------------------------------------------------- /spec/dummy/README.rdoc: -------------------------------------------------------------------------------- 1 | == README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | 26 | 27 | Please feel free to use a different markup language if you do not plan to run 28 | rake doc:app. 29 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20151001210315_create_fae_changes.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20150930224821) 2 | class CreateFaeChanges < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_changes do |t| 5 | t.integer :changeable_id 6 | t.string :changeable_type 7 | t.integer :user_id 8 | t.string :change_type 9 | t.text :updated_attributes 10 | 11 | t.timestamps null: false 12 | end 13 | 14 | add_index :fae_changes, :changeable_id 15 | add_index :fae_changes, :changeable_type 16 | add_index :fae_changes, :user_id 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/chevron_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/admin/releases_controller.rb: -------------------------------------------------------------------------------- 1 | class Admin::ReleasesController < Fae::BaseController 2 | 3 | private 4 | 5 | def build_assets 6 | @item.build_bottle_shot if @item.bottle_shot.blank? 7 | @item.build_hero_image if @item.hero_image.blank? 8 | @item.build_label_pdf if @item.label_pdf.blank? 9 | end 10 | 11 | def attributes_for_cloning 12 | [:name, :slug, :intro, :body, :wine_id, :release_date] 13 | end 14 | 15 | def associations_for_cloning 16 | [:aromas, :events, :bottle_shot, :label_pdf] 17 | end 18 | 19 | def use_pagination 20 | true 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/chevron_up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/views/kaminari/fae/_page.html.slim: -------------------------------------------------------------------------------- 1 | / Link showing page number 2 | / - available local variables 3 | / page: a page object for "this" page 4 | / url: url to this page 5 | / current_page: a page object for the currently displayed page 6 | / total_pages: total number of pages 7 | / per_page: number of items to fetch per page 8 | / remote: data-remote 9 | - if page.current? 10 | span.page.current 11 | == page.number 12 | - else 13 | - rel = page.next? ? 'next' : page.prev? ? 'prev' : nil 14 | span.page 15 | a href=url rel=rel remote=remote data-page=page.number = page.number 16 | -------------------------------------------------------------------------------- /docs/features/disable_envs.md: -------------------------------------------------------------------------------- 1 | # Disabling Environments 2 | 3 | Sometimes an application will have two environments that share a DB. This is helpful when you want to flag data in a production admin to be available for review on a staging admin. 4 | 5 | It can be confusing for the user to have an admin on the staging site and could potentially lead to unkowning affecting production data. 6 | 7 | If you want to disable Fae on any Rails environment, you can do so with this option in `config/initializers/fae.rb`: 8 | 9 | ```ruby 10 | Fae.setup do |config| 11 | 12 | config.disabled_environments = [ :preview, :staging ] 13 | 14 | end 15 | ``` -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20141105221151_create_fae_text_fields.fae.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from fae (originally 20141105214814) 2 | class CreateFaeTextFields < ActiveRecord::Migration[4.2] 3 | def change 4 | create_table :fae_text_fields do |t| 5 | t.references :contentable, polymorphic: true, index: true 6 | t.string :attatched_as, index: true 7 | t.string :label 8 | t.string :content 9 | t.integer :position, default: 0, index: true 10 | t.boolean :on_stage, default: true, index: true 11 | t.boolean :on_prod, default: false, index: true 12 | 13 | t.timestamps 14 | end 15 | end 16 | end -------------------------------------------------------------------------------- /app/assets/images/fae/icons/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/sort.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.slim: -------------------------------------------------------------------------------- 1 | .login-form 2 | = simple_form_for(resource, as: resource_name, url: session_path(resource_name), html: { id: 'login_form' }) do |f| 3 | = f.input :email, required: false, autofocus: true 4 | = f.input :password, required: false 5 | - if @option.site_mfa_enabled 6 | = fae_input f, :otp_attempt, label: 'MFA Code', helper_text: 'Contact an admin if you don’t have access to your multi-factor authentication code.' 7 | .login-form-actions 8 | = f.input :remember_me, as: :boolean if devise_mapping.rememberable? 9 | = f.button :submit, "Submit", class: "login-form-actions-submit" 10 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/sub_aromas/_form.html.slim: -------------------------------------------------------------------------------- 1 | ruby: 2 | form_options = { 3 | html: { 4 | multipart: true, 5 | novalidate: true, 6 | class: 'js-file-form', 7 | remote: true, 8 | data: { 9 | type: "html", 10 | form_manager_model: @item.fae_form_manager_model_name, 11 | form_manager_info: (@form_manager.present? ? @form_manager.to_json : nil) 12 | } 13 | } 14 | } 15 | = simple_form_for([:admin, @item], form_options) do |f| 16 | = fae_input f, :name 17 | 18 | = f.hidden_field :aroma_id 19 | 20 | = f.submit 21 | = button_tag 'Cancel', type: 'button', class: 'js-cancel-nested cancel-nested-button' 22 | -------------------------------------------------------------------------------- /config/initializers/two_factor_backupable_patch.rb: -------------------------------------------------------------------------------- 1 | module Devise 2 | module Models 3 | module TwoFactorBackupable 4 | 5 | def invalidate_otp_backup_code!(code) 6 | codes = self.otp_backup_codes || [] 7 | 8 | if codes.is_a? String 9 | codes = JSON.parse(codes) 10 | end 11 | 12 | codes.each do |backup_code| 13 | next unless Devise::Encryptor.compare(self.class, backup_code, code) 14 | 15 | codes.delete(backup_code) 16 | self.otp_backup_codes = codes 17 | return true 18 | end 19 | 20 | false 21 | end 22 | 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /db/migrate/20141008180718_create_fae_images_table.rb: -------------------------------------------------------------------------------- 1 | class CreateFaeImagesTable < ActiveRecord::Migration[4.2] 2 | def change 3 | create_table(:fae_images) do |t| 4 | t.string :name 5 | t.string :asset 6 | t.references :imageable, polymorphic: true, index: true 7 | t.string :alt 8 | t.string :caption 9 | t.integer :position, default: 0 10 | t.string :attached_as, index: true 11 | t.boolean :on_stage, default: true 12 | t.boolean :on_prod, default: false 13 | t.integer :file_size 14 | t.boolean :required, default: false 15 | 16 | t.timestamps 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/dummy/app/models/contact_us_page.rb: -------------------------------------------------------------------------------- 1 | class ContactUsPage < Fae::StaticPage 2 | 3 | @slug = 'contact_us' 4 | 5 | fae_translate :body 6 | 7 | # required to set the has_one associations, Fae::StaticPage will build these associations dynamically 8 | def self.fae_fields 9 | { 10 | hero: { type: Fae::Image, languages: Fae.languages.keys }, 11 | email: { type: Fae::TextField }, 12 | body: { 13 | type: Fae::TextArea, 14 | languages: [:en, :zh], 15 | validates: { 16 | length: { 17 | maximum: 150 18 | } 19 | } 20 | } 21 | } 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/validation_testers/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for([:admin, @item]) do |f| 2 | == render 'fae/shared/form_header', header: @klass_name 3 | 4 | section.content 5 | = fae_input f, :name, input_class: 'slugger' 6 | = fae_input f, :slug 7 | = fae_input f, :email 8 | = fae_input f, :second_email 9 | = fae_input f, :unique_email 10 | = fae_input f, :url 11 | = fae_input f, :second_url 12 | = fae_input f, :phone 13 | = fae_input f, :second_phone 14 | = fae_input f, :zip 15 | = fae_input f, :second_zip 16 | = fae_input f, :youtube_url 17 | = fae_input f, :second_youtube_url 18 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | brakeman: 3 | enabled: true 4 | bundler-audit: 5 | enabled: true 6 | csslint: 7 | enabled: true 8 | rubocop: 9 | enabled: true 10 | eslint: 11 | enabled: true 12 | fixme: 13 | enabled: true 14 | duplication: 15 | enabled: true 16 | config: 17 | languages: 18 | - ruby 19 | - javascript 20 | ratings: 21 | paths: 22 | - app/** 23 | - lib/** 24 | - "**.rb" 25 | - Gemfile.lock 26 | exclude_paths: 27 | - app/assets/javascripts/fae/vendor/* 28 | - app/assets/stylesheets/fae/vendor/* 29 | - spec/** 30 | - config/deploy/** 31 | - lib/generators/fae/templates/* 32 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/arrow_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/arrow_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/graphql/graphql_page_type.rb: -------------------------------------------------------------------------------- 1 | class Types::<%= class_name %>PageType < Types::BaseObject 2 | 3 | graphql_name '<%= class_name %>Page' 4 | 5 | field :title, String, null: false 6 | <% if @graphql_attributes.present? -%> 7 | <% @graphql_attributes.each do |graphql_object| -%> 8 | <% if graphql_object[:type]['Types::'] -%> 9 | field :<%= graphql_object[:attr] %>, <%= graphql_object[:type] %>, null: true 10 | <% else -%> 11 | field :<%= graphql_object[:attr] %>, <%= graphql_object[:type] %>, 12 | null: true, 13 | method: :<%= graphql_object[:attr] %>_content 14 | <% end -%> 15 | <% end -%> 16 | <% end -%> 17 | end 18 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/content_blocks/about_us.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for @item, url: fae.update_content_block_path(slug: @item.slug), method: :put do |f| 2 | == render 'fae/shared/form_header', header: @item, f: f, languages: true 3 | 4 | section.content 5 | = fae_input f, :title 6 | 7 | = fae_content_form f, :header, input_options: { wrapper_html: { class: 'hidden' } } 8 | = fae_content_form f, :introduction, markdown: true, input_options: { input_html: { class: 'js-intro-field' } } 9 | = fae_content_form f, :body, markdown_supported: true 10 | = fae_image_form f, :header_image 11 | 12 | == render 'fae/shared/recent_changes' 13 | -------------------------------------------------------------------------------- /spec/factories/fae/user_factory.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | 3 | factory :fae_user, class: 'Fae::User' do 4 | sequence(:first_name) { |n| "Andy#{n}" } 5 | sequence(:last_name) { |n| "Doe#{n}" } 6 | email 7 | sequence(:password) { |n| "Passw0rd#{n}" } 8 | password_confirmation { password } 9 | active true 10 | 11 | association :role, factory: :fae_role 12 | 13 | trait :with_otp do 14 | otp_required_for_login { true } 15 | 16 | after(:build) do |user, _evaluator| 17 | user.otp_secret = Fae::User.generate_otp_secret 18 | user.generate_otp_backup_codes! 19 | end 20 | end 21 | end 22 | 23 | end -------------------------------------------------------------------------------- /spec/features/form_helpers/fae_daterange_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | feature 'fae_daterange' do 4 | 5 | scenario 'should open and select dates', js: true do 6 | admin_login 7 | visit new_admin_release_path 8 | 9 | start_date_input = page.find('#release_show') 10 | end_date_input = page.find('#release_hide') 11 | start_date_input.click 12 | within('.date-picker-wrapper .month1') do 13 | find('div.day', text: '10').click 14 | find('div.day', text: '15').click 15 | end 16 | 17 | expect(start_date_input.value).to include('10') 18 | expect(end_date_input.value).to include('15') 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /app/models/fae/form_manager.rb: -------------------------------------------------------------------------------- 1 | module Fae 2 | class FormManager < ActiveRecord::Base 3 | 4 | include Fae::BaseModelConcern 5 | 6 | def fae_display_field 7 | model_name 8 | end 9 | 10 | class << self 11 | 12 | def for_model(params, item) 13 | if item.present? && item.class.superclass.name == 'Fae::StaticPage' 14 | conditions = {form_manager_model_name: 'Fae::StaticPage', form_manager_model_id: item.fae_form_manager_model_id} 15 | else 16 | conditions = {form_manager_model_name: params[:controller].gsub('admin/','').classify} 17 | end 18 | where(conditions).first 19 | end 20 | 21 | end 22 | 23 | end 24 | end -------------------------------------------------------------------------------- /docs/features/search.md: -------------------------------------------------------------------------------- 1 | # Global Search 2 | 3 | Fae features a global search/navigation in the upper right. Clicking on this will automatically display the first two levels of navigation. Search results will be displayed from both navigation items and DB objects when three characters or more are entered in the search bar. 4 | 5 | Navigation items are matched by their defined titles, ignoring case. Objects are matched by their `fae_display_field`. 6 | 7 | ## Omitting an Object 8 | 9 | To omit an object from global search, add it to the `dashboard_exclusions` array in `config/initializers/fae.rb` 10 | 11 | ```ruby 12 | config.dashboard_exclusions = %w( Cat ) 13 | ``` -------------------------------------------------------------------------------- /spec/support/database_cleaner.rb: -------------------------------------------------------------------------------- 1 | # because Avdi Grimm said so 2 | # http://devblog.avdi.org/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/ 3 | 4 | RSpec.configure do |config| 5 | 6 | config.before(:suite) do 7 | DatabaseCleaner.clean_with(:truncation) 8 | end 9 | 10 | config.before(:each) do 11 | DatabaseCleaner.strategy = :transaction 12 | end 13 | 14 | config.before(:each, :js => true) do 15 | DatabaseCleaner.strategy = :truncation 16 | end 17 | 18 | config.before(:each) do 19 | DatabaseCleaner.start 20 | end 21 | 22 | config.after(:each) do 23 | DatabaseCleaner.clean 24 | end 25 | 26 | end -------------------------------------------------------------------------------- /app/views/fae/two_factor_settings/edit.html.slim: -------------------------------------------------------------------------------- 1 | = render 'fae/shared/index_header', title: 'Multi-Factor Authentication Backup Codes', breadcrumbs: false, new_button: false 2 | 3 | section.content 4 | article.content 5 | p 6 | 'The multi-factor authentication setup is complete. Save the following backup codes in a secure place in case you lose access to your authenticator app. Backup codes can be used as a one-time replacement MFA code. 7 | br 8 | 9 | 10 | - @backup_codes.each_slice(2) do |(code1, code2)| 11 | div.mfa-section-content 12 | div.mfa-backup-codes = code1 13 | div.mfa-backup-codes = code2 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /lib/generators/fae/templates/tasks/fae_tasks.rake: -------------------------------------------------------------------------------- 1 | namespace :fae do 2 | desc "Seeds the parent app with Fae's defaults" 3 | task :seed_db => :environment do 4 | Fae::Role.delete_all 5 | Fae::Role.create(name: 'super admin', position: 0) 6 | Fae::Role.create(name: 'admin', position: 1) 7 | Fae::Role.create(name: 'user', position: 2) 8 | 9 | if Fae::Option.first.blank? 10 | option = Fae::Option.new({ 11 | title: 'My FINE Admin', 12 | singleton_guard: 0, 13 | time_zone: 'Pacific Time (US & Canada)', 14 | live_url: 'http://www.wearefine.com' 15 | }) 16 | option.save! 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/delete_x.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/pulldown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/inputs/radio_collection_input.rb: -------------------------------------------------------------------------------- 1 | class RadioCollectionInput < SimpleForm::Inputs::CollectionRadioButtonsInput 2 | 3 | def input(wrapper_options) 4 | label_method, value_method = detect_collection_methods 5 | 6 | @builder.send("collection_radio_buttons", 7 | attribute_name, collection, value_method, label_method, 8 | input_options, input_html_options, &collection_block_for_nested_boolean_style 9 | ) 10 | end 11 | 12 | protected 13 | 14 | def build_nested_boolean_style_item_tag(collection_builder) 15 | collection_builder.radio_button + "".html_safe + collection_builder.text 16 | end 17 | end -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/spirits/index.html.slim: -------------------------------------------------------------------------------- 1 | == render 'fae/shared/index_header', title: @klass_humanized.pluralize.titleize 2 | 3 | main.content 4 | table.js-sort-column 5 | thead 6 | tr 7 | th Name 8 | th.-action-wide Modified 9 | th.-action data-sorter="false" 10 | 11 | tbody 12 | - if @items.present? 13 | - @items.each do |item| 14 | tr id=fae_sort_id(item) 15 | td = link_to item.fae_display_field, edit_admin_spirit_path(item) 16 | td = fae_date_format item.updated_at 17 | td = fae_delete_button item 18 | - else 19 | tr: td colspan="3" No items found 20 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/chevron_left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/views/fae/users/_form.html.slim: -------------------------------------------------------------------------------- 1 | = simple_form_for(@user) do |f| 2 | - if params[:action] === 'settings' 3 | - title = t('fae.navbar.your_settings') 4 | - else 5 | - title = "#{params[:action]} User".titleize 6 | == render 'fae/shared/form_header', header: 'User', title: title 7 | 8 | main.content 9 | = fae_input f, :first_name 10 | = fae_input f, :last_name 11 | = fae_input f, :email 12 | = fae_input f, :password, helper_text: t('fae.user.password_hint') 13 | = fae_input f, :password_confirmation 14 | - if current_user.admin? || current_user.super_admin? 15 | = fae_association f, :role, collection: @role_collection, prompt: false 16 | -------------------------------------------------------------------------------- /spec/dummy/lib/tasks/fae_tasks.rake: -------------------------------------------------------------------------------- 1 | namespace :fae do 2 | desc "Seeds the parent app with Fae's defaults" 3 | task :seed_db => :environment do 4 | if Fae::Role.first.blank? 5 | Fae::Role.create(name: 'super admin', position: 0) 6 | Fae::Role.create(name: 'admin', position: 1) 7 | Fae::Role.create(name: 'user', position: 2) 8 | end 9 | 10 | if Fae::Option.first.blank? 11 | option = Fae::Option.new({ 12 | title: 'My FINE Admin', 13 | singleton_guard: 0, 14 | time_zone: 'Pacific Time (US & Canada)', 15 | live_url: 'http://www.wearefine.com' 16 | }) 17 | option.save! 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/features/sign_out_spec.rb: -------------------------------------------------------------------------------- 1 | # require 'spec_helper' 2 | 3 | # feature 'Sign Out' do 4 | 5 | # scenario 'when user clicks log out', js: true do 6 | # TODO: this test is flickering, occasionally getting `Capybara::ElementNotFound: Unable to find link "Log Out"` 7 | # it's a test worth having, so we should look into it 8 | 9 | # admin_login 10 | 11 | # visit fae.root_path 12 | 13 | # find('.utility-nav-user').click 14 | 15 | # eventually { 16 | # click_link 'Log Out' 17 | 18 | # expect(page).to have_content('Goodbye for now.') 19 | # expect(page).to have_content('Forgot your password?') 20 | # } 21 | # end 22 | 23 | # end 24 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/chevron_right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/assets/images/fae/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | --------------------------------------------------------------------------------