has_helpers 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +38 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.tekton/Chart.yaml +14 -0
- data/.tekton/templates/pipelinerun.yaml +44 -0
- data/.tekton/values-main.yaml +53 -0
- data/.tekton/values-pr.yaml +40 -0
- data/.tekton/values.yaml +17 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +204 -0
- data/Gemfile +25 -0
- data/README.md +76 -0
- data/Rakefile +46 -0
- data/app/api/has_helpers/rack_api.rb +116 -0
- data/app/api/has_helpers/search_api.rb +173 -0
- data/app/assets/stylesheets/has_helpers/base.scss +5 -0
- data/app/assets/stylesheets/has_helpers/color_palette.scss +33 -0
- data/app/assets/stylesheets/has_helpers/color_palettes/default.scss +11 -0
- data/app/assets/stylesheets/has_helpers/components/dataset.scss +43 -0
- data/app/assets/stylesheets/has_helpers/mixins.scss +149 -0
- data/app/commands/has_helpers/cards/available_cards_command.rb +98 -0
- data/app/commands/has_helpers/cards/card_data_command.rb +1062 -0
- data/app/commands/reports/base_options.rb +79 -0
- data/app/commands/reports/belongs_to_options.rb +178 -0
- data/app/commands/reports/constant_options.rb +66 -0
- data/app/commands/reports/external_graphql_client.rb +116 -0
- data/app/commands/reports/fill_dates.rb +65 -0
- data/app/commands/reports/filter_option_generator.rb +186 -0
- data/app/commands/reports/generator.rb +310 -0
- data/app/commands/reports/has_many_options.rb +105 -0
- data/app/commands/reports/importer.rb +132 -0
- data/app/commands/reports/nested_attribute_options.rb +134 -0
- data/app/constants/color.rb +9 -0
- data/app/constants/file_format.rb +12 -0
- data/app/constants/has_helpers/cards/card_custom_field.rb +12 -0
- data/app/constants/has_helpers/cards/card_data_type.rb +11 -0
- data/app/constants/has_helpers/cards/card_identifier.rb +10 -0
- data/app/constants/has_helpers/cards/card_layout_type.rb +11 -0
- data/app/constants/has_helpers/cards/card_variant_type.rb +12 -0
- data/app/constants/has_helpers/link_type.rb +10 -0
- data/app/constants/has_helpers/notification_alert_status.rb +14 -0
- data/app/constants/has_helpers/notification_alert_type.rb +10 -0
- data/app/constants/has_helpers/operation.rb +11 -0
- data/app/constants/has_helpers/resource_type.rb +25 -0
- data/app/constants/icon.rb +22 -0
- data/app/constants/logical_operator.rb +7 -0
- data/app/constants/option.rb +10 -0
- data/app/constants/time_zone.rb +12 -0
- data/app/constructors/has_helpers/base_constructor.rb +62 -0
- data/app/controllers/concerns/has_helpers/service_trust/authenticated_as_service.rb +51 -0
- data/app/controllers/concerns/has_helpers/service_trust/graphql_authentication.rb +57 -0
- data/app/controllers/has_helpers/controller.rb +63 -0
- data/app/controllers/has_helpers/factory_controller.rb +261 -0
- data/app/controllers/has_helpers/graphql_extensions.rb +83 -0
- data/app/controllers/has_helpers/health_check_controller.rb +46 -0
- data/app/controllers/has_helpers/search_extensions.rb +92 -0
- data/app/controllers/has_helpers/service_trust/jwks_controller.rb +20 -0
- data/app/controllers/has_helpers/xlsx_export.rb +115 -0
- data/app/controllers/search_extensions.rb +5 -0
- data/app/graphql/has_helpers/base_type.rb +13 -0
- data/app/graphql/has_helpers/base_union.rb +9 -0
- data/app/graphql/has_helpers/enums/resource_enum.rb +24 -0
- data/app/graphql/has_helpers/middleware/application_access.rb +26 -0
- data/app/graphql/has_helpers/mutations/base.rb +27 -0
- data/app/graphql/has_helpers/mutations/external_data_sync.rb +72 -0
- data/app/graphql/has_helpers/mutations/mark_individual_alert_read.rb +31 -0
- data/app/graphql/has_helpers/mutations/mark_notifications_read.rb +50 -0
- data/app/graphql/has_helpers/mutations/toggle_favorite.rb +39 -0
- data/app/graphql/has_helpers/resolvers/app_nav.rb +107 -0
- data/app/graphql/has_helpers/resolvers/base.rb +27 -0
- data/app/graphql/has_helpers/resolvers/cards/available_cards.rb +31 -0
- data/app/graphql/has_helpers/resolvers/cards/card_data.rb +74 -0
- data/app/graphql/has_helpers/resolvers/cards/hover_card_data.rb +153 -0
- data/app/graphql/has_helpers/resolvers/favorite.rb +62 -0
- data/app/graphql/has_helpers/resolvers/internal/roles.rb +54 -0
- data/app/graphql/has_helpers/resolvers/is_favorite.rb +24 -0
- data/app/graphql/has_helpers/resolvers/list_notification_alerts.rb +47 -0
- data/app/graphql/has_helpers/resolvers/lookup.rb +36 -0
- data/app/graphql/has_helpers/resolvers/recently_viewed.rb +54 -0
- data/app/graphql/has_helpers/resolvers/resource_tab.rb +22 -0
- data/app/graphql/has_helpers/resolvers/search.rb +18 -0
- data/app/graphql/has_helpers/resolvers/search_query.rb +38 -0
- data/app/graphql/has_helpers/resolvers/user_application_order.rb +35 -0
- data/app/graphql/has_helpers/resources/organization_option_resource.rb +28 -0
- data/app/graphql/has_helpers/resources/organization_resource_resource.rb +18 -0
- data/app/graphql/has_helpers/resources/resource_group_resource.rb +10 -0
- data/app/graphql/has_helpers/resources/resource_resource.rb +21 -0
- data/app/graphql/has_helpers/resources/user_role_resource.rb +9 -0
- data/app/graphql/has_helpers/types/application_order_type.rb +18 -0
- data/app/graphql/has_helpers/types/cards/available_card_type.rb +20 -0
- data/app/graphql/has_helpers/types/cards/card_badge_type.rb +12 -0
- data/app/graphql/has_helpers/types/cards/card_config_type.rb +18 -0
- data/app/graphql/has_helpers/types/cards/card_data_type.rb +13 -0
- data/app/graphql/has_helpers/types/cards/card_entry_field_type.rb +21 -0
- data/app/graphql/has_helpers/types/cards/card_entry_type.rb +12 -0
- data/app/graphql/has_helpers/types/cards/card_field_config_type.rb +17 -0
- data/app/graphql/has_helpers/types/layouts/app_nav/link_section_type.rb +17 -0
- data/app/graphql/has_helpers/types/layouts/app_nav/link_type.rb +20 -0
- data/app/graphql/has_helpers/types/layouts/app_nav/sub_link_type.rb +17 -0
- data/app/graphql/has_helpers/types/layouts/app_nav/type.rb +16 -0
- data/app/graphql/has_helpers/types/lookup.rb +16 -0
- data/app/graphql/has_helpers/types/resource_tab/type.rb +15 -0
- data/app/graphql/has_helpers/types/role_type.rb +13 -0
- data/app/graphql/has_helpers/types/search/detail_badge_type.rb +15 -0
- data/app/graphql/has_helpers/types/search/detail_item_type.rb +14 -0
- data/app/graphql/has_helpers/types/search/detail_type.rb +16 -0
- data/app/graphql/has_helpers/types/search/filter_operation_enum.rb +19 -0
- data/app/graphql/has_helpers/types/search/input_type.rb +16 -0
- data/app/graphql/has_helpers/types/search/result_type.rb +72 -0
- data/app/graphql/has_helpers/types/search/search_filter_input_type.rb +17 -0
- data/app/graphql/has_helpers/types/search/type.rb +17 -0
- data/app/importers/has_helpers/cards/importer.rb +1223 -0
- data/app/lib/has_helpers/application_helper.rb +21 -0
- data/app/lib/has_helpers/dn/processor.rb +55 -0
- data/app/lib/has_helpers/dn/refresh.rb +13 -0
- data/app/lib/has_helpers/dn/utils/backfill_utils.rb +80 -0
- data/app/lib/has_helpers/dn/utils/query_utils.rb +216 -0
- data/app/lib/has_helpers/feature.rb +88 -0
- data/app/lib/has_helpers/hq_exception.rb +18 -0
- data/app/lib/has_helpers/index.rb +890 -0
- data/app/lib/has_helpers/organization_merge.rb +128 -0
- data/app/lib/has_helpers/query/elasticsearch.rb +20 -0
- data/app/lib/has_helpers/query/provider.rb +105 -0
- data/app/lib/has_helpers/query/sql.rb +133 -0
- data/app/lib/has_helpers/query.rb +14 -0
- data/app/lib/has_helpers/search/elasticsearch.rb +41 -0
- data/app/lib/has_helpers/search/elasticsearch_shared.rb +70 -0
- data/app/lib/has_helpers/search/provider.rb +149 -0
- data/app/lib/has_helpers/search/search_utils.rb +74 -0
- data/app/lib/has_helpers/search/sql_search.rb +219 -0
- data/app/lib/has_helpers/search.rb +46 -0
- data/app/models/ability.rb +233 -0
- data/app/models/has_helpers/application.rb +47 -0
- data/app/models/has_helpers/application_record.rb +7 -0
- data/app/models/has_helpers/cards/card_builder/base.rb +74 -0
- data/app/models/has_helpers/cards/card_builder/card_definition_builder.rb +486 -0
- data/app/models/has_helpers/cards/card_builder/definition_context.rb +82 -0
- data/app/models/has_helpers/cards/card_builder/field_builder.rb +142 -0
- data/app/models/has_helpers/cards/card_builder/resource_builder.rb +34 -0
- data/app/models/has_helpers/cards/card_definition.rb +41 -0
- data/app/models/has_helpers/cards/card_definition_resource.rb +19 -0
- data/app/models/has_helpers/cards/card_field.rb +39 -0
- data/app/models/has_helpers/cards/registry.rb +115 -0
- data/app/models/has_helpers/cards/role_card_field.rb +28 -0
- data/app/models/has_helpers/cards/role_resource_card.rb +41 -0
- data/app/models/has_helpers/dn_utils.rb +61 -0
- data/app/models/has_helpers/favorite.rb +20 -0
- data/app/models/has_helpers/master_record.rb +18 -0
- data/app/models/has_helpers/notification_alert.rb +52 -0
- data/app/models/has_helpers/organization.rb +16 -0
- data/app/models/has_helpers/organization_link.rb +92 -0
- data/app/models/has_helpers/organization_methods.rb +62 -0
- data/app/models/has_helpers/organization_option.rb +31 -0
- data/app/models/has_helpers/organization_resource.rb +45 -0
- data/app/models/has_helpers/pending_db_operation.rb +31 -0
- data/app/models/has_helpers/recently_viewed.rb +34 -0
- data/app/models/has_helpers/reindex_queue.rb +43 -0
- data/app/models/has_helpers/resource.rb +38 -0
- data/app/models/has_helpers/resource_group.rb +15 -0
- data/app/models/has_helpers/restriction.rb +15 -0
- data/app/models/has_helpers/restriction_operation.rb +13 -0
- data/app/models/has_helpers/role.rb +20 -0
- data/app/models/has_helpers/service_trust/audit_log.rb +20 -0
- data/app/models/has_helpers/service_trust/key.rb +56 -0
- data/app/models/has_helpers/stat.rb +13 -0
- data/app/models/has_helpers/user.rb +18 -0
- data/app/models/has_helpers/user_methods.rb +184 -0
- data/app/models/has_helpers/user_organization.rb +33 -0
- data/app/models/has_helpers/user_role.rb +27 -0
- data/app/models/has_helpers/user_session.rb +19 -0
- data/app/presenters/has_helpers/barcode_base_presenter.rb +113 -0
- data/app/presenters/has_helpers/base_presenter.rb +100 -0
- data/app/presenters/has_helpers/cacheable_item.rb +28 -0
- data/app/presenters/has_helpers/item_presenter.rb +52 -0
- data/app/presenters/has_helpers/items_presenter.rb +33 -0
- data/app/presenters/has_helpers/resource/action_presenter.rb +8 -0
- data/app/presenters/has_helpers/resource/cell_presenter.rb +52 -0
- data/app/presenters/has_helpers/resource/email_presenter.rb +34 -0
- data/app/presenters/has_helpers/resource/form_presenter.rb +76 -0
- data/app/presenters/has_helpers/resource/info_collection_presenter.rb +33 -0
- data/app/presenters/has_helpers/resource/info_presenter.rb +34 -0
- data/app/presenters/has_helpers/resource/list_presenter.rb +120 -0
- data/app/presenters/has_helpers/resource/note_presenter.rb +14 -0
- data/app/presenters/has_helpers/resource/row_presenter.rb +25 -0
- data/app/presenters/has_helpers/resource/tag_presenter.rb +31 -0
- data/app/presenters/has_helpers/search_presenter.rb +230 -0
- data/app/triggers/has_helpers/erase_denormalized_belongs_to_column_trigger.rb +85 -0
- data/app/triggers/has_helpers/limit_favorites.rb +97 -0
- data/app/utils/has_helpers/redis_configurable.rb +79 -0
- data/app/utils/has_helpers/sync_utils.rb +234 -0
- data/app/views/has_helpers/actions/_action.html.erb +31 -0
- data/app/views/has_helpers/alerts/_alert.html.erb +3 -0
- data/app/views/has_helpers/barcodes.html.erb +36 -0
- data/app/views/has_helpers/containers/_container.html.erb +3 -0
- data/app/views/has_helpers/email_notifier/system.html.erb +8 -0
- data/app/views/has_helpers/email_notifier/system.text.erb +7 -0
- data/app/views/has_helpers/enumerables/_enumerable.html.erb +1 -0
- data/app/views/has_helpers/icons/_icon.html.erb +1 -0
- data/app/views/has_helpers/render_objects/_render_object.html.erb +1 -0
- data/app/views/has_helpers/services/_service.html.erb +1 -0
- data/app/views/has_helpers/text_nodes/_text_node.html.erb +4 -0
- data/app/views/has_helpers/ui_attributes/_html_attrs.html.erb +1 -0
- data/app/workers/elasticsearch_process_queue.rb +11 -0
- data/app/workers/elasticsearch_reindex.rb +11 -0
- data/app/workers/elasticsearch_reindex_scheduler.rb +35 -0
- data/app/workers/good_job/configurable_backfill.rb +64 -0
- data/app/workers/good_job/cron_denormalization_stats_manager.rb +39 -0
- data/app/workers/good_job/denormalization_stats_worker.rb +57 -0
- data/app/workers/good_job/dn_update_worker.rb +30 -0
- data/app/workers/good_job/dn_worker.rb +47 -0
- data/app/workers/good_job/elasticsearch_old_index_cleaner_worker.rb +113 -0
- data/app/workers/good_job/elasticsearch_on_finish_reindex.rb +26 -0
- data/app/workers/good_job/elasticsearch_process_batch.rb +78 -0
- data/app/workers/good_job/elasticsearch_process_change_logs_master_worker.rb +27 -0
- data/app/workers/good_job/elasticsearch_process_change_logs_worker.rb +155 -0
- data/app/workers/good_job/elasticsearch_process_queue.rb +50 -0
- data/app/workers/good_job/elasticsearch_reindex.rb +31 -0
- data/app/workers/has_helpers/cards/orphan_card_sweeper.rb +28 -0
- data/app/workers/has_helpers/db_operations/clean_stats_worker.rb +42 -0
- data/app/workers/has_helpers/db_operations/helper_worker.rb +131 -0
- data/app/workers/has_helpers/db_operations/main_worker.rb +164 -0
- data/app/workers/has_helpers/db_operations/operations.rb +134 -0
- data/app/workers/has_helpers/db_operations/update_operations_stats_resume_worker.rb +35 -0
- data/app/workers/has_helpers/default_worker.rb +17 -0
- data/app/workers/has_helpers/good_job/notification_alert_cleanup_worker.rb +43 -0
- data/app/workers/has_helpers/service_trust/audit_log_cleanup_worker.rb +19 -0
- data/app/workers/sidekiq/elasticsearch_old_index_cleaner_worker.rb +112 -0
- data/app/workers/sidekiq/elasticsearch_process_batch.rb +87 -0
- data/app/workers/sidekiq/elasticsearch_process_queue.rb +40 -0
- data/app/workers/sidekiq/elasticsearch_reindex.rb +53 -0
- data/config/initializers/action_view.rb +7 -0
- data/config/initializers/inflections.rb +24 -0
- data/config/initializers/marginalia.rb +8 -0
- data/config/initializers/mime_types.rb +6 -0
- data/config/initializers/opentelemetry.rb +12 -0
- data/config/initializers/redis_conf.rb +40 -0
- data/config/initializers/searchkick.rb +9 -0
- data/config/initializers/will_paginate.rb +39 -0
- data/config/redis.yml +12 -0
- data/config/routes.rb +27 -0
- data/config/service_trust_routes.rb +5 -0
- data/config.ru +9 -0
- data/db/migrate/20230127194725_create_organization_table.rb +25 -0
- data/db/migrate/20230127194726_validate_organization_foreign_keys.rb +7 -0
- data/db/migrate/20230206141413_create_security_models.rb +42 -0
- data/db/migrate/20230206141513_create_restriction_model.rb +20 -0
- data/db/migrate/20230206142613_add_security_indexes.rb +14 -0
- data/db/migrate/20230206143513_security_model_constants_seed.rb +8 -0
- data/db/migrate/20230206161513_add_organization_to_security_models.rb +13 -0
- data/db/migrate/20230209121019_create_search_group_models.rb +36 -0
- data/db/migrate/20230209122919_add_search_group_indexes.rb +21 -0
- data/db/migrate/20230209181832_add_search_group_resources_type_constraint_trigger.rb +61 -0
- data/db/migrate/20230313220337_create_table_user_sessions.rb +31 -0
- data/db/migrate/20230517141106_update_resource_types.rb +12 -0
- data/db/migrate/20230518194611_add_resources_contraints.rb +17 -0
- data/db/migrate/20230518194642_create_nested_resource_model.rb +21 -0
- data/db/migrate/20230518194645_validate_security_models_constraints.rb +23 -0
- data/db/migrate/20230608125037_add_inactive_field_to_user_sessions.rb +7 -0
- data/db/migrate/20230919191525_add_parent_id_to_resources.rb +8 -0
- data/db/migrate/20230919191535_validate_parent_id_fk_resources.rb +7 -0
- data/db/migrate/20230919210456_drop_nested_resources.rb +7 -0
- data/db/migrate/20231222135620_add_user_role.rb +19 -0
- data/db/migrate/20240108172021_create_favorites_table.rb +20 -0
- data/db/migrate/20240108190209_create_organization_link_table_if_doesnt_exists.rb +31 -0
- data/db/migrate/20240109211445_validate_fks_org_links.rb +9 -0
- data/db/migrate/20240110135440_create_recently_vieweds.rb +20 -0
- data/db/migrate/20240112185312_link_type_options_seed.rb +7 -0
- data/db/migrate/20240116173201_organization_link_resource_tab_constraints.rb +19 -0
- data/db/migrate/20240131160949_add_user_organizations_table.rb +32 -0
- data/db/migrate/20240212132519_add_organization_in_user_sessions.rb +13 -0
- data/db/migrate/20240227135052_add_user_organization_composite_fks.rb +32 -0
- data/db/migrate/20240312193501_update_organization_links.rb +11 -0
- data/db/migrate/20240426185902_add_user_organizations_current_organization_column.rb +12 -0
- data/db/migrate/20240429214601_add_primary_trigger.rb +10 -0
- data/db/migrate/20241112131819_add_json_file_format_seed.rb +7 -0
- data/db/migrate/20250520133417_create_restriction_operations.rb +18 -0
- data/db/migrate/20250520133420_validate_create_restriction_operations.rb +8 -0
- data/db/migrate/20250520140642_add_indexes_to_restrictions.rb +9 -0
- data/db/migrate/20250529130741_create_notification_alerts_table.rb +28 -0
- data/db/migrate/20250530223332_create_data_migrations_table.rb +19 -0
- data/db/migrate/20250605121622_seed_notification_alert_status.rb +7 -0
- data/db/migrate/20250605131439_seed_notification_alert_types.rb +7 -0
- data/db/migrate/20250606173128_update_notification_alert_length_constraint.rb +18 -0
- data/db/migrate/20250606174043_validate_notification_alert_length_constraints.rb +8 -0
- data/db/migrate/20250624183000_add_data_import_alert_type.rb +11 -0
- data/db/migrate/20250722183935_create_organization_options_table.rb +38 -0
- data/db/migrate/20250722192724_validate_organization_options_fks_and_constraints.rb +32 -0
- data/db/migrate/20250722192936_add_indexes_to_organization_options_table.rb +15 -0
- data/db/migrate/20250915132448_add_column_restrictions_hash.rb +7 -0
- data/db/migrate/20250917143211_add_column_permissions_hash.rb +7 -0
- data/db/migrate/20251001145950_add_trust_this_device.rb +7 -0
- data/db/migrate/20251021130835_add_backend_urls_to_applications_table.rb +13 -0
- data/db/migrate/20251021172715_validate_backend_urls_constraints_in_applications.rb +9 -0
- data/db/migrate/20251030200020_create_card_definitions.rb +23 -0
- data/db/migrate/20251030201012_create_card_definition_resources.rb +24 -0
- data/db/migrate/20251030201236_create_card_fields.rb +34 -0
- data/db/migrate/20251103194317_create_role_resource_cards.rb +37 -0
- data/db/migrate/20251103194426_create_role_card_fields.rb +34 -0
- data/db/migrate/20251107173218_validate_columns_from_cards.rb +17 -0
- data/db/migrate/20251111173212_add_column_application_array.rb +7 -0
- data/db/migrate/20251112203326_add_card_types.rb +10 -0
- data/db/migrate/20251115120000_add_virtual_cards_support.rb +28 -0
- data/db/migrate/20251202231256_add_org_scoped_fk_role_resource_cards_to_roles.rb +14 -0
- data/db/migrate/20260105134504_add_accessor_field_resource_type.rb +7 -0
- data/db/migrate/20260115123000_add_default_visibility_to_card_definitions.rb +9 -0
- data/db/migrate/20260120175037_is_new_admin.rb +9 -0
- data/db/migrate/20260122392008_add_stats_table.rb +17 -0
- data/db/migrate/20260414204718_add_index_to_stats_table.rb +10 -0
- data/db/migrate/20260509120000_create_service_trust_keys.rb +25 -0
- data/db/migrate/20260509120001_create_service_trust_audit_logs.rb +26 -0
- data/db/migrate/20260511120000_add_direction_to_service_trust_audit_logs.rb +17 -0
- data/db/migrate/20260511121000_remove_role_fk_from_role_resource_cards.rb +19 -0
- data/db/migrate/20260511121001_add_disabled_at_to_role_resource_cards.rb +10 -0
- data/db/migrate/20260605120100_seed_hover_card_options.rb +8 -0
- data/db/migrate/20260608120000_seed_badge_list_card_data_type.rb +7 -0
- data/db/migrate/20260727000000_add_two_factor_trust_id_to_user_sessions.rb +11 -0
- data/db/seeds.rb +14 -0
- data/docs/Elasticsearch.md +23 -0
- data/docs/Search_API.md +126 -0
- data/docs/cards_role_proxy.md +107 -0
- data/docs/factory_api.md +135 -0
- data/has-helpers-pr-289-pipeline.yaml +16 -0
- data/has-helpers-pr-298-pipeline.yaml +15 -0
- data/has_helpers.gemspec +68 -0
- data/lib/active_record/migration/active_migration_patch.rb +123 -0
- data/lib/generators/has_helpers/install/USAGE +8 -0
- data/lib/generators/has_helpers/install/install_generator.rb +22 -0
- data/lib/generators/has_helpers/install/templates/migrate/has_helpers_initial_setup.rb +26 -0
- data/lib/has_helpers/active_record/base.rb +50 -0
- data/lib/has_helpers/active_record/date_range.rb +228 -0
- data/lib/has_helpers/active_record/nested_resource.rb +58 -0
- data/lib/has_helpers/active_record/validation.rb +63 -0
- data/lib/has_helpers/active_record.rb +520 -0
- data/lib/has_helpers/app/command.rb +107 -0
- data/lib/has_helpers/app.rb +10 -0
- data/lib/has_helpers/assets_precompile_helper.rb +20 -0
- data/lib/has_helpers/attributes.rb +196 -0
- data/lib/has_helpers/aws.rb +67 -0
- data/lib/has_helpers/cards/cache.rb +49 -0
- data/lib/has_helpers/cards/config.rb +42 -0
- data/lib/has_helpers/cards/remote_role.rb +27 -0
- data/lib/has_helpers/cards/remote_roles.rb +75 -0
- data/lib/has_helpers/cards/roles.rb +55 -0
- data/lib/has_helpers/cards.rb +34 -0
- data/lib/has_helpers/concerns/hydrate_concern.rb +76 -0
- data/lib/has_helpers/concerns/importable_accessors.rb +25 -0
- data/lib/has_helpers/concerns/restrictions_parseable.rb +51 -0
- data/lib/has_helpers/config.rb +11 -0
- data/lib/has_helpers/constant.rb +578 -0
- data/lib/has_helpers/constraints.rb +10 -0
- data/lib/has_helpers/core_ext/array.rb +28 -0
- data/lib/has_helpers/core_ext/date/infinity.rb +25 -0
- data/lib/has_helpers/core_ext/date.rb +39 -0
- data/lib/has_helpers/core_ext/enumerable.rb +20 -0
- data/lib/has_helpers/core_ext/false_class.rb +14 -0
- data/lib/has_helpers/core_ext/float.rb +18 -0
- data/lib/has_helpers/core_ext/hash.rb +71 -0
- data/lib/has_helpers/core_ext/integer.rb +18 -0
- data/lib/has_helpers/core_ext/nil_class.rb +30 -0
- data/lib/has_helpers/core_ext/object.rb +60 -0
- data/lib/has_helpers/core_ext/proc.rb +16 -0
- data/lib/has_helpers/core_ext/string.rb +81 -0
- data/lib/has_helpers/core_ext/symbol.rb +17 -0
- data/lib/has_helpers/core_ext/true_class.rb +14 -0
- data/lib/has_helpers/cursor.rb +46 -0
- data/lib/has_helpers/data_migration/base.rb +293 -0
- data/lib/has_helpers/data_migration/large_worker.rb +20 -0
- data/lib/has_helpers/data_migration/master_worker.rb +33 -0
- data/lib/has_helpers/data_migration/migrator.rb +83 -0
- data/lib/has_helpers/data_migration/model.rb +18 -0
- data/lib/has_helpers/data_migration/small_worker.rb +20 -0
- data/lib/has_helpers/data_migration.rb +8 -0
- data/lib/has_helpers/engine.rb +47 -0
- data/lib/has_helpers/extensions.rb +17 -0
- data/lib/has_helpers/factory_api.rb +47 -0
- data/lib/has_helpers/factory_scenario/definition.rb +33 -0
- data/lib/has_helpers/factory_scenario/dsl.rb +80 -0
- data/lib/has_helpers/factory_scenario/factory_bot_override.rb +53 -0
- data/lib/has_helpers/factory_scenario/registry.rb +31 -0
- data/lib/has_helpers/factory_scenario/runner.rb +285 -0
- data/lib/has_helpers/factory_scenario.rb +27 -0
- data/lib/has_helpers/fixed_expiration_time_cache_session_store.rb +20 -0
- data/lib/has_helpers/flattener/association.rb +140 -0
- data/lib/has_helpers/flattener/attribute.rb +42 -0
- data/lib/has_helpers/flattener/base.rb +428 -0
- data/lib/has_helpers/flattener/column/types.rb +71 -0
- data/lib/has_helpers/flattener/column.rb +97 -0
- data/lib/has_helpers/flattener/pivot.rb +49 -0
- data/lib/has_helpers/flattener/reset.rb +33 -0
- data/lib/has_helpers/flattener/resource.rb +114 -0
- data/lib/has_helpers/flattener/resource_generator.rb +21 -0
- data/lib/has_helpers/flattener/utils.rb +14 -0
- data/lib/has_helpers/flattener.rb +53 -0
- data/lib/has_helpers/hash_accessors.rb +62 -0
- data/lib/has_helpers/helpers/application.rb +291 -0
- data/lib/has_helpers/index/config.rb +15 -0
- data/lib/has_helpers/lazy_config.rb +61 -0
- data/lib/has_helpers/resource_importer.rb +260 -0
- data/lib/has_helpers/resources.rb +127 -0
- data/lib/has_helpers/rspec/constants.rb +61 -0
- data/lib/has_helpers/rspec/factories.rb +11 -0
- data/lib/has_helpers/rspec.rb +22 -0
- data/lib/has_helpers/sentry/graphql_trace.rb +37 -0
- data/lib/has_helpers/serializer.rb +41 -0
- data/lib/has_helpers/service_trust/audit.rb +45 -0
- data/lib/has_helpers/service_trust/authorization.rb +34 -0
- data/lib/has_helpers/service_trust/bearer_token.rb +23 -0
- data/lib/has_helpers/service_trust/capability.rb +32 -0
- data/lib/has_helpers/service_trust/client/response.rb +13 -0
- data/lib/has_helpers/service_trust/client/retry.rb +35 -0
- data/lib/has_helpers/service_trust/client.rb +128 -0
- data/lib/has_helpers/service_trust/configuration.rb +76 -0
- data/lib/has_helpers/service_trust/engine.rb +10 -0
- data/lib/has_helpers/service_trust/errors.rb +32 -0
- data/lib/has_helpers/service_trust/graphql/authorizable.rb +72 -0
- data/lib/has_helpers/service_trust/graphql_client.rb +54 -0
- data/lib/has_helpers/service_trust/jwks_client.rb +133 -0
- data/lib/has_helpers/service_trust/jwt_codec.rb +45 -0
- data/lib/has_helpers/service_trust/key_manager.rb +160 -0
- data/lib/has_helpers/service_trust/rate_limiter.rb +27 -0
- data/lib/has_helpers/service_trust/replay_cache.rb +26 -0
- data/lib/has_helpers/service_trust/signer.rb +47 -0
- data/lib/has_helpers/service_trust/test.rb +60 -0
- data/lib/has_helpers/service_trust/verifier.rb +85 -0
- data/lib/has_helpers/service_trust/verify_middleware.rb +55 -0
- data/lib/has_helpers/service_trust.rb +51 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_addresses.rb +42 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_advisors.rb +272 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_emails.rb +37 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_organizations.rb +48 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_people.rb +34 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_phones.rb +41 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_states.rb +26 -0
- data/lib/has_helpers/test_helpers/factory_data/unit_webs.rb +31 -0
- data/lib/has_helpers/test_helpers/shoulda_helpers.rb +249 -0
- data/lib/has_helpers/ui_attributes.rb +39 -0
- data/lib/has_helpers/utils/action.rb +87 -0
- data/lib/has_helpers/utils/active_record_utils.rb +40 -0
- data/lib/has_helpers/utils/alert.rb +42 -0
- data/lib/has_helpers/utils/container.rb +46 -0
- data/lib/has_helpers/utils/dataset.rb +34 -0
- data/lib/has_helpers/utils/email_notifier.rb +15 -0
- data/lib/has_helpers/utils/icon.rb +66 -0
- data/lib/has_helpers/utils/input.rb +45 -0
- data/lib/has_helpers/utils/log_notifier.rb +79 -0
- data/lib/has_helpers/utils/render_object.rb +32 -0
- data/lib/has_helpers/utils/s3_utils.rb +37 -0
- data/lib/has_helpers/utils/service.rb +87 -0
- data/lib/has_helpers/utils/slack_conf.rb +31 -0
- data/lib/has_helpers/utils/slack_notifier.rb +42 -0
- data/lib/has_helpers/utils/text_node.rb +34 -0
- data/lib/has_helpers/utils/user_restrictions.rb +266 -0
- data/lib/has_helpers/utils.rb +19 -0
- data/lib/has_helpers/version.rb +6 -0
- data/lib/has_helpers/web_socket_publisher.rb +20 -0
- data/lib/has_helpers/webhook.rb +17 -0
- data/lib/has_helpers.rb +63 -0
- data/lib/hq/resource.rb +55 -0
- data/lib/hq/structure/inserts.rb +176 -0
- data/lib/hq/structure.rb +115 -0
- data/lib/tasks/has_helpers/service_trust.rake +39 -0
- data/script/rails +10 -0
- data/sorbet/config +5 -0
- data/sorbet/rbi/gems/actionpack.rbi +1361 -0
- data/sorbet/rbi/gems/activemodel.rbi +755 -0
- data/sorbet/rbi/gems/activerecord.rbi +4713 -0
- data/sorbet/rbi/gems/activesupport.rbi +1970 -0
- data/sorbet/rbi/gems/barby.rbi +129 -0
- data/sorbet/rbi/gems/better_errors.rbi +155 -0
- data/sorbet/rbi/gems/binding_of_caller.rbi +22 -0
- data/sorbet/rbi/gems/byebug.rbi +19 -0
- data/sorbet/rbi/gems/chronic.rbi +480 -0
- data/sorbet/rbi/gems/chunky_png.rbi +510 -0
- data/sorbet/rbi/gems/climate_control.rbi +45 -0
- data/sorbet/rbi/gems/coderay.rbi +91 -0
- data/sorbet/rbi/gems/concurrent-ruby.rbi +1587 -0
- data/sorbet/rbi/gems/debug_inspector.rbi +18 -0
- data/sorbet/rbi/gems/erubi.rbi +26 -0
- data/sorbet/rbi/gems/holidays.rbi +362 -0
- data/sorbet/rbi/gems/i18n.rbi +132 -0
- data/sorbet/rbi/gems/method_source.rbi +63 -0
- data/sorbet/rbi/gems/mime-types-data.rbi +16 -0
- data/sorbet/rbi/gems/mime-types.rbi +217 -0
- data/sorbet/rbi/gems/mimemagic.rbi +36 -0
- data/sorbet/rbi/gems/minitest.rbi +282 -0
- data/sorbet/rbi/gems/mustache.rbi +151 -0
- data/sorbet/rbi/gems/paperclip.rbi +644 -0
- data/sorbet/rbi/gems/parallel.rbi +81 -0
- data/sorbet/rbi/gems/parallel_tests.rbi +27 -0
- data/sorbet/rbi/gems/pry-rails.rbi +71 -0
- data/sorbet/rbi/gems/pry.rbi +1964 -0
- data/sorbet/rbi/gems/rack.rbi +228 -0
- data/sorbet/rbi/gems/railties.rbi +364 -0
- data/sorbet/rbi/gems/rspec-core.rbi +1704 -0
- data/sorbet/rbi/gems/rspec-expectations.rbi +389 -0
- data/sorbet/rbi/gems/rspec-support.rbi +206 -0
- data/sorbet/rbi/gems/rspec.rbi +14 -0
- data/sorbet/rbi/gems/spreadsheet_architect.rbi +10 -0
- data/sorbet/rbi/gems/sprockets.rbi +659 -0
- data/sorbet/rbi/gems/terrapin.rbi +115 -0
- data/sorbet/rbi/gems/testhq.rbi +14 -0
- data/sorbet/rbi/gems/thor.rbi +482 -0
- data/sorbet/rbi/gems/thread_safe.rbi +81 -0
- data/sorbet/rbi/gems/tzinfo.rbi +407 -0
- data/sorbet/rbi/gems/zeitwerk.rbi +131 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +35111 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +59974 -0
- data/sorbet/rbi/sorbet-typed/lib/actionmailer/all/actionmailer.rbi +13 -0
- data/sorbet/rbi/sorbet-typed/lib/actionpack/all/actionpack.rbi +855 -0
- data/sorbet/rbi/sorbet-typed/lib/actionview/all/actionview.rbi +314 -0
- data/sorbet/rbi/sorbet-typed/lib/activemodel/all/activemodel.rbi +423 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/>=5.2/activerecord.rbi +17 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/all/activerecord.rbi +1415 -0
- data/sorbet/rbi/sorbet-typed/lib/activerecord/~>6.0.0/activerecord.rbi +475 -0
- data/sorbet/rbi/sorbet-typed/lib/activestorage/>=6.0.0/activestorage.rbi +19 -0
- data/sorbet/rbi/sorbet-typed/lib/activestorage/all/activestorage.rbi +173 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/>=6.0.0.rc1/activesupport.rbi +23 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/all/activesupport.rbi +625 -0
- data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +8684 -0
- data/sorbet/rbi/sorbet-typed/lib/minitest/all/minitest.rbi +99 -0
- data/sorbet/rbi/sorbet-typed/lib/railties/all/railties.rbi +25 -0
- data/sorbet/rbi/sorbet-typed/lib/rainbow/all/rainbow.rbi +254 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +4222 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +111 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +543 -0
- data/sorbet/rbi/todo.rbi +244 -0
- data/spec/commands/cards/available_cards_command_spec.rb +90 -0
- data/spec/commands/cards/card_data_command_spec.rb +1048 -0
- data/spec/constructors/has_helpers/base_constructor_spec.rb +49 -0
- data/spec/controllers/has_helpers/controller_spec.rb +71 -0
- data/spec/controllers/has_helpers/xlsx_export_spec.rb +96 -0
- data/spec/factories/advisors.rb +20 -0
- data/spec/factories/anonymous_cowards.rb +5 -0
- data/spec/factories/applications.rb +5 -0
- data/spec/factories/appointments.rb +6 -0
- data/spec/factories/attachment.rb +15 -0
- data/spec/factories/audits.rb +5 -0
- data/spec/factories/basic_schedules.rb +12 -0
- data/spec/factories/cards/card_definition_resources.rb +7 -0
- data/spec/factories/cards/card_definitions.rb +11 -0
- data/spec/factories/cards/card_fields.rb +22 -0
- data/spec/factories/cards/role_card_fields.rb +17 -0
- data/spec/factories/cards/role_resource_cards.rb +12 -0
- data/spec/factories/constant_definition.rb +7 -0
- data/spec/factories/contracts.rb +10 -0
- data/spec/factories/data_migration_models.rb +9 -0
- data/spec/factories/demographics.rb +22 -0
- data/spec/factories/events.rb +21 -0
- data/spec/factories/firms.rb +21 -0
- data/spec/factories/imports.rb +9 -0
- data/spec/factories/meetups.rb +13 -0
- data/spec/factories/organizations.rb +13 -0
- data/spec/factories/policies.rb +7 -0
- data/spec/factories/policy_notes.rb +9 -0
- data/spec/factories/read_only_values.rb +7 -0
- data/spec/factories/resources.rb +7 -0
- data/spec/factories/roles.rb +11 -0
- data/spec/factories/schedules.rb +13 -0
- data/spec/factories/shared/flattener/attributes.rb +10 -0
- data/spec/factories/shared/flattener/columns.rb +6 -0
- data/spec/factories/shared/flattener/resources.rb +5 -0
- data/spec/factories/templates.rb +12 -0
- data/spec/factories/user_organizations.rb +23 -0
- data/spec/factories/user_session.rb +11 -0
- data/spec/factories/users.rb +55 -0
- data/spec/fixtures/sample_config.yml +3 -0
- data/spec/graphql/has_helpers/mutations/external_data_sync_spec.rb +101 -0
- data/spec/graphql/has_helpers/resolvers/cards/available_cards_spec.rb +36 -0
- data/spec/graphql/has_helpers/resolvers/cards/card_data_spec.rb +42 -0
- data/spec/graphql/has_helpers/resolvers/cards/hover_card_data_spec.rb +59 -0
- data/spec/has_helpers/cards/cache_spec.rb +58 -0
- data/spec/has_helpers/cards/config_spec.rb +68 -0
- data/spec/has_helpers/cards/orphan_card_sweeper_spec.rb +97 -0
- data/spec/has_helpers/cards/remote_role_spec.rb +17 -0
- data/spec/has_helpers/cards/remote_roles_spec.rb +97 -0
- data/spec/has_helpers/cards/roles_spec.rb +52 -0
- data/spec/has_helpers/cards/smoke_spec.rb +168 -0
- data/spec/has_helpers/cards/support.rb +52 -0
- data/spec/has_helpers/resolvers/internal/roles_spec.rb +73 -0
- data/spec/has_helpers/service_trust/audit_log_cleanup_worker_spec.rb +33 -0
- data/spec/has_helpers/service_trust/audit_spec.rb +70 -0
- data/spec/has_helpers/service_trust/authenticated_as_service_spec.rb +65 -0
- data/spec/has_helpers/service_trust/authorization_spec.rb +37 -0
- data/spec/has_helpers/service_trust/capability_spec.rb +35 -0
- data/spec/has_helpers/service_trust/client_spec.rb +129 -0
- data/spec/has_helpers/service_trust/configuration_spec.rb +35 -0
- data/spec/has_helpers/service_trust/engine_spec.rb +13 -0
- data/spec/has_helpers/service_trust/errors_spec.rb +23 -0
- data/spec/has_helpers/service_trust/graphql_authentication_spec.rb +59 -0
- data/spec/has_helpers/service_trust/graphql_authorizable_spec.rb +91 -0
- data/spec/has_helpers/service_trust/graphql_client_spec.rb +47 -0
- data/spec/has_helpers/service_trust/jwks_client_spec.rb +85 -0
- data/spec/has_helpers/service_trust/jwks_controller_spec.rb +47 -0
- data/spec/has_helpers/service_trust/jwt_codec_spec.rb +30 -0
- data/spec/has_helpers/service_trust/key_manager_spec.rb +80 -0
- data/spec/has_helpers/service_trust/key_spec.rb +52 -0
- data/spec/has_helpers/service_trust/rake_tasks_spec.rb +58 -0
- data/spec/has_helpers/service_trust/rate_limiter_spec.rb +31 -0
- data/spec/has_helpers/service_trust/replay_cache_spec.rb +29 -0
- data/spec/has_helpers/service_trust/signer_verifier_spec.rb +159 -0
- data/spec/has_helpers/service_trust/smoke_spec.rb +216 -0
- data/spec/has_helpers/service_trust/support.rb +121 -0
- data/spec/has_helpers/service_trust/test_module_spec.rb +39 -0
- data/spec/has_helpers/service_trust/verify_middleware_spec.rb +82 -0
- data/spec/helpers/application_spec.rb +155 -0
- data/spec/importers/cards/importer_spec.rb +861 -0
- data/spec/internal/app/assets/config/manifest.js +0 -0
- data/spec/internal/app/constants/cat_egory.rb +33 -0
- data/spec/internal/app/constants/color.rb +19 -0
- data/spec/internal/app/constants/exclude_group_nil_constant.rb +5 -0
- data/spec/internal/app/constants/foo.rb +6 -0
- data/spec/internal/app/constants/fruit.rb +3 -0
- data/spec/internal/app/constants/generic_group_example.rb +12 -0
- data/spec/internal/app/constants/my_constant.rb +4 -0
- data/spec/internal/app/constants/product.rb +3 -0
- data/spec/internal/app/constants/shirt_size.rb +18 -0
- data/spec/internal/app/constants/simple_option.rb +14 -0
- data/spec/internal/app/constants/status.rb +5 -0
- data/spec/internal/app/constructors/organization_constructor.rb +4 -0
- data/spec/internal/app/controllers/application_controller.rb +27 -0
- data/spec/internal/app/controllers/search_extensions.rb +3 -0
- data/spec/internal/app/indices/advisor_index.rb +35 -0
- data/spec/internal/app/indices/contract_index.rb +52 -0
- data/spec/internal/app/indices/firm_index.rb +16 -0
- data/spec/internal/app/indices/policy_index.rb +20 -0
- data/spec/internal/app/models/advisor.rb +24 -0
- data/spec/internal/app/models/agency.rb +3 -0
- data/spec/internal/app/models/anonymous_coward.rb +5 -0
- data/spec/internal/app/models/another_event.rb +2 -0
- data/spec/internal/app/models/appointment.rb +3 -0
- data/spec/internal/app/models/attachment.rb +10 -0
- data/spec/internal/app/models/basic_schedule.rb +6 -0
- data/spec/internal/app/models/beneficiary.rb +6 -0
- data/spec/internal/app/models/client.rb +5 -0
- data/spec/internal/app/models/contract.rb +9 -0
- data/spec/internal/app/models/demographic.rb +4 -0
- data/spec/internal/app/models/division.rb +3 -0
- data/spec/internal/app/models/event.rb +10 -0
- data/spec/internal/app/models/event_template.rb +1 -0
- data/spec/internal/app/models/firm.rb +18 -0
- data/spec/internal/app/models/has_audits/audit.rb +15 -0
- data/spec/internal/app/models/import.rb +7 -0
- data/spec/internal/app/models/meetup.rb +8 -0
- data/spec/internal/app/models/organization.rb +17 -0
- data/spec/internal/app/models/organization_event.rb +5 -0
- data/spec/internal/app/models/policy.rb +16 -0
- data/spec/internal/app/models/policy_holder.rb +7 -0
- data/spec/internal/app/models/policy_note.rb +8 -0
- data/spec/internal/app/models/project.rb +3 -0
- data/spec/internal/app/models/read_only_value.rb +8 -0
- data/spec/internal/app/models/schedule.rb +12 -0
- data/spec/internal/app/models/template.rb +9 -0
- data/spec/internal/app/models/user.rb +31 -0
- data/spec/internal/app/models/user_organization.rb +17 -0
- data/spec/internal/app/views/has_lists/lists/_table.html.erb +1 -0
- data/spec/internal/config/database-standard.yml +24 -0
- data/spec/internal/config/initializers/resources.rb +19 -0
- data/spec/internal/config/routes.rb +19 -0
- data/spec/internal/config/storage.yml +3 -0
- data/spec/internal/db/good_job_schema.rb +141 -0
- data/spec/internal/db/schema.rb +334 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/flattener/base_spec.rb +93 -0
- data/spec/lib/flattener/column/types_spec.rb +65 -0
- data/spec/lib/has_helpers/active_record/base_spec.rb +53 -0
- data/spec/lib/has_helpers/active_record/date_range_spec.rb +498 -0
- data/spec/lib/has_helpers/active_record/lookup_model_spec.rb +408 -0
- data/spec/lib/has_helpers/active_record/nested_resource_spec.rb +43 -0
- data/spec/lib/has_helpers/app/command/reports/generator_specs.rb +887 -0
- data/spec/lib/has_helpers/app/command_spec.rb +117 -0
- data/spec/lib/has_helpers/app/support/mocks/graphql_reports_helpers.rb +96 -0
- data/spec/lib/has_helpers/app/support/mocks/reports_api_mock.rb +47 -0
- data/spec/lib/has_helpers/attributes_spec.rb +220 -0
- data/spec/lib/has_helpers/aws_spec.rb +126 -0
- data/spec/lib/has_helpers/concerns/hydrate_concern_spec.rb +473 -0
- data/spec/lib/has_helpers/constant/definition_spec.rb +128 -0
- data/spec/lib/has_helpers/constant_spec.rb +432 -0
- data/spec/lib/has_helpers/core_ext/array_spec.rb +22 -0
- data/spec/lib/has_helpers/core_ext/date/infinity_spec.rb +67 -0
- data/spec/lib/has_helpers/core_ext/date_spec.rb +27 -0
- data/spec/lib/has_helpers/core_ext/false_class_spec.rb +7 -0
- data/spec/lib/has_helpers/core_ext/float_spec.rb +9 -0
- data/spec/lib/has_helpers/core_ext/hash_spec.rb +48 -0
- data/spec/lib/has_helpers/core_ext/integer_spec.rb +9 -0
- data/spec/lib/has_helpers/core_ext/nil_class_spec.rb +17 -0
- data/spec/lib/has_helpers/core_ext/object_spec.rb +54 -0
- data/spec/lib/has_helpers/core_ext/proc_spec.rb +24 -0
- data/spec/lib/has_helpers/core_ext/string_spec.rb +154 -0
- data/spec/lib/has_helpers/core_ext/true_class_spec.rb +7 -0
- data/spec/lib/has_helpers/data_migration/base_spec.rb +470 -0
- data/spec/lib/has_helpers/data_migration/large_worker_spec.rb +34 -0
- data/spec/lib/has_helpers/data_migration/master_worker_spec.rb +51 -0
- data/spec/lib/has_helpers/data_migration/migrator_spec.rb +113 -0
- data/spec/lib/has_helpers/data_migration/model_spec.rb +52 -0
- data/spec/lib/has_helpers/data_migration/small_worker_spec.rb +34 -0
- data/spec/lib/has_helpers/good_job/notification_alert_cleanup_worker_spec.rb +89 -0
- data/spec/lib/has_helpers/hash_accessors_spec.rb +66 -0
- data/spec/lib/has_helpers/index_spec.rb +442 -0
- data/spec/lib/has_helpers/lazy_config_spec.rb +31 -0
- data/spec/lib/has_helpers/organization_merge_spec.rb +88 -0
- data/spec/lib/has_helpers/resource_importer_spec.rb +119 -0
- data/spec/lib/has_helpers/rspec_spec.rb +16 -0
- data/spec/lib/has_helpers/search/provider_spec.rb +26 -0
- data/spec/lib/has_helpers/search/search_utils_spec.rb +134 -0
- data/spec/lib/has_helpers/sentry/graphql_trace_spec.rb +140 -0
- data/spec/lib/has_helpers/ui_attributes_spec.rb +42 -0
- data/spec/lib/has_helpers/utils/action_spec.rb +49 -0
- data/spec/lib/has_helpers/utils/alert_spec.rb +33 -0
- data/spec/lib/has_helpers/utils/dataset_spec.rb +10 -0
- data/spec/lib/has_helpers/utils/icon_spec.rb +23 -0
- data/spec/lib/has_helpers/utils/input_spec.rb +40 -0
- data/spec/lib/has_helpers/utils/log_notifier_spec.rb +25 -0
- data/spec/lib/has_helpers/utils/render_object_spec.rb +17 -0
- data/spec/lib/has_helpers/utils/s3_utils_spec.rb +78 -0
- data/spec/lib/has_helpers/utils/service_spec.rb +79 -0
- data/spec/lib/has_helpers/utils/slack_notifier_spec.rb +70 -0
- data/spec/lib/has_helpers/utils/user_restrictions_spec.rb +343 -0
- data/spec/lib/hq/structure/inserts_spec.rb +152 -0
- data/spec/lib/hq/structure_spec.rb +12 -0
- data/spec/models/cards/base_spec.rb +149 -0
- data/spec/models/cards/card_definition_resource_spec.rb +103 -0
- data/spec/models/cards/card_definition_spec.rb +50 -0
- data/spec/models/cards/card_field_spec.rb +46 -0
- data/spec/models/cards/field_builder_spec.rb +318 -0
- data/spec/models/cards/registry_spec.rb +147 -0
- data/spec/models/cards/role_card_field_spec.rb +111 -0
- data/spec/models/cards/role_resource_card_spec.rb +112 -0
- data/spec/models/has_helpers/master_record_spec.rb +20 -0
- data/spec/models/has_helpers/user_organization_spec.rb +28 -0
- data/spec/models/has_helpers/user_session_spec.rb +16 -0
- data/spec/presenters/base_presenter_spec.rb +166 -0
- data/spec/rails_helper.rb +119 -0
- data/spec/requests/has_helpers/factory_controller_spec.rb +159 -0
- data/spec/requests/has_helpers/health_check_controller_spec.rb +37 -0
- data/spec/scenarios/empty_setup.rb +6 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/has_helpers/database_helpers.rb +12 -0
- data/spec/utils/sync_utils_spec.rb +233 -0
- data/spec/workers/goodjob/elasticsearch_process_batch_spec.rb +94 -0
- data/spec/workers/goodjob/elasticsearch_process_change_logs_master_worker_spec.rb +40 -0
- data/spec/workers/goodjob/elasticsearch_process_change_logs_worker_spec.rb +82 -0
- data/spec/workers/goodjob/elasticsearch_process_queue_spec.rb +89 -0
- data/spec/workers/goodjob/elasticsearch_reindex_spec.rb +49 -0
- metadata +1593 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HasHelpers::UserMethods
|
|
4
|
+
REMOTE_ATTRS = %w[first_name last_name photo_file_name photo_content_type photo_file_size photo_updated_at]
|
|
5
|
+
|
|
6
|
+
# Including apps' user models can use this to set common settings
|
|
7
|
+
# for user photos.
|
|
8
|
+
PHOTO_OPTIONS = {
|
|
9
|
+
# Always use the hqadmin bucket for user photos
|
|
10
|
+
bucket: "hqadmin-#{::HasUtils::Env.current_environment}", # TODO: upgrade paperclip to 6 and you can use -> { "#{::HasHelpers::Application::HQADMIN.name}-#{ ::HasUtils::Env.current_environment }" },
|
|
11
|
+
}.freeze
|
|
12
|
+
|
|
13
|
+
def self.included(base)
|
|
14
|
+
base.class_eval do
|
|
15
|
+
attr_accessor :skip_update_master_record # When set to a truthy value this prevents pushing changes to the AdminHQ API on save.
|
|
16
|
+
attr_accessor :master_record_attributes # Set with the attributes returned from pushing user changes to the AdminHQ API
|
|
17
|
+
attr_accessor :extra_attributes # Stores information retrieved from hqsso. These can be handled every time cas_extra_attributes=
|
|
18
|
+
# is called by creating a method called handle_extra_attributes on the class/module that includes this module.
|
|
19
|
+
|
|
20
|
+
def ip_whitelist
|
|
21
|
+
# The support user does not have an IP whitelist.
|
|
22
|
+
# Support users can log in from anywhere.
|
|
23
|
+
return nil if is_support?
|
|
24
|
+
[*super, *organization.ip_whitelist].presence
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
serialize :permissions_hash, type: Hash
|
|
28
|
+
serialize :applications_array, type: Array
|
|
29
|
+
|
|
30
|
+
# Runs within the save transaction. Pushes changes to IAMHQ
|
|
31
|
+
# Do not run this callback from within IAMHQ
|
|
32
|
+
after_save :update_master_record,
|
|
33
|
+
unless: -> { HasHelpers::Application.current_application == ::HasHelpers::Application::HQADMIN || skip_update_master_record }
|
|
34
|
+
|
|
35
|
+
after_commit :save_master_record_attributes, if: :master_record_attributes
|
|
36
|
+
end
|
|
37
|
+
base.send(:include, InstanceMethods)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module InstanceMethods
|
|
41
|
+
def cas_extra_attributes=(extra_attributes)
|
|
42
|
+
org_id = extra_attributes["organization_id_or_uuid"] || extra_attributes["organization_id"]
|
|
43
|
+
org = ::HasHelpers::Organization.find_or_initialize_by(id: org_id)
|
|
44
|
+
time_zone = ::TimeZone.find_by(name: extra_attributes["organization_time_zone_name"])
|
|
45
|
+
if time_zone.nil?
|
|
46
|
+
time_zone = org.time_zone
|
|
47
|
+
data = {
|
|
48
|
+
message: "TimeZone Lookup Failed",
|
|
49
|
+
organization: org.inspect,
|
|
50
|
+
user: self.inspect,
|
|
51
|
+
extra_attributes: extra_attributes,
|
|
52
|
+
}.inspect
|
|
53
|
+
HasHelpers::LogNotifier.notify(
|
|
54
|
+
HasHelpers::HQException.new(data, backtrace: caller)
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
organization_attributes = {
|
|
59
|
+
code_name: extra_attributes["organization_code_name"],
|
|
60
|
+
domain: extra_attributes["organization_domain"],
|
|
61
|
+
ip_whitelist: extra_attributes["organization_ip_whitelist"],
|
|
62
|
+
is_use_roles_for_authorization: extra_attributes["organization_is_use_roles_for_authorization"],
|
|
63
|
+
name: extra_attributes["organization_name"],
|
|
64
|
+
time_zone_id: time_zone.id,
|
|
65
|
+
}
|
|
66
|
+
organization_attributes[:is_active] = extra_attributes["organization_is_active"] if ::HasHelpers::Organization.column_names.include?("is_active")
|
|
67
|
+
organization_attributes[:start_date] = extra_attributes["organization_go_live_date"] if org.start_date.blank?
|
|
68
|
+
|
|
69
|
+
if !org.update(organization_attributes) && ::Rails.application.config.x.support_email_address.present?
|
|
70
|
+
notifier_body = {
|
|
71
|
+
"User" => username,
|
|
72
|
+
"Class" => self.class.name,
|
|
73
|
+
"Org ID" => org.id,
|
|
74
|
+
"Organization name" => org.name,
|
|
75
|
+
"Org name of extra attrs" => extra_attributes["organization_name"] || "no attr found",
|
|
76
|
+
"Test org name" => extra_attributes["organization_name_test"] || "no name found",
|
|
77
|
+
"Created at" => extra_attributes["created_at_test"],
|
|
78
|
+
"Errors" => org.errors.full_messages.join(", "),
|
|
79
|
+
"Backtrace" => Thread.current.backtrace.first(100),
|
|
80
|
+
}
|
|
81
|
+
::HasHelpers::EmailNotifier.system(subject: "Error synchronizing organization attributes", to: "tools@onehq.com", body: notifier_body).deliver_now
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Ensure there's a join
|
|
85
|
+
link = user_organizations.find_or_initialize_by(organization_id: org.id)
|
|
86
|
+
link.is_primary = true
|
|
87
|
+
|
|
88
|
+
self.assign_attributes(
|
|
89
|
+
applications_array: extra_attributes["user_applications_array"],
|
|
90
|
+
import_key: extra_attributes["user_import_key"],
|
|
91
|
+
ip_whitelist: extra_attributes["user_ip_whitelist"],
|
|
92
|
+
is_support: extra_attributes["user_is_support"] ? true : nil, # bi-state bool here, regular bool in hqsso
|
|
93
|
+
permissions_hash: extra_attributes["user_permissions_hash"],
|
|
94
|
+
photo_content_type: extra_attributes["user_photo_content_type"],
|
|
95
|
+
photo_file_name: extra_attributes["user_photo_file_name"],
|
|
96
|
+
photo_file_size: extra_attributes["user_photo_file_size"],
|
|
97
|
+
photo_updated_at: extra_attributes["user_photo_updated_at"],
|
|
98
|
+
production_api_key: extra_attributes["user_production_api_key"],
|
|
99
|
+
staging_api_key: extra_attributes["user_staging_api_key"],
|
|
100
|
+
username: extra_attributes["user_username"],
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
self.first_name = extra_attributes["user_first_name"] if respond_to?(:first_name)
|
|
104
|
+
self.last_name = extra_attributes["user_last_name"] if respond_to?(:last_name)
|
|
105
|
+
|
|
106
|
+
# only for new users
|
|
107
|
+
if new_record?
|
|
108
|
+
self.id = extra_attributes["user_id"]
|
|
109
|
+
self.created_by = self
|
|
110
|
+
self.updated_by = self
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Do not push changes to HQAdmin since the latest changes are currently being applied.
|
|
114
|
+
# This is not strictly necessary, but it currenty prevents a pointless API call.
|
|
115
|
+
self.skip_update_master_record = true
|
|
116
|
+
|
|
117
|
+
self.extra_attributes = extra_attributes.select { |attr_name, _| attr_name.start_with?("user") }
|
|
118
|
+
org.extra_attributes = extra_attributes.select { |attr_name, _| attr_name.start_with?("organization") }
|
|
119
|
+
self.send(:handle_extra_attributes) if self.respond_to?(:handle_extra_attributes, true)
|
|
120
|
+
org.send(:handle_extra_attributes) if org.respond_to?(:handle_extra_attributes, true)
|
|
121
|
+
link.save!
|
|
122
|
+
# Make sure all other links are not primary
|
|
123
|
+
user_organizations.where.not(id: link.id).update_all(is_primary: nil)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def abbreviated_name
|
|
127
|
+
receiver = respond_to?(:demographic) ? demographic : self
|
|
128
|
+
"#{receiver.first_name}#{receiver.last_name.to_s.sub(/^(.).*/, ' \1.')}"
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def is_admin?
|
|
132
|
+
applications_array.include?(::HasHelpers::Application::HQADMIN.name)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def is_super_user?
|
|
136
|
+
is_admin? || is_support?
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
protected
|
|
140
|
+
|
|
141
|
+
###### normalizations ######
|
|
142
|
+
|
|
143
|
+
# Pushes changes to the master record (in HQAdmin) through an API.
|
|
144
|
+
# This should run within the save transaction so that a failed API request will
|
|
145
|
+
# prevent a local update.
|
|
146
|
+
def update_master_record
|
|
147
|
+
changed_attr_names = changed.select { |attr| REMOTE_ATTRS.include?(attr) } # Exclude some attributes from update
|
|
148
|
+
changed_attrs = attributes.slice(*changed_attr_names)
|
|
149
|
+
|
|
150
|
+
# Also grab changed attrs from the associated Demographic record (if applicable).
|
|
151
|
+
if respond_to?(:demographic) && demographic
|
|
152
|
+
# Need to access the previous_changes because the Demographic record (child) will be saved before the current user.
|
|
153
|
+
demographic.previous_changes.select { |attr, _values| REMOTE_ATTRS.include?(attr) }.each do |attr, (_, new_value)|
|
|
154
|
+
changed_attrs[attr] = new_value
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
if changed_attrs.any?
|
|
159
|
+
# TODO: 2015-04-01 Revert this code which disables SSL verification. This was only intended as a temporary measure to work around the issue described below. *
|
|
160
|
+
response = ::RestClient.post("#{::HasHelpers::Application::HQADMIN.url}/api/v1/users/#{id}", changed_attrs)
|
|
161
|
+
# response = ::RestClient::Resource.new("#{::HasHelpers::Application::HQADMIN.url}/api/v1/users/#{id}", verify_ssl: OpenSSL::SSL::VERIFY_NONE).post(changed_attrs) # Turn off SSL verification which has recently started causing connection issues here due to our invalid cert for HQAdmin (in production).
|
|
162
|
+
|
|
163
|
+
response_data = JSON.parse(response.body)
|
|
164
|
+
|
|
165
|
+
self.master_record_attributes = response_data["user"] # Hold onto the user attributes received in the API response.
|
|
166
|
+
response_data["message"] == "success" # Returning a falsey value here will cancel the save operation when the current method is used as an after save callback.
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def save_master_record_attributes
|
|
171
|
+
self.skip_update_master_record = true
|
|
172
|
+
attrs = master_record_attributes # Grab another reference to the new user attributes, so the virtual attribute can be cleared.
|
|
173
|
+
self.master_record_attributes = nil # Clear this out so the callback does not loop.
|
|
174
|
+
|
|
175
|
+
if respond_to?(:demographic) && demographic
|
|
176
|
+
remote_demographic_attrs = REMOTE_ATTRS.select { |remote_attr| demographic.respond_to?("#{remote_attr}=") } # Get a list of all the remote attrs which match up with Demographic
|
|
177
|
+
demographic.assign_attributes attrs.slice(*remote_demographic_attrs) # Do not update here. Allow the Demographic to be saved as part of the save operation for the current user in order to have all updates within a single transaction.
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
remote_user_attrs = REMOTE_ATTRS.select { |remote_attr| respond_to?("#{remote_attr}=") } # Get a list of all the remote attrs which match up with User
|
|
181
|
+
update attrs.slice(*remote_user_attrs) # In addition to updating the current user, this will save the Demographic record if one exists and is modified.
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HasHelpers
|
|
4
|
+
class UserOrganization < ApplicationRecord
|
|
5
|
+
self.table_name = :user_organizations
|
|
6
|
+
|
|
7
|
+
###### callbacks ######
|
|
8
|
+
|
|
9
|
+
###### variables ######
|
|
10
|
+
|
|
11
|
+
###### associations ######
|
|
12
|
+
belongs_to :organization, class_name: "::HasHelpers::Organization", optional: false
|
|
13
|
+
belongs_to :user, class_name: "::HasHelpers::User", optional: false
|
|
14
|
+
|
|
15
|
+
###### triggers ######
|
|
16
|
+
auto_primary foreign_keys: ["user_id"]
|
|
17
|
+
after_delete_primary foreign_keys: ["user_id"]
|
|
18
|
+
|
|
19
|
+
###### externals ######
|
|
20
|
+
|
|
21
|
+
###### validations ######
|
|
22
|
+
validates :user_id, uniqueness: {
|
|
23
|
+
scope: :organization_id,
|
|
24
|
+
message: "The user already has this organization set"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
###### scopes ######
|
|
28
|
+
|
|
29
|
+
###### class methods ######
|
|
30
|
+
|
|
31
|
+
###### instance methods ######
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HasHelpers
|
|
4
|
+
class UserRole < ApplicationRecord
|
|
5
|
+
self.table_name = :user_roles
|
|
6
|
+
|
|
7
|
+
###### callbacks ######
|
|
8
|
+
autoset :organization_id
|
|
9
|
+
|
|
10
|
+
###### variables ######
|
|
11
|
+
|
|
12
|
+
###### associations ######
|
|
13
|
+
belongs_to :role, optional: false
|
|
14
|
+
belongs_to :organization, class_name: "::HasHelpers::Organization"
|
|
15
|
+
belongs_to :user, class_name: "::HasHelpers::User", optional: false
|
|
16
|
+
|
|
17
|
+
###### externals ######
|
|
18
|
+
|
|
19
|
+
###### validations ######
|
|
20
|
+
|
|
21
|
+
###### scopes ######
|
|
22
|
+
|
|
23
|
+
###### class methods ######
|
|
24
|
+
|
|
25
|
+
###### instance methods ######
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module HasHelpers
|
|
4
|
+
class UserSession < ApplicationRecord
|
|
5
|
+
self.table_name = :user_sessions
|
|
6
|
+
|
|
7
|
+
###### associations ######
|
|
8
|
+
belongs_to :user
|
|
9
|
+
|
|
10
|
+
###### validations ######
|
|
11
|
+
validates :user_id, presence: true
|
|
12
|
+
validates :session_id, presence: true, uniqueness: { scope: [:user_id] }
|
|
13
|
+
validates :expired_at, presence: true
|
|
14
|
+
|
|
15
|
+
###### scopes ######
|
|
16
|
+
scope :expired, -> { where("expired_at < ?", Time.current) }
|
|
17
|
+
scope :active, -> { where("? BETWEEN created_at AND expired_at", Time.current) }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# An "abstract" superclass for BarcodePresenter subclasses. Each subclass must
|
|
5
|
+
# overwrite the private #get_texts method to return the data that should be
|
|
6
|
+
# rendered as barcodes.
|
|
7
|
+
require "barby/barcode/code_128"
|
|
8
|
+
require "barby/outputter/png_outputter"
|
|
9
|
+
require "barby/outputter/html_outputter"
|
|
10
|
+
|
|
11
|
+
module HasHelpers
|
|
12
|
+
class BarcodeBasePresenter < ::HasHelpers::BasePresenter
|
|
13
|
+
##### CLASS METHODS #####
|
|
14
|
+
|
|
15
|
+
# Returns a BarcodePresenter class that matches the object passed in. It
|
|
16
|
+
# does this by looking for a BarcodePresenter matching the object's base
|
|
17
|
+
# class. For example, if the object is a Policy (or any subclass of Policy),
|
|
18
|
+
# this method will see if there is a Policy::BarcodePresenter class. If it
|
|
19
|
+
# finds a matching class, it returns the class; if not, it returns nil.
|
|
20
|
+
def self.get_presenter_class(object)
|
|
21
|
+
base_class_name = object.class.base_class.name
|
|
22
|
+
"::#{base_class_name}::BarcodePresenter".safe_constantize
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Same as #get_presenter_class, but raises an error if it cannot find a
|
|
26
|
+
# matching BarcodePresenter class.
|
|
27
|
+
def self.get_presenter_class!(object)
|
|
28
|
+
presenter_class = get_presenter_class(object)
|
|
29
|
+
raise "Cannot find a barcode presenter for #{object.class}." unless presenter_class
|
|
30
|
+
presenter_class
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##### INSTANCE METHODS #####
|
|
34
|
+
|
|
35
|
+
# Returns an array of hashes representing barcodes. Each hash has the
|
|
36
|
+
# following keys:
|
|
37
|
+
# :text => String with the plain text version of the barcode
|
|
38
|
+
# :image_src => String with the Base64-encoded barcode PNG, prefixed with
|
|
39
|
+
# the necessary inline image HTML prefix; intended to be
|
|
40
|
+
# the entire value needed for an IMG tag's SRC attribute
|
|
41
|
+
# :last => Set to true for last barcode (to help rendering)
|
|
42
|
+
# It gets the actual content for the hashes from the #get_texts method,
|
|
43
|
+
# and then adds one more barcode representing the wrapped object's base
|
|
44
|
+
# class name.
|
|
45
|
+
def barcode_infos
|
|
46
|
+
@barcode_infos ||= begin
|
|
47
|
+
texts = get_texts
|
|
48
|
+
texts << ("#{base_class_name}/") if base_class_name
|
|
49
|
+
|
|
50
|
+
infos = texts.map do |text|
|
|
51
|
+
{ text: text, image_src: barcode_inline_image_src(text) }
|
|
52
|
+
end
|
|
53
|
+
infos.last[:last] = true
|
|
54
|
+
infos
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# All subclasses must overwrite this method to return an array of
|
|
61
|
+
# strings to generate barcodes for. The strings should already be formatted
|
|
62
|
+
# (upcased, invalid chars removed, max length enforced, etc.).
|
|
63
|
+
def get_texts # rubocop:disable Naming/AccessorMethodName
|
|
64
|
+
raise "Subclasses of HasHelpers::BarcodeBasePresenter must implement #get_texts."
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Returns a String that is the wrapped object's base class's name. Overwrite
|
|
68
|
+
# this in the subclass if you want it to return a different String, or set
|
|
69
|
+
# it to return nil if you don't want this included in the barcodes.
|
|
70
|
+
def base_class_name
|
|
71
|
+
@base_class_name ||= wrapped_object.class.base_class.name
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Returns a copy of the string passed in with the following changes:
|
|
75
|
+
# 1. Removes all non-alphanumeric chars. Note that this also removes
|
|
76
|
+
# underscores, even though regex considers those alphanumeric - i.e.
|
|
77
|
+
# we only preserve a-z, A-Z, and 0-9.
|
|
78
|
+
# 2. Upcases the string.
|
|
79
|
+
# 3. If a maximum length is passed in, truncates the string to be no longer
|
|
80
|
+
# than that.
|
|
81
|
+
# If the string passed in is nil, returns an empty string.
|
|
82
|
+
def format_alphanumeric(str, maximum_length = nil)
|
|
83
|
+
return "" if str.blank?
|
|
84
|
+
|
|
85
|
+
formatted_string = str.upcase.gsub(/[^a-zA-Z\d]/, "")
|
|
86
|
+
formatted_string = formatted_string[0, maximum_length] if maximum_length
|
|
87
|
+
formatted_string
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Returns a copy of the string passed in with the following changes:
|
|
91
|
+
# 1. Removes all non-numeric chars.
|
|
92
|
+
# 2. If a maximum length is passed in, truncates the string to be no longer
|
|
93
|
+
# than that.
|
|
94
|
+
# If the string passed in is nil, returns an empty string.
|
|
95
|
+
def format_numeric(str, maximum_length = nil)
|
|
96
|
+
return "" if str.blank?
|
|
97
|
+
|
|
98
|
+
formatted_string = str.gsub(/[\D]/, "")
|
|
99
|
+
formatted_string = formatted_string[0, maximum_length] if maximum_length
|
|
100
|
+
formatted_string
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def barcode_inline_image_src(text)
|
|
104
|
+
"data:image/png;base64,#{barcode_base64(text)}"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Takes the text passed in, returns a base64 string representing the PNG
|
|
108
|
+
# data for the barcode representation of that text.
|
|
109
|
+
def barcode_base64(text)
|
|
110
|
+
Base64.encode64(::Barby::Code128B.new(text).to_png(xdim: 2, height: 36))
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module HasHelpers
|
|
5
|
+
class BasePresenter
|
|
6
|
+
module Routing
|
|
7
|
+
# Returns an object which has the URL helpers for the current Rails application.
|
|
8
|
+
def self.routes
|
|
9
|
+
@routes ||= Class.new do
|
|
10
|
+
include Rails.application.routes.url_helpers # Including the helpers will mix in the polymorphic url helper methods in addition to the regular url helpers.
|
|
11
|
+
end.new
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
include ::HasHelpers::Attributes
|
|
16
|
+
attr_accessor :wrapped_object
|
|
17
|
+
attr_writer :errors
|
|
18
|
+
|
|
19
|
+
# Accepts an object or collection of objects and returns an
|
|
20
|
+
# Array of presenter instances wrapping each object.
|
|
21
|
+
def self.wrap(*args, **options)
|
|
22
|
+
if args.length == 1 && args[0].respond_to?(:map)
|
|
23
|
+
args[0].map do |data|
|
|
24
|
+
data_args = ::Array[data]
|
|
25
|
+
options = data_args.last.is_a?(Hash) ? data_args.pop : {}
|
|
26
|
+
new(*data_args, options)
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
[new(*args, **options)]
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Merges options with each element of the collection argument, and then calls
|
|
34
|
+
# .wrap passing the result
|
|
35
|
+
def self.wrap_with_options(collection, **options)
|
|
36
|
+
self.wrap(collection.lazy.map { |values| values.reverse_merge(options) })
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def initialize(*args)
|
|
40
|
+
attrs = args.last.is_a?(Hash) ? args.pop : {}
|
|
41
|
+
self.wrapped_object = args.first
|
|
42
|
+
super(attrs) # run Attributes initializer
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def ==(other)
|
|
46
|
+
other.is_a?(self.class) && instance_variables.all? do |ivar|
|
|
47
|
+
instance_variable_get(ivar) == other.instance_variable_get(ivar)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def error_on(accessor_name, include_dot_keys: true)
|
|
52
|
+
return if errors.blank?
|
|
53
|
+
|
|
54
|
+
messages =
|
|
55
|
+
if errors.respond_to?(:messages)
|
|
56
|
+
errors.messages
|
|
57
|
+
else
|
|
58
|
+
errors
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if include_dot_keys
|
|
62
|
+
keys = messages.keys.grep(/\A#{Regexp.quote(accessor_name.to_s)}(\z|\.)/)
|
|
63
|
+
keys.flat_map { |key| messages[key] }
|
|
64
|
+
else
|
|
65
|
+
messages[accessor_name.to_sym] || messages[accessor_name.to_s]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def errors
|
|
70
|
+
@errors || wrapped_object_errors || {}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Convenience method for accessing application routes.
|
|
74
|
+
# === Examples
|
|
75
|
+
# routes.advisor_path(@advisor)
|
|
76
|
+
# routes.polymorphic_url([@advisor, @payment])
|
|
77
|
+
delegate :routes, to: :'::HasHelpers::BasePresenter::Routing'
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def method_missing(name, *args, &block)
|
|
82
|
+
if (accessor_name = name.to_s[/\Ahas_error_on_(.*)\Z/, 1]) # Check for names such as `has_error_on_field_name`
|
|
83
|
+
error_on(accessor_name).present?
|
|
84
|
+
elsif (accessor_name = name.to_s[/\Ahas_(.*)\Z/, 1]) && respond_to?(accessor_name) # Check for names such as `has_some_method` and strip the leading `has_` portion.
|
|
85
|
+
result = send(accessor_name)
|
|
86
|
+
if result.is_a?(Enumerator) # Enumerable#present? does not return the expected value, e.g. `[].to_enum.present? #=> true`
|
|
87
|
+
result.size && result.size > 0
|
|
88
|
+
else
|
|
89
|
+
result.present?
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
super
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def wrapped_object_errors
|
|
97
|
+
wrapped_object && wrapped_object.respond_to?(:errors) && wrapped_object.errors
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# typed: false
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
class HasHelpers::CacheableItem
|
|
5
|
+
attr_writer :cache_key
|
|
6
|
+
attr_accessor :promised_item
|
|
7
|
+
|
|
8
|
+
def initialize(key, item = nil, &block)
|
|
9
|
+
self.cache_key = key
|
|
10
|
+
self.promised_item = item || block
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def item
|
|
14
|
+
::HasHelpers::ItemPresenter.new(
|
|
15
|
+
case promised_item
|
|
16
|
+
when Proc then promised_item[]
|
|
17
|
+
else promised_item
|
|
18
|
+
end
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def cache_key
|
|
23
|
+
case @cache_key
|
|
24
|
+
when ::ActiveRecord::Base then "#{@cache_key.class.name}/#{@cache_key.id}-#{@cache_key.updated_at.to_i}#{@cache_key['cache_key']}"
|
|
25
|
+
else @cache_key
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
class HasHelpers::ItemPresenter < ::HasHelpers::BasePresenter
|
|
5
|
+
attr_accessor :selected, :is_heading, :name, :status, :highlight, :tag, :emphasized
|
|
6
|
+
attr_writer :details, :service, :image_service, :icon, :items,
|
|
7
|
+
:title, # Value used for the HTML title attribute. When set explicitly to `true` (`TrueClass`) then the value returned by `name` will be used as the title.
|
|
8
|
+
:data # Set with a hash of data-attribute key/value pairs.
|
|
9
|
+
|
|
10
|
+
def details
|
|
11
|
+
Array[*@details]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def service
|
|
15
|
+
@service && @service.to_service
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def image_service
|
|
19
|
+
@image_service && @image_service.to_service
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def cache_key
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def item
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def icon
|
|
31
|
+
@icon && @icon.to_icon
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def items
|
|
35
|
+
::HasHelpers::ItemPresenter.new(items: @items) if @items
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def title
|
|
39
|
+
case @title
|
|
40
|
+
when TrueClass then name
|
|
41
|
+
else @title
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def attributes
|
|
46
|
+
(@data || {}).tap do |data_hash|
|
|
47
|
+
data_hash.keys.each do |k|
|
|
48
|
+
data_hash["data-#{k}"] = data_hash.delete(k)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# typed: true
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
class HasHelpers::ItemsPresenter < ::HasHelpers::BasePresenter
|
|
5
|
+
attr_accessor :skin
|
|
6
|
+
attr_writer :items, :attributes
|
|
7
|
+
|
|
8
|
+
def items(i = @items)
|
|
9
|
+
@memoized_items ||= i.map do |item| # rubocop:disable Naming/MemoizedInstanceVariableName
|
|
10
|
+
case item
|
|
11
|
+
when ::HasHelpers::CacheableItem
|
|
12
|
+
item
|
|
13
|
+
else
|
|
14
|
+
::HasHelpers::ItemPresenter.new(item)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def attributes
|
|
20
|
+
@attributes || []
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def cache_key
|
|
24
|
+
@cache_key ||= if @cache_key_is_memoized
|
|
25
|
+
@cache_key_memoized
|
|
26
|
+
else
|
|
27
|
+
@cache_key_is_memoized = true
|
|
28
|
+
@cache_key_memoized = if (cache_key_items = items.map(&:cache_key)).all?
|
|
29
|
+
Digest::MD5.hexdigest cache_key_items.join
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class HasHelpers::Resource::ActionPresenter < ::HasHelpers::BasePresenter
|
|
4
|
+
attr_accessor :service, # href attribute
|
|
5
|
+
:title, # anchor title attribute
|
|
6
|
+
:icon, # Font awesome icon class, icon- prefix omitted, e.g. "angle-down" or "search"
|
|
7
|
+
:data # Collection of data attributes for action
|
|
8
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class HasHelpers::Resource::CellPresenter < ::HasHelpers::BasePresenter
|
|
4
|
+
# Content attributes +value+, +resource+ and +tags+. These attributes should be used exclusively.
|
|
5
|
+
attr_writer :value, # +value+ will be displayed as the content of the current cell.
|
|
6
|
+
:resource # Use +resource+ instead of +value+ when the target should be automatically wrapped in an InfoPresenter.
|
|
7
|
+
attr_accessor :tags # +tags+ will generate an unordered list using the collection it is set to.
|
|
8
|
+
|
|
9
|
+
attr_accessor :blank, # When set to true no output is generated for the content of the current cell. Without this option
|
|
10
|
+
# a nil value will be formatted to display "none" as the cell content.
|
|
11
|
+
:is_primary,
|
|
12
|
+
:primary_title, # E.g. the wording of the indication that this object is a favorite
|
|
13
|
+
:service, # When set the cell content is wrapped with an anchor tag which links to the given service URL.
|
|
14
|
+
:service_title, # E.g. used for link title attributes
|
|
15
|
+
:is_service_external, # When set to true the link for the cell (if any) should be externalized.
|
|
16
|
+
:is_header, # E.g, If set to true the cell will be rendered within a <TH> tag instead of <TD>
|
|
17
|
+
:warning, # When set to true an warning sign icon is displayed along with the cell content.
|
|
18
|
+
:is_text, # Used to identify cells with long text values which may need extra styling (or formatting?)
|
|
19
|
+
:colspan
|
|
20
|
+
attr_writer :template, # Setting template will cause rendering to use a custom partial
|
|
21
|
+
:current_user # Used to pass through to presenters for content
|
|
22
|
+
|
|
23
|
+
# Returns the content from either +value+ or resource.
|
|
24
|
+
def content
|
|
25
|
+
if @value.nil?
|
|
26
|
+
resource
|
|
27
|
+
elsif @value.present?
|
|
28
|
+
@value
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def template
|
|
33
|
+
@template.nil? ? detect_template_from_value : @template
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def detect_template_from_value
|
|
39
|
+
case content
|
|
40
|
+
when ::HasHelpers::Resource::InfoPresenter then "info"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Return the resource object which was set, wrapped in an InfoPresenter.
|
|
45
|
+
def resource
|
|
46
|
+
case @resource
|
|
47
|
+
when ::HasHelpers::Resource::InfoPresenter, NilClass then @resource
|
|
48
|
+
when Hash then ::HasHelpers::Resource::InfoPresenter.new(@resource.reverse_merge(current_user: @current_user))
|
|
49
|
+
else ::HasHelpers::Resource::InfoPresenter.new(@resource, current_user: @current_user)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|