linked_rails 0.0.2 → 0.0.4.pre.g4c8e21c9f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/LICENSE +21 -674
 - data/app/controllers/linked_rails/actions/objects_controller.rb +9 -0
 - data/app/controllers/linked_rails/bulk_controller.rb +104 -21
 - data/app/controllers/linked_rails/enum_values_controller.rb +0 -42
 - data/app/models/linked_rails/actions/item.rb +64 -55
 - data/app/models/linked_rails/actions/list.rb +6 -31
 - data/app/models/linked_rails/actions/object.rb +38 -0
 - data/app/models/linked_rails/collection/configuration.rb +55 -0
 - data/app/models/linked_rails/collection/filter.rb +1 -1
 - data/app/models/linked_rails/collection/filter_field.rb +19 -2
 - data/app/models/linked_rails/collection/filter_option.rb +1 -1
 - data/app/models/linked_rails/collection/filterable.rb +6 -9
 - data/app/models/linked_rails/collection/infinite.rb +113 -0
 - data/app/models/linked_rails/collection/infinite_view.rb +1 -90
 - data/app/models/linked_rails/collection/iri.rb +47 -43
 - data/app/models/linked_rails/collection/iri_mapping.rb +15 -7
 - data/app/models/linked_rails/collection/paginated.rb +46 -0
 - data/app/models/linked_rails/collection/paginated_view.rb +1 -33
 - data/app/models/linked_rails/collection/sortable.rb +1 -9
 - data/app/models/linked_rails/collection/sorting.rb +1 -1
 - data/app/models/linked_rails/collection/view.rb +51 -14
 - data/app/models/linked_rails/collection.rb +53 -85
 - data/app/models/linked_rails/creative_work.rb +1 -1
 - data/app/models/linked_rails/entry_point.rb +8 -5
 - data/app/models/linked_rails/enum_value.rb +40 -2
 - data/app/models/linked_rails/form/field/association_input.rb +7 -1
 - data/app/models/linked_rails/form/field/file_input.rb +1 -0
 - data/app/models/linked_rails/form/field/resource_field.rb +2 -0
 - data/{lib/linked_rails/enhancements/indexable/model.rb → app/models/linked_rails/form/field/url_input.rb} +3 -3
 - data/app/models/linked_rails/form/field.rb +37 -13
 - data/app/models/linked_rails/form/field_factory.rb +48 -18
 - data/app/models/linked_rails/form/group.rb +4 -6
 - data/app/models/linked_rails/form/page.rb +8 -4
 - data/app/models/linked_rails/form.rb +17 -21
 - data/app/models/linked_rails/manifest.rb +102 -22
 - data/app/models/linked_rails/menus/item.rb +10 -13
 - data/app/models/linked_rails/menus/list.rb +16 -7
 - data/app/models/linked_rails/ontology/base.rb +3 -1
 - data/app/models/linked_rails/ontology/class.rb +3 -3
 - data/app/models/linked_rails/ontology.rb +6 -5
 - data/app/models/linked_rails/property_query.rb +2 -0
 - data/app/models/linked_rails/sequence.rb +4 -13
 - data/app/models/linked_rails/shacl/property_shape.rb +1 -1
 - data/app/models/linked_rails/web_page.rb +0 -4
 - data/app/models/linked_rails/web_site.rb +0 -4
 - data/app/models/linked_rails/widget.rb +4 -11
 - data/app/policies/linked_rails/actions/object_policy.rb +11 -0
 - data/app/policies/linked_rails/collection_policy.rb +2 -2
 - data/app/policies/linked_rails/form_policy.rb +13 -0
 - data/app/policies/linked_rails/ontology_policy.rb +13 -0
 - data/app/serializers/linked_rails/actions/item_serializer.rb +5 -5
 - data/app/serializers/linked_rails/actions/object_serializer.rb +9 -0
 - data/app/serializers/linked_rails/collection/filter_field_serializer.rb +3 -2
 - data/app/serializers/linked_rails/collection/filter_option_serializer.rb +1 -1
 - data/app/serializers/linked_rails/collection/filter_serializer.rb +1 -1
 - data/app/serializers/linked_rails/collection/sorting_serializer.rb +1 -1
 - data/app/serializers/linked_rails/collection/view_serializer.rb +3 -3
 - data/app/serializers/linked_rails/collection_serializer.rb +8 -7
 - data/app/serializers/linked_rails/condition_serializer.rb +3 -3
 - data/app/serializers/linked_rails/entry_point_serializer.rb +3 -3
 - data/app/serializers/linked_rails/enum_value_serializer.rb +1 -0
 - data/app/serializers/linked_rails/form/field/association_input_serializer.rb +1 -0
 - data/app/serializers/linked_rails/form/field/file_input_serializer.rb +11 -0
 - data/app/serializers/linked_rails/form/field_serializer.rb +3 -1
 - data/app/serializers/linked_rails/form/group_serializer.rb +1 -1
 - data/app/serializers/linked_rails/form/page_serializer.rb +1 -1
 - data/app/serializers/linked_rails/menus/item_serializer.rb +3 -3
 - data/app/serializers/linked_rails/menus/list_serializer.rb +1 -1
 - data/app/serializers/linked_rails/ontology_serializer.rb +2 -2
 - data/app/serializers/linked_rails/property_query_serializer.rb +7 -0
 - data/app/serializers/linked_rails/sequence_serializer.rb +2 -5
 - data/app/serializers/linked_rails/shacl/node_shape_serializer.rb +1 -1
 - data/app/serializers/linked_rails/shacl/property_shape_serializer.rb +1 -1
 - data/app/serializers/linked_rails/shacl/shape_serializer.rb +5 -5
 - data/app/serializers/linked_rails/web_page_serializer.rb +3 -3
 - data/app/serializers/linked_rails/web_site_serializer.rb +1 -1
 - data/app/serializers/linked_rails/widget_serializer.rb +3 -3
 - data/app/workers/linked_rails/invalidation_stream_worker.rb +16 -0
 - data/lib/generators/linked_rails/install/install_generator.rb +7 -8
 - data/lib/generators/linked_rails/install/templates/README +7 -0
 - data/lib/generators/linked_rails/install/templates/app_menu_list.rb +36 -7
 - data/lib/generators/linked_rails/install/templates/application_menu_list.rb +40 -1
 - data/lib/generators/linked_rails/install/templates/initializer.rb +1 -2
 - data/lib/generators/linked_rails/install/templates/locales.yml +16 -0
 - data/lib/generators/linked_rails/install/templates/rdf_serializers_initializer.rb +1 -1
 - data/lib/generators/linked_rails/install/templates/vocab.rb +1 -0
 - data/lib/generators/linked_rails/install/templates/vocab.yml +2 -2
 - data/lib/generators/linked_rails/model/model_generator.rb +0 -1
 - data/lib/generators/linked_rails/model/templates/controller.rb.tt +5 -1
 - data/lib/generators/linked_rails/model/templates/form.rb.tt +3 -0
 - data/lib/generators/linked_rails/model/templates/menu_list.rb.tt +15 -0
 - data/lib/generators/linked_rails/model/templates/policy.rb.tt +13 -0
 - data/lib/generators/linked_rails/model/templates/serializer.rb.tt +5 -1
 - data/lib/linked_rails/active_response/controller/collections.rb +1 -1
 - data/lib/linked_rails/active_response/controller/crud_defaults.rb +4 -4
 - data/lib/linked_rails/active_response/controller/params.rb +10 -10
 - data/lib/linked_rails/active_response/controller.rb +8 -18
 - data/lib/linked_rails/active_response/responders/rdf.rb +19 -10
 - data/lib/linked_rails/callable_variable.rb +1 -1
 - data/lib/linked_rails/collection_params_parser.rb +93 -0
 - data/lib/linked_rails/controller/actionable.rb +121 -0
 - data/lib/linked_rails/controller/authorization.rb +6 -0
 - data/lib/linked_rails/controller/default_actions/create.rb +52 -0
 - data/lib/linked_rails/controller/default_actions/destroy.rb +42 -0
 - data/lib/linked_rails/controller/default_actions/update.rb +43 -0
 - data/lib/linked_rails/controller/delta.rb +58 -0
 - data/lib/linked_rails/controller/error_handling.rb +14 -7
 - data/lib/linked_rails/controller/rendering.rb +48 -0
 - data/lib/linked_rails/controller.rb +24 -4
 - data/lib/linked_rails/enhanceable.rb +1 -1
 - data/lib/linked_rails/enhancements/creatable/controller.rb +1 -1
 - data/lib/linked_rails/enhancements/destroyable/controller.rb +1 -1
 - data/lib/linked_rails/enhancements/updatable/controller.rb +1 -1
 - data/lib/linked_rails/enhancements.rb +0 -16
 - data/lib/linked_rails/errors/forbidden.rb +37 -0
 - data/lib/linked_rails/errors.rb +3 -0
 - data/lib/linked_rails/helpers/delta_helper.rb +26 -57
 - data/lib/linked_rails/helpers/ontola_actions_helper.rb +2 -2
 - data/lib/linked_rails/helpers/resource_helper.rb +11 -2
 - data/lib/linked_rails/iri_mapper.rb +17 -39
 - data/lib/linked_rails/middleware/error_handling.rb +51 -0
 - data/lib/linked_rails/middleware/linked_data_params.rb +30 -151
 - data/lib/linked_rails/model/actionable.rb +68 -0
 - data/lib/linked_rails/model/cacheable.rb +45 -0
 - data/lib/linked_rails/model/collections.rb +201 -39
 - data/lib/linked_rails/model/dirty.rb +6 -18
 - data/lib/linked_rails/model/enhancements.rb +1 -6
 - data/lib/linked_rails/model/filtering.rb +4 -6
 - data/lib/linked_rails/model/indexable.rb +6 -16
 - data/lib/linked_rails/model/iri.rb +29 -19
 - data/lib/linked_rails/model/iri_mapping.rb +37 -8
 - data/lib/linked_rails/model/menuable.rb +28 -0
 - data/lib/linked_rails/model/serialization.rb +2 -15
 - data/lib/linked_rails/model/singularable.rb +57 -0
 - data/lib/linked_rails/model/sorting.rb +0 -5
 - data/lib/linked_rails/model/tables.rb +26 -0
 - data/lib/linked_rails/model.rb +18 -7
 - data/lib/linked_rails/params_parser.rb +131 -54
 - data/lib/linked_rails/policy/attribute_conditions.rb +2 -2
 - data/lib/linked_rails/policy.rb +44 -46
 - data/lib/linked_rails/railtie.rb +11 -0
 - data/lib/linked_rails/rdf_error.rb +2 -2
 - data/lib/linked_rails/renderers.rb +1 -0
 - data/lib/linked_rails/routes.rb +38 -22
 - data/lib/linked_rails/serializer/actionable.rb +27 -0
 - data/lib/linked_rails/serializer/menuable.rb +31 -0
 - data/lib/linked_rails/serializer/singularable.rb +26 -0
 - data/lib/linked_rails/serializer.rb +28 -11
 - data/lib/linked_rails/storage.rb +32 -0
 - data/lib/linked_rails/test_methods.rb +114 -0
 - data/lib/linked_rails/translate.rb +31 -9
 - data/lib/linked_rails/types/iri_type.rb +37 -0
 - data/lib/linked_rails/uri_template.rb +30 -0
 - data/lib/linked_rails/url.rb +11 -0
 - data/lib/linked_rails/version.rb +1 -1
 - data/lib/linked_rails/vocab.rb +9 -0
 - data/lib/linked_rails.rb +40 -14
 - data/lib/rails/welcome_controller.rb +3 -2
 - data/lib/rdf/list.rb +9 -0
 - data/lib/rdf/query_fix.rb +15 -0
 - metadata +80 -33
 - data/app/models/linked_rails/actions/default_actions/create.rb +0 -60
 - data/app/models/linked_rails/actions/default_actions/destroy.rb +0 -45
 - data/app/models/linked_rails/actions/default_actions/update.rb +0 -50
 - data/app/models/linked_rails/actions/default_actions.rb +0 -17
 - data/lib/generators/linked_rails/install/templates/application_action_list.rb +0 -3
 - data/lib/generators/linked_rails/model/templates/action_list.rb.tt +0 -6
 - data/lib/linked_rails/enhancements/actionable/model.rb +0 -71
 - data/lib/linked_rails/enhancements/actionable/serializer.rb +0 -25
 - data/lib/linked_rails/enhancements/creatable/action.rb +0 -15
 - data/lib/linked_rails/enhancements/destroyable/action.rb +0 -15
 - data/lib/linked_rails/enhancements/destroyable/routing.rb +0 -19
 - data/lib/linked_rails/enhancements/menuable/model.rb +0 -36
 - data/lib/linked_rails/enhancements/menuable/serializer.rb +0 -33
 - data/lib/linked_rails/enhancements/route_concerns.rb +0 -56
 - data/lib/linked_rails/enhancements/singularable/controller.rb +0 -43
 - data/lib/linked_rails/enhancements/singularable/model.rb +0 -47
 - data/lib/linked_rails/enhancements/singularable/serializer.rb +0 -28
 - data/lib/linked_rails/enhancements/tableable/model.rb +0 -28
 - data/lib/linked_rails/enhancements/updatable/action.rb +0 -15
 - data/lib/linked_rails/enhancements/updatable/routing.rb +0 -20
 
| 
         @@ -3,10 +3,17 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            module LinkedRails
         
     | 
| 
       4 
4 
     | 
    
         
             
              class Form
         
     | 
| 
       5 
5 
     | 
    
         
             
                class FieldFactory # rubocop:disable Metrics/ClassLength
         
     | 
| 
      
 6 
     | 
    
         
            +
                  DATABASE_ERRORS = [
         
     | 
| 
      
 7 
     | 
    
         
            +
                    'PG::ConnectionBad'.safe_constantize,
         
     | 
| 
      
 8 
     | 
    
         
            +
                    ActiveRecord::StatementInvalid,
         
     | 
| 
      
 9 
     | 
    
         
            +
                    ActiveRecord::ConnectionNotEstablished
         
     | 
| 
      
 10 
     | 
    
         
            +
                  ].compact.freeze
         
     | 
| 
       6 
11 
     | 
    
         
             
                  MAX_STR_LEN = 255
         
     | 
| 
       7 
12 
     | 
    
         
             
                  VALIDATOR_SELECTORS = [
         
     | 
| 
       8 
13 
     | 
    
         
             
                    [:min_length, ActiveModel::Validations::LengthValidator, :minimum],
         
     | 
| 
      
 14 
     | 
    
         
            +
                    [:min_inclusive, ActiveModel::Validations::NumericalityValidator, :greater_than_or_equal_to],
         
     | 
| 
       9 
15 
     | 
    
         
             
                    [:max_length, ActiveModel::Validations::LengthValidator, :maximum],
         
     | 
| 
      
 16 
     | 
    
         
            +
                    [:max_inclusive, ActiveModel::Validations::NumericalityValidator, :less_than_or_equal_to],
         
     | 
| 
       10 
17 
     | 
    
         
             
                    [:pattern, ActiveModel::Validations::FormatValidator, :with],
         
     | 
| 
       11 
18 
     | 
    
         
             
                    [:presence, ActiveModel::Validations::PresenceValidator, nil],
         
     | 
| 
       12 
19 
     | 
    
         
             
                    [:sh_in, ActiveModel::Validations::InclusionValidator, :in]
         
     | 
| 
         @@ -15,7 +22,8 @@ module LinkedRails 
     | 
|
| 
       15 
22 
     | 
    
         | 
| 
       16 
23 
     | 
    
         
             
                  attr_accessor :field_options, :form, :key
         
     | 
| 
       17 
24 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
                  delegate : 
     | 
| 
      
 25 
     | 
    
         
            +
                  delegate :abstract_form,
         
     | 
| 
      
 26 
     | 
    
         
            +
                           :form_options_iri,
         
     | 
| 
       19 
27 
     | 
    
         
             
                           :model_class,
         
     | 
| 
       20 
28 
     | 
    
         
             
                           :model_policy!,
         
     | 
| 
       21 
29 
     | 
    
         
             
                           :serializer_attributes,
         
     | 
| 
         @@ -24,12 +32,21 @@ module LinkedRails 
     | 
|
| 
       24 
32 
     | 
    
         
             
                           to: :form
         
     | 
| 
       25 
33 
     | 
    
         | 
| 
       26 
34 
     | 
    
         
             
                  def condition_or_field
         
     | 
| 
       27 
     | 
    
         
            -
                    @condition_or_field  
     | 
| 
      
 35 
     | 
    
         
            +
                    return @condition_or_field if instance_variable_defined?(:@condition_or_field)
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    alternatives = node_shapes_for(
         
     | 
| 
       28 
38 
     | 
    
         
             
                      key,
         
     | 
| 
       29 
     | 
    
         
            -
                      field,
         
     | 
| 
       30 
39 
     | 
    
         
             
                      property: field_options[:if] || [],
         
     | 
| 
       31 
40 
     | 
    
         
             
                      sh_not: field_options[:unless] || []
         
     | 
| 
       32 
41 
     | 
    
         
             
                    )
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @condition_or_field =
         
     | 
| 
      
 43 
     | 
    
         
            +
                      if alternatives.count == 1
         
     | 
| 
      
 44 
     | 
    
         
            +
                        Condition.new(shape: alternatives.first, pass: field)
         
     | 
| 
      
 45 
     | 
    
         
            +
                      elsif alternatives.count.positive?
         
     | 
| 
      
 46 
     | 
    
         
            +
                        Condition.new(shape: SHACL::NodeShape.new(or: alternatives), pass: field)
         
     | 
| 
      
 47 
     | 
    
         
            +
                      else
         
     | 
| 
      
 48 
     | 
    
         
            +
                        field
         
     | 
| 
      
 49 
     | 
    
         
            +
                      end
         
     | 
| 
       33 
50 
     | 
    
         
             
                  end
         
     | 
| 
       34 
51 
     | 
    
         | 
| 
       35 
52 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -45,8 +62,7 @@ module LinkedRails 
     | 
|
| 
       45 
62 
     | 
    
         
             
                  end
         
     | 
| 
       46 
63 
     | 
    
         | 
| 
       47 
64 
     | 
    
         
             
                  def attr_to_datatype # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
         
     | 
| 
       48 
     | 
    
         
            -
                     
     | 
| 
       49 
     | 
    
         
            -
                    case attribute_type(name)
         
     | 
| 
      
 65 
     | 
    
         
            +
                    case attribute_type
         
     | 
| 
       50 
66 
     | 
    
         
             
                    when :string, :text
         
     | 
| 
       51 
67 
     | 
    
         
             
                      Vocab.xsd.string
         
     | 
| 
       52 
68 
     | 
    
         
             
                    when :integer
         
     | 
| 
         @@ -58,22 +74,26 @@ module LinkedRails 
     | 
|
| 
       58 
74 
     | 
    
         
             
                    when :boolean
         
     | 
| 
       59 
75 
     | 
    
         
             
                      Vocab.xsd.boolean
         
     | 
| 
       60 
76 
     | 
    
         
             
                    when :decimal
         
     | 
| 
       61 
     | 
    
         
            -
                      decimal_data_type( 
     | 
| 
      
 77 
     | 
    
         
            +
                      decimal_data_type(attribute_name)
         
     | 
| 
       62 
78 
     | 
    
         
             
                    when :file
         
     | 
| 
       63 
79 
     | 
    
         
             
                      Vocab.ll[:blob]
         
     | 
| 
       64 
80 
     | 
    
         
             
                    else
         
     | 
| 
       65 
     | 
    
         
            -
                      Vocab.xsd.string if model_class.try(:defined_enums)&.key?( 
     | 
| 
      
 81 
     | 
    
         
            +
                      Vocab.xsd.string if model_class.try(:defined_enums)&.key?(attribute_name)
         
     | 
| 
       66 
82 
     | 
    
         
             
                    end
         
     | 
| 
       67 
83 
     | 
    
         
             
                  end
         
     | 
| 
       68 
84 
     | 
    
         | 
| 
       69 
     | 
    
         
            -
                  def  
     | 
| 
       70 
     | 
    
         
            -
                     
     | 
| 
       71 
     | 
    
         
            -
                   
     | 
| 
      
 85 
     | 
    
         
            +
                  def attribute_name
         
     | 
| 
      
 86 
     | 
    
         
            +
                    serializer_attribute&.key&.to_s || key.to_s
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  def attribute_type
         
     | 
| 
      
 90 
     | 
    
         
            +
                    model_class.try(:attribute_types).try(:[], attribute_name)&.type
         
     | 
| 
      
 91 
     | 
    
         
            +
                  rescue *DATABASE_ERRORS
         
     | 
| 
       72 
92 
     | 
    
         
             
                    :string
         
     | 
| 
       73 
93 
     | 
    
         
             
                  end
         
     | 
| 
       74 
94 
     | 
    
         | 
| 
       75 
95 
     | 
    
         
             
                  def attribute_validators
         
     | 
| 
       76 
     | 
    
         
            -
                    @attribute_validators ||= model_class 
     | 
| 
      
 96 
     | 
    
         
            +
                    @attribute_validators ||= model_class&.validators&.select { |v| v.attributes.include?(model_attribute) }
         
     | 
| 
       77 
97 
     | 
    
         
             
                  end
         
     | 
| 
       78 
98 
     | 
    
         | 
| 
       79 
99 
     | 
    
         
             
                  def datatype
         
     | 
| 
         @@ -143,7 +163,7 @@ module LinkedRails 
     | 
|
| 
       143 
163 
     | 
    
         
             
                    when Vocab.ontola['datatype/postalRange']
         
     | 
| 
       144 
164 
     | 
    
         
             
                      return Form::Field::PostalRangeInput
         
     | 
| 
       145 
165 
     | 
    
         
             
                    else
         
     | 
| 
       146 
     | 
    
         
            -
                       
     | 
| 
      
 166 
     | 
    
         
            +
                      attribute_type == :text ? Form::Field::TextAreaInput : Form::Field::TextInput
         
     | 
| 
       147 
167 
     | 
    
         
             
                    end
         
     | 
| 
       148 
168 
     | 
    
         
             
                  end
         
     | 
| 
       149 
169 
     | 
    
         
             
                  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
         
     | 
| 
         @@ -168,6 +188,15 @@ module LinkedRails 
     | 
|
| 
       168 
188 
     | 
    
         
             
                    @model_attribute ||= (model_class.try(:attribute_alias, key) || key).to_sym
         
     | 
| 
       169 
189 
     | 
    
         
             
                  end
         
     | 
| 
       170 
190 
     | 
    
         | 
| 
      
 191 
     | 
    
         
            +
                  def node_shapes_for(attr, property: [], sh_not: [])
         
     | 
| 
      
 192 
     | 
    
         
            +
                    alternatives = abstract_form ? [] : model_policy!.condition_alternatives(attr, field.permission_required?)
         
     | 
| 
      
 193 
     | 
    
         
            +
                    alternatives = [[]] if alternatives.empty? && (property.any? || sh_not.any?)
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
                    alternatives.map do |props|
         
     | 
| 
      
 196 
     | 
    
         
            +
                      SHACL::NodeShape.new(property: props + property, sh_not: sh_not)
         
     | 
| 
      
 197 
     | 
    
         
            +
                    end
         
     | 
| 
      
 198 
     | 
    
         
            +
                  end
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
       171 
200 
     | 
    
         
             
                  def normalized_key(key)
         
     | 
| 
       172 
201 
     | 
    
         
             
                    return key.to_s[0...-3].to_sym if key.to_s.ends_with?('_id')
         
     | 
| 
       173 
202 
     | 
    
         
             
                    return key.to_s[0...-4].pluralize.to_sym if key.to_s.ends_with?('_ids')
         
     | 
| 
         @@ -197,14 +226,15 @@ module LinkedRails 
     | 
|
| 
       197 
226 
     | 
    
         
             
                  def validator(klass, option_key)
         
     | 
| 
       198 
227 
     | 
    
         
             
                    matched_validator = validator_by_class(klass)
         
     | 
| 
       199 
228 
     | 
    
         | 
| 
       200 
     | 
    
         
            -
                    option_key ? matched_validator&.options.try(:[], option_key) : matched_validator.present?
         
     | 
| 
      
 229 
     | 
    
         
            +
                    value = option_key ? matched_validator&.options.try(:[], option_key) : matched_validator.present?
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                    value unless value.respond_to?(:call)
         
     | 
| 
       201 
232 
     | 
    
         
             
                  end
         
     | 
| 
       202 
233 
     | 
    
         | 
| 
       203 
234 
     | 
    
         
             
                  def validator_by_class(klass)
         
     | 
| 
       204 
     | 
    
         
            -
                     
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
             
     | 
| 
       207 
     | 
    
         
            -
                    matched_validator if matched_validator.options[:if].blank? && matched_validator.options[:unless].blank?
         
     | 
| 
      
 235 
     | 
    
         
            +
                    attribute_validators&.detect do |validator|
         
     | 
| 
      
 236 
     | 
    
         
            +
                      validator.is_a?(klass) && validator.options[:if].blank? && validator.options[:unless].blank?
         
     | 
| 
      
 237 
     | 
    
         
            +
                    end
         
     | 
| 
       208 
238 
     | 
    
         
             
                  end
         
     | 
| 
       209 
239 
     | 
    
         | 
| 
       210 
240 
     | 
    
         
             
                  def validators
         
     | 
| 
         @@ -212,7 +242,7 @@ module LinkedRails 
     | 
|
| 
       212 
242 
     | 
    
         
             
                      VALIDATOR_SELECTORS.map do |key, klass, option_key|
         
     | 
| 
       213 
243 
     | 
    
         
             
                        [key, validator(klass, option_key)]
         
     | 
| 
       214 
244 
     | 
    
         
             
                      end
         
     | 
| 
       215 
     | 
    
         
            -
                    ]
         
     | 
| 
      
 245 
     | 
    
         
            +
                    ].compact
         
     | 
| 
       216 
246 
     | 
    
         
             
                  end
         
     | 
| 
       217 
247 
     | 
    
         
             
                end
         
     | 
| 
       218 
248 
     | 
    
         
             
              end
         
     | 
| 
         @@ -6,19 +6,17 @@ module LinkedRails 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  attr_accessor :fields, :collapsible, :hidden, :footer
         
     | 
| 
       7 
7 
     | 
    
         
             
                  attr_writer :description, :key, :label
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                  def initialize(attrs 
     | 
| 
       10 
     | 
    
         
            -
                    super(attrs)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(**attrs)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(**attrs)
         
     | 
| 
       11 
11 
     | 
    
         
             
                    self.fields = []
         
     | 
| 
       12 
12 
     | 
    
         
             
                  end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  def description
         
     | 
| 
       15 
     | 
    
         
            -
                    @description  
     | 
| 
       16 
     | 
    
         
            -
                    @description
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @description.respond_to?(:call) ? @description.call : @description
         
     | 
| 
       17 
16 
     | 
    
         
             
                  end
         
     | 
| 
       18 
17 
     | 
    
         | 
| 
       19 
18 
     | 
    
         
             
                  def label
         
     | 
| 
       20 
     | 
    
         
            -
                    @label  
     | 
| 
       21 
     | 
    
         
            -
                    @label
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @label.respond_to?(:call) ? @label.call : @label
         
     | 
| 
       22 
20 
     | 
    
         
             
                  end
         
     | 
| 
       23 
21 
     | 
    
         | 
| 
       24 
22 
     | 
    
         
             
                  def rdf_type
         
     | 
| 
         @@ -6,13 +6,13 @@ module LinkedRails 
     | 
|
| 
       6 
6 
     | 
    
         
             
                  attr_accessor :groups, :label, :description
         
     | 
| 
       7 
7 
     | 
    
         
             
                  attr_writer :key
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                  def initialize(attrs 
     | 
| 
       10 
     | 
    
         
            -
                    super(attrs)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def initialize(**attrs)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    super(**attrs)
         
     | 
| 
       11 
11 
     | 
    
         
             
                    self.groups = []
         
     | 
| 
       12 
12 
     | 
    
         
             
                  end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                  def add_group(opts)
         
     | 
| 
       15 
     | 
    
         
            -
                    group = Form::Group.new(opts)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  def add_group(**opts)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    group = Form::Group.new(**opts)
         
     | 
| 
       16 
16 
     | 
    
         
             
                    groups << group
         
     | 
| 
       17 
17 
     | 
    
         
             
                    group
         
     | 
| 
       18 
18 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -21,6 +21,10 @@ module LinkedRails 
     | 
|
| 
       21 
21 
     | 
    
         
             
                    @footer_group ||= add_group(collapsible: false, footer: true, key: :footer)
         
     | 
| 
       22 
22 
     | 
    
         
             
                  end
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
      
 24 
     | 
    
         
            +
                  def footer_group!
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @footer_group
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       24 
28 
     | 
    
         
             
                  class << self
         
     | 
| 
       25 
29 
     | 
    
         
             
                    def iri
         
     | 
| 
       26 
30 
     | 
    
         
             
                      Vocab.form[:Page]
         
     | 
| 
         @@ -5,10 +5,11 @@ require 'pundit' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            module LinkedRails
         
     | 
| 
       6 
6 
     | 
    
         
             
              class Form # rubocop:disable Metrics/ClassLength
         
     | 
| 
       7 
7 
     | 
    
         
             
                include LinkedRails::Model
         
     | 
| 
      
 8 
     | 
    
         
            +
                include LinkedRails::Model::Cacheable
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
                class_attribute :pages, :model_class
         
     | 
| 
      
 10 
     | 
    
         
            +
                class_attribute :abstract_form, :pages, :model_class
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
                def root_relative_iri(_opts 
     | 
| 
      
 12 
     | 
    
         
            +
                def root_relative_iri(**_opts)
         
     | 
| 
       12 
13 
     | 
    
         
             
                  self.class.form_iri_path
         
     | 
| 
       13 
14 
     | 
    
         
             
                end
         
     | 
| 
       14 
15 
     | 
    
         | 
| 
         @@ -63,10 +64,6 @@ module LinkedRails 
     | 
|
| 
       63 
64 
     | 
    
         
             
                    @serializer_reflections ||= serializer_class&.relationships_to_serialize || {}
         
     | 
| 
       64 
65 
     | 
    
         
             
                  end
         
     | 
| 
       65 
66 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
                  def preview_includes
         
     | 
| 
       67 
     | 
    
         
            -
                    [pages: {groups: [fields: [:fail, :pass, shape: [:property, nested_shapes: :property]]]}]
         
     | 
| 
       68 
     | 
    
         
            -
                  end
         
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
67 
     | 
    
         
             
                  private
         
     | 
| 
       71 
68 
     | 
    
         | 
| 
       72 
69 
     | 
    
         
             
                  def current_group
         
     | 
| 
         @@ -85,7 +82,7 @@ module LinkedRails 
     | 
|
| 
       85 
82 
     | 
    
         
             
                    @default_page ||= page(:default)
         
     | 
| 
       86 
83 
     | 
    
         
             
                  end
         
     | 
| 
       87 
84 
     | 
    
         | 
| 
       88 
     | 
    
         
            -
                  def field(key, opts 
     | 
| 
      
 85 
     | 
    
         
            +
                  def field(key, **opts)
         
     | 
| 
       89 
86 
     | 
    
         
             
                    current_group.fields << Form::FieldFactory.new(
         
     | 
| 
       90 
87 
     | 
    
         
             
                      field_options: opts,
         
     | 
| 
       91 
88 
     | 
    
         
             
                      form: self,
         
     | 
| 
         @@ -94,9 +91,10 @@ module LinkedRails 
     | 
|
| 
       94 
91 
     | 
    
         
             
                  end
         
     | 
| 
       95 
92 
     | 
    
         | 
| 
       96 
93 
     | 
    
         
             
                  def find_form_class(params)
         
     | 
| 
       97 
     | 
    
         
            -
                     
     | 
| 
      
 94 
     | 
    
         
            +
                    form_name = [params[:module], "#{params[:id]&.singularize}_forms"].compact.join('/').classify
         
     | 
| 
      
 95 
     | 
    
         
            +
                    requested_class = form_name.safe_constantize
         
     | 
| 
       98 
96 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
                     
     | 
| 
      
 97 
     | 
    
         
            +
                    requested_class if requested_class && requested_class < LinkedRails::Form
         
     | 
| 
       100 
98 
     | 
    
         
             
                  end
         
     | 
| 
       101 
99 
     | 
    
         | 
| 
       102 
100 
     | 
    
         
             
                  def footer
         
     | 
| 
         @@ -108,10 +106,10 @@ module LinkedRails 
     | 
|
| 
       108 
106 
     | 
    
         
             
                    current_page.footer_group
         
     | 
| 
       109 
107 
     | 
    
         
             
                  end
         
     | 
| 
       110 
108 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
                  def group(key, opts 
     | 
| 
      
 109 
     | 
    
         
            +
                  def group(key, **opts)
         
     | 
| 
       112 
110 
     | 
    
         
             
                    opts[:collapsible] = true unless opts.key?(:collapsible)
         
     | 
| 
       113 
111 
     | 
    
         
             
                    opts[:key] = key
         
     | 
| 
       114 
     | 
    
         
            -
                    group = current_page.add_group(opts)
         
     | 
| 
      
 112 
     | 
    
         
            +
                    group = current_page.add_group(**opts)
         
     | 
| 
       115 
113 
     | 
    
         
             
                    @current_group = group
         
     | 
| 
       116 
114 
     | 
    
         | 
| 
       117 
115 
     | 
    
         
             
                    yield if block_given?
         
     | 
| 
         @@ -120,26 +118,24 @@ module LinkedRails 
     | 
|
| 
       120 
118 
     | 
    
         
             
                    group
         
     | 
| 
       121 
119 
     | 
    
         
             
                  end
         
     | 
| 
       122 
120 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                   
     | 
| 
       124 
     | 
    
         
            -
                  def has_many(key, opts = {})
         
     | 
| 
      
 121 
     | 
    
         
            +
                  def has_many(key, **opts)
         
     | 
| 
       125 
122 
     | 
    
         
             
                    opts[:input_field] = Form::Field::AssociationInput
         
     | 
| 
       126 
123 
     | 
    
         
             
                    opts[:max_count] = 99
         
     | 
| 
       127 
     | 
    
         
            -
                    field(key, opts)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    field(key, **opts)
         
     | 
| 
       128 
125 
     | 
    
         
             
                  end
         
     | 
| 
       129 
126 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
                  def has_one(key, opts 
     | 
| 
      
 127 
     | 
    
         
            +
                  def has_one(key, **opts)
         
     | 
| 
       131 
128 
     | 
    
         
             
                    opts[:input_field] = Form::Field::AssociationInput
         
     | 
| 
       132 
129 
     | 
    
         
             
                    opts[:max_count] = 1
         
     | 
| 
       133 
     | 
    
         
            -
                    field(key, opts)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    field(key, **opts)
         
     | 
| 
       134 
131 
     | 
    
         
             
                  end
         
     | 
| 
       135 
     | 
    
         
            -
                  # rubocop:enable Naming/PredicateName
         
     | 
| 
       136 
132 
     | 
    
         | 
| 
       137 
133 
     | 
    
         
             
                  def hidden(&block)
         
     | 
| 
       138 
134 
     | 
    
         
             
                    group(:hidden, collapsible: false, hidden: true, &block)
         
     | 
| 
       139 
135 
     | 
    
         
             
                  end
         
     | 
| 
       140 
136 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
                  def page(key, opts 
     | 
| 
       142 
     | 
    
         
            -
                    page = Form::Page.new(opts.merge(key: key))
         
     | 
| 
      
 137 
     | 
    
         
            +
                  def page(key, **opts)
         
     | 
| 
      
 138 
     | 
    
         
            +
                    page = Form::Page.new(**opts.merge(key: key))
         
     | 
| 
       143 
139 
     | 
    
         
             
                    @current_page = page
         
     | 
| 
       144 
140 
     | 
    
         
             
                    pages << @current_page
         
     | 
| 
       145 
141 
     | 
    
         
             
                    yield if block_given?
         
     | 
| 
         @@ -147,9 +143,9 @@ module LinkedRails 
     | 
|
| 
       147 
143 
     | 
    
         
             
                    page
         
     | 
| 
       148 
144 
     | 
    
         
             
                  end
         
     | 
| 
       149 
145 
     | 
    
         | 
| 
       150 
     | 
    
         
            -
                  def resource(key, opts 
     | 
| 
      
 146 
     | 
    
         
            +
                  def resource(key, **opts)
         
     | 
| 
       151 
147 
     | 
    
         
             
                    opts[:input_field] = Form::Field::ResourceField
         
     | 
| 
       152 
     | 
    
         
            -
                    field(key, opts)
         
     | 
| 
      
 148 
     | 
    
         
            +
                    field(key, **opts)
         
     | 
| 
       153 
149 
     | 
    
         
             
                  end
         
     | 
| 
       154 
150 
     | 
    
         
             
                end
         
     | 
| 
       155 
151 
     | 
    
         
             
              end
         
     | 
| 
         @@ -5,6 +5,27 @@ module LinkedRails 
     | 
|
| 
       5 
5 
     | 
    
         
             
                include ActiveModel::Model
         
     | 
| 
       6 
6 
     | 
    
         
             
                include LinkedRails::Model
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
      
 8 
     | 
    
         
            +
                def save
         
     | 
| 
      
 9 
     | 
    
         
            +
                  Storage.hset(
         
     | 
| 
      
 10 
     | 
    
         
            +
                    :persistent,
         
     | 
| 
      
 11 
     | 
    
         
            +
                    :manifest,
         
     | 
| 
      
 12 
     | 
    
         
            +
                    URL.as_href(LinkedRails.iri) => web_manifest.to_json
         
     | 
| 
      
 13 
     | 
    
         
            +
                  )
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def web_manifest
         
     | 
| 
      
 17 
     | 
    
         
            +
                  web_manifest_base.merge(
         
     | 
| 
      
 18 
     | 
    
         
            +
                    ontola: web_manifest_ontola_section,
         
     | 
| 
      
 19 
     | 
    
         
            +
                    serviceworker: web_manifest_sw_section
         
     | 
| 
      
 20 
     | 
    
         
            +
                  )
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                private
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def allowed_external_sources
         
     | 
| 
      
 26 
     | 
    
         
            +
                  []
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       8 
29 
     | 
    
         
             
                def app_name
         
     | 
| 
       9 
30 
     | 
    
         
             
                  Rails.application.railtie_name.chomp('_application').humanize
         
     | 
| 
       10 
31 
     | 
    
         
             
                end
         
     | 
| 
         @@ -17,8 +38,27 @@ module LinkedRails 
     | 
|
| 
       17 
38 
     | 
    
         
             
                  '#eef0f2'
         
     | 
| 
       18 
39 
     | 
    
         
             
                end
         
     | 
| 
       19 
40 
     | 
    
         | 
| 
      
 41 
     | 
    
         
            +
                def blob_preview_iri
         
     | 
| 
      
 42 
     | 
    
         
            +
                  return unless ActiveStorage::Blob.service.present?
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                  "#{LinkedRails.iri(path: 'rails/active_storage/blobs/redirect')}/{signed_id}/preview')"
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def blob_upload_iri
         
     | 
| 
      
 48 
     | 
    
         
            +
                  return unless ActiveStorage::Blob.service.present?
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  LinkedRails.iri(path: 'rails/active_storage/direct_uploads')
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
       20 
53 
     | 
    
         
             
                def css_class; end
         
     | 
| 
       21 
54 
     | 
    
         | 
| 
      
 55 
     | 
    
         
            +
                def csp_entries
         
     | 
| 
      
 56 
     | 
    
         
            +
                  {
         
     | 
| 
      
 57 
     | 
    
         
            +
                    connectSrc: [ActiveStorage::Blob.service.try(:bucket)&.url].compact,
         
     | 
| 
      
 58 
     | 
    
         
            +
                    scriptSrc: [ActiveStorage::Blob.service.try(:bucket)&.url].compact
         
     | 
| 
      
 59 
     | 
    
         
            +
                  }
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
       22 
62 
     | 
    
         
             
                def header_background
         
     | 
| 
       23 
63 
     | 
    
         
             
                  :primary
         
     | 
| 
       24 
64 
     | 
    
         
             
                end
         
     | 
| 
         @@ -27,17 +67,16 @@ module LinkedRails 
     | 
|
| 
       27 
67 
     | 
    
         
             
                  :white
         
     | 
| 
       28 
68 
     | 
    
         
             
                end
         
     | 
| 
       29 
69 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                def  
     | 
| 
       31 
     | 
    
         
            -
                  [
         
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
                  ]
         
     | 
| 
      
 70 
     | 
    
         
            +
                def icons
         
     | 
| 
      
 71 
     | 
    
         
            +
                  []
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                def lang
         
     | 
| 
      
 75 
     | 
    
         
            +
                  :nl
         
     | 
| 
       37 
76 
     | 
    
         
             
                end
         
     | 
| 
       38 
77 
     | 
    
         | 
| 
       39 
78 
     | 
    
         
             
                def scope
         
     | 
| 
       40 
     | 
    
         
            -
                   
     | 
| 
      
 79 
     | 
    
         
            +
                  LinkedRails.iri.to_s
         
     | 
| 
       41 
80 
     | 
    
         
             
                end
         
     | 
| 
       42 
81 
     | 
    
         | 
| 
       43 
82 
     | 
    
         
             
                def site_theme_color
         
     | 
| 
         @@ -52,51 +91,92 @@ module LinkedRails 
     | 
|
| 
       52 
91 
     | 
    
         
             
                  app_name
         
     | 
| 
       53 
92 
     | 
    
         
             
                end
         
     | 
| 
       54 
93 
     | 
    
         | 
| 
      
 94 
     | 
    
         
            +
                def start_url
         
     | 
| 
      
 95 
     | 
    
         
            +
                  scope == '/' ? scope : "#{scope}/"
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
       55 
98 
     | 
    
         
             
                def theme; end
         
     | 
| 
       56 
99 
     | 
    
         | 
| 
       57 
100 
     | 
    
         
             
                def theme_options
         
     | 
| 
       58 
101 
     | 
    
         
             
                  {}
         
     | 
| 
       59 
102 
     | 
    
         
             
                end
         
     | 
| 
       60 
103 
     | 
    
         | 
| 
       61 
     | 
    
         
            -
                def web_manifest
         
     | 
| 
       62 
     | 
    
         
            -
                  web_manifest_base.merge(
         
     | 
| 
       63 
     | 
    
         
            -
                    ontola: web_manifest_ontola_section,
         
     | 
| 
       64 
     | 
    
         
            -
                    serviceworker: web_manifest_sw_section
         
     | 
| 
       65 
     | 
    
         
            -
                  )
         
     | 
| 
       66 
     | 
    
         
            -
                end
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
104 
     | 
    
         
             
                def web_manifest_base # rubocop:disable Metrics/MethodLength
         
     | 
| 
       69 
105 
     | 
    
         
             
                  {
         
     | 
| 
       70 
106 
     | 
    
         
             
                    background_color: background_color,
         
     | 
| 
       71 
107 
     | 
    
         
             
                    dir: :rtl,
         
     | 
| 
       72 
108 
     | 
    
         
             
                    display: :standalone,
         
     | 
| 
       73 
     | 
    
         
            -
                     
     | 
| 
      
 109 
     | 
    
         
            +
                    icons: icons,
         
     | 
| 
      
 110 
     | 
    
         
            +
                    lang: lang,
         
     | 
| 
       74 
111 
     | 
    
         
             
                    name: app_name,
         
     | 
| 
       75 
112 
     | 
    
         
             
                    scope: scope,
         
     | 
| 
       76 
113 
     | 
    
         
             
                    short_name: app_name,
         
     | 
| 
       77 
     | 
    
         
            -
                    start_url:  
     | 
| 
      
 114 
     | 
    
         
            +
                    start_url: start_url,
         
     | 
| 
       78 
115 
     | 
    
         
             
                    theme_color: site_theme_color
         
     | 
| 
       79 
116 
     | 
    
         
             
                  }
         
     | 
| 
       80 
117 
     | 
    
         
             
                end
         
     | 
| 
       81 
118 
     | 
    
         | 
| 
       82 
     | 
    
         
            -
                def web_manifest_ontola_section
         
     | 
| 
      
 119 
     | 
    
         
            +
                def web_manifest_ontola_section # rubocop:disable Metrics/MethodLength
         
     | 
| 
       83 
120 
     | 
    
         
             
                  {
         
     | 
| 
       84 
     | 
    
         
            -
                     
     | 
| 
      
 121 
     | 
    
         
            +
                    allowed_external_sources: allowed_external_sources,
         
     | 
| 
      
 122 
     | 
    
         
            +
                    blob_preview_iri:  blob_preview_iri,
         
     | 
| 
      
 123 
     | 
    
         
            +
                    blob_upload_iri: blob_upload_iri,
         
     | 
| 
      
 124 
     | 
    
         
            +
                    csp: csp_entries,
         
     | 
| 
       85 
125 
     | 
    
         
             
                    header_background: header_background,
         
     | 
| 
       86 
126 
     | 
    
         
             
                    header_text: header_text,
         
     | 
| 
       87 
     | 
    
         
            -
                     
     | 
| 
      
 127 
     | 
    
         
            +
                    preconnect: preconnect,
         
     | 
| 
       88 
128 
     | 
    
         
             
                    primary_color: site_theme_color,
         
     | 
| 
       89 
129 
     | 
    
         
             
                    secondary_color: site_secondary_color,
         
     | 
| 
      
 130 
     | 
    
         
            +
                    styled_headers: styled_headers,
         
     | 
| 
       90 
131 
     | 
    
         
             
                    theme: theme,
         
     | 
| 
       91 
     | 
    
         
            -
                    theme_options: theme_options.to_query
         
     | 
| 
      
 132 
     | 
    
         
            +
                    theme_options: theme_options.to_query,
         
     | 
| 
      
 133 
     | 
    
         
            +
                    tracking: tracking,
         
     | 
| 
      
 134 
     | 
    
         
            +
                    website_iri: LinkedRails.iri.to_s,
         
     | 
| 
      
 135 
     | 
    
         
            +
                    websocket_path: websocket_path
         
     | 
| 
       92 
136 
     | 
    
         
             
                  }
         
     | 
| 
       93 
137 
     | 
    
         
             
                end
         
     | 
| 
       94 
138 
     | 
    
         | 
| 
       95 
139 
     | 
    
         
             
                def web_manifest_sw_section
         
     | 
| 
       96 
140 
     | 
    
         
             
                  {
         
     | 
| 
       97 
     | 
    
         
            -
                    src: "#{scope}/sw.js 
     | 
| 
      
 141 
     | 
    
         
            +
                    src: "#{scope.chomp('/')}/sw.js",
         
     | 
| 
       98 
142 
     | 
    
         
             
                    scope: scope
         
     | 
| 
       99 
143 
     | 
    
         
             
                  }
         
     | 
| 
       100 
144 
     | 
    
         
             
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                def websocket_path
         
     | 
| 
      
 147 
     | 
    
         
            +
                  Rails.application.config.try(:action_cable).try(:mount_path).try(:[], 1..-1)
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                def preconnect
         
     | 
| 
      
 151 
     | 
    
         
            +
                  []
         
     | 
| 
      
 152 
     | 
    
         
            +
                end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                def styled_headers
         
     | 
| 
      
 155 
     | 
    
         
            +
                  false
         
     | 
| 
      
 156 
     | 
    
         
            +
                end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                def tracking
         
     | 
| 
      
 159 
     | 
    
         
            +
                  []
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 163 
     | 
    
         
            +
                  def destroy(iri)
         
     | 
| 
      
 164 
     | 
    
         
            +
                    Storage.hdel(:persistent, :manifest, URL.as_href(iri))
         
     | 
| 
      
 165 
     | 
    
         
            +
                  end
         
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
      
 167 
     | 
    
         
            +
                  def move(from, to)
         
     | 
| 
      
 168 
     | 
    
         
            +
                    Storage.hset(
         
     | 
| 
      
 169 
     | 
    
         
            +
                      :persistent,
         
     | 
| 
      
 170 
     | 
    
         
            +
                      :redirect_prefix,
         
     | 
| 
      
 171 
     | 
    
         
            +
                      URL.as_href(from) => URL.as_href(to)
         
     | 
| 
      
 172 
     | 
    
         
            +
                    )
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                    data = Storage.hget(:persistent, :manifest, URL.as_href(from))
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
                    Storage.hset(:persistent, :manifest, URL.as_href(to), data) if data
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                    destroy(from)
         
     | 
| 
      
 179 
     | 
    
         
            +
                  end
         
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
       101 
181 
     | 
    
         
             
              end
         
     | 
| 
       102 
182 
     | 
    
         
             
            end
         
     | 
| 
         @@ -12,7 +12,7 @@ module LinkedRails 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  delegate :iri_opts, to: :parent
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  alias id iri
         
     | 
| 
       15 
     | 
    
         
            -
                  %i[action href image label  
     | 
| 
      
 15 
     | 
    
         
            +
                  %i[action href image label iri_base].each do |method|
         
     | 
| 
       16 
16 
     | 
    
         
             
                    callable_variable(method, instance: :parent)
         
     | 
| 
       17 
17 
     | 
    
         
             
                  end
         
     | 
| 
       18 
18 
     | 
    
         | 
| 
         @@ -26,7 +26,7 @@ module LinkedRails 
     | 
|
| 
       26 
26 
     | 
    
         
             
                  def iri_template
         
     | 
| 
       27 
27 
     | 
    
         
             
                    return parent.send(:iri_template) unless parent.is_a?(LinkedRails::Menus::List)
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
                    return URITemplate.new("#{iri_base}{/tag}{#fragment}") if iri_base
         
     | 
| 
      
 29 
     | 
    
         
            +
                    return LinkedRails::URITemplate.new("#{iri_base}{/tag}{#fragment}") if iri_base
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
                    iri_template_expand_path(parent.send(:iri_template), '{/tag}')
         
     | 
| 
       32 
32 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -36,7 +36,7 @@ module LinkedRails 
     | 
|
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                    @menu_sequence ||=
         
     | 
| 
       38 
38 
     | 
    
         
             
                      LinkedRails::Sequence.new(
         
     | 
| 
       39 
     | 
    
         
            -
                        -> { menus 
     | 
| 
      
 39 
     | 
    
         
            +
                        -> { menus },
         
     | 
| 
       40 
40 
     | 
    
         
             
                        id: menu_sequence_iri,
         
     | 
| 
       41 
41 
     | 
    
         
             
                        parent: self,
         
     | 
| 
       42 
42 
     | 
    
         
             
                        scope: false
         
     | 
| 
         @@ -52,6 +52,12 @@ module LinkedRails 
     | 
|
| 
       52 
52 
     | 
    
         
             
                    sequence_iri
         
     | 
| 
       53 
53 
     | 
    
         
             
                  end
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
      
 55 
     | 
    
         
            +
                  def menus
         
     | 
| 
      
 56 
     | 
    
         
            +
                    return @menus unless @menus.respond_to?(:call)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                    @menus = parent.instance_exec(&@menus).compact.each { |menu| menu.parent = self }
         
     | 
| 
      
 59 
     | 
    
         
            +
                  end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
       55 
61 
     | 
    
         
             
                  def rdf_type
         
     | 
| 
       56 
62 
     | 
    
         
             
                    type || Vocab.ontola[:MenuItem]
         
     | 
| 
       57 
63 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -67,17 +73,8 @@ module LinkedRails 
     | 
|
| 
       67 
73 
     | 
    
         
             
                  end
         
     | 
| 
       68 
74 
     | 
    
         | 
| 
       69 
75 
     | 
    
         
             
                  class << self
         
     | 
| 
       70 
     | 
    
         
            -
                    def base_includes
         
     | 
| 
       71 
     | 
    
         
            -
                      [action: :target]
         
     | 
| 
       72 
     | 
    
         
            -
                    end
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
76 
     | 
    
         
             
                    def preview_includes
         
     | 
| 
       75 
     | 
    
         
            -
                       
     | 
| 
       76 
     | 
    
         
            -
                        menu_sequence: [
         
     | 
| 
       77 
     | 
    
         
            -
                          members: base_includes +
         
     | 
| 
       78 
     | 
    
         
            -
                            [menu_sequence: [members: base_includes]]
         
     | 
| 
       79 
     | 
    
         
            -
                        ]
         
     | 
| 
       80 
     | 
    
         
            -
                      ]
         
     | 
| 
      
 77 
     | 
    
         
            +
                      [menu_sequence: [members: [menu_sequence: :members]]]
         
     | 
| 
       81 
78 
     | 
    
         
             
                    end
         
     | 
| 
       82 
79 
     | 
    
         | 
| 
       83 
80 
     | 
    
         
             
                    def requested_index_resource(params, user_context)
         
     | 
| 
         @@ -20,21 +20,28 @@ module LinkedRails 
     | 
|
| 
       20 
20 
     | 
    
         
             
                  end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
                  def iri_opts
         
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
      
 23 
     | 
    
         
            +
                    return {} if resource.blank?
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    resource.try(:singular_resource?) ? resource.singular_iri_opts : resource.iri_opts
         
     | 
| 
       24 
26 
     | 
    
         
             
                  end
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
       26 
28 
     | 
    
         
             
                  def menus
         
     | 
| 
       27 
     | 
    
         
            -
                    @menus ||= available_menus.map(&method(: 
     | 
| 
      
 29 
     | 
    
         
            +
                    @menus ||= available_menus.map(&method(:memoized_menu_item))
         
     | 
| 
       28 
30 
     | 
    
         
             
                  end
         
     | 
| 
       29 
31 
     | 
    
         | 
| 
       30 
32 
     | 
    
         
             
                  def menu(tag)
         
     | 
| 
       31 
     | 
    
         
            -
                     
     | 
| 
      
 33 
     | 
    
         
            +
                    memoized_menu_item(tag, available_menus[tag].dup) if available_menus.key?(tag)
         
     | 
| 
       32 
34 
     | 
    
         
             
                  end
         
     | 
| 
       33 
35 
     | 
    
         | 
| 
       34 
36 
     | 
    
         
             
                  private
         
     | 
| 
       35 
37 
     | 
    
         | 
| 
       36 
38 
     | 
    
         
             
                  def default_label(tag, options)
         
     | 
| 
       37 
     | 
    
         
            -
                    I18n.t("menus.#{resource&.class&.name&.tableize}.#{tag}", options[:label_params])
         
     | 
| 
      
 39 
     | 
    
         
            +
                    I18n.t("menus.#{resource&.class&.name&.tableize}.#{tag}", **options[:label_params])
         
     | 
| 
      
 40 
     | 
    
         
            +
                  end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                  def memoized_menu_item(tag, options)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    @memoized_menu_item ||= {}
         
     | 
| 
      
 44 
     | 
    
         
            +
                    @memoized_menu_item[tag] ||= menu_item(tag, options)
         
     | 
| 
       38 
45 
     | 
    
         
             
                  end
         
     | 
| 
       39 
46 
     | 
    
         | 
| 
       40 
47 
     | 
    
         
             
                  def menu_available?(_tag, options)
         
     | 
| 
         @@ -48,6 +55,7 @@ module LinkedRails 
     | 
|
| 
       48 
55 
     | 
    
         
             
                    options[:label_params] ||= {}
         
     | 
| 
       49 
56 
     | 
    
         
             
                    options[:label_params][:default] ||= ["menus.default.#{tag}".to_sym, tag.to_s.capitalize]
         
     | 
| 
       50 
57 
     | 
    
         
             
                    options[:label] ||= default_label(tag, options)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    options[:action] = ontola_dialog_action(options[:href]) if options.delete(:dialog)
         
     | 
| 
       51 
59 
     | 
    
         
             
                    options.except!(:policy_resource, :policy, :policy_arguments, :label_params)
         
     | 
| 
       52 
60 
     | 
    
         
             
                    LinkedRails.menus_item_class.new(resource: resource, tag: tag, parent: self, **options)
         
     | 
| 
       53 
61 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -62,7 +70,9 @@ module LinkedRails 
     | 
|
| 
       62 
70 
     | 
    
         
             
                  end
         
     | 
| 
       63 
71 
     | 
    
         | 
| 
       64 
72 
     | 
    
         
             
                  def iri_template
         
     | 
| 
       65 
     | 
    
         
            -
                     
     | 
| 
      
 73 
     | 
    
         
            +
                    base_template = resource.send(resource.try(:singular_resource?) ? :singular_iri_template : :iri_template)
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                    @iri_template ||= iri_template_expand_path(base_template, '/menus')
         
     | 
| 
       66 
76 
     | 
    
         
             
                  end
         
     | 
| 
       67 
77 
     | 
    
         | 
| 
       68 
78 
     | 
    
         
             
                  class << self
         
     | 
| 
         @@ -88,7 +98,7 @@ module LinkedRails 
     | 
|
| 
       88 
98 
     | 
    
         
             
                      _defined_menus || {}
         
     | 
| 
       89 
99 
     | 
    
         
             
                    end
         
     | 
| 
       90 
100 
     | 
    
         | 
| 
       91 
     | 
    
         
            -
                    def has_menu(tag, opts 
     | 
| 
      
 101 
     | 
    
         
            +
                    def has_menu(tag, **opts)
         
     | 
| 
       92 
102 
     | 
    
         
             
                      defined_menus[tag] = opts
         
     | 
| 
       93 
103 
     | 
    
         
             
                    end
         
     | 
| 
       94 
104 
     | 
    
         | 
| 
         @@ -100,7 +110,6 @@ module LinkedRails 
     | 
|
| 
       100 
110 
     | 
    
         
             
                      LinkedRails::Sequence.new(
         
     | 
| 
       101 
111 
     | 
    
         
             
                        menu_list.menus,
         
     | 
| 
       102 
112 
     | 
    
         
             
                        id: menu_list.iri,
         
     | 
| 
       103 
     | 
    
         
            -
                        member_includes: Item.preview_includes,
         
     | 
| 
       104 
113 
     | 
    
         
             
                        scope: false
         
     | 
| 
       105 
114 
     | 
    
         
             
                      )
         
     | 
| 
       106 
115 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -9,7 +9,7 @@ module LinkedRails 
     | 
|
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
                  def data
         
     | 
| 
       11 
11 
     | 
    
         
             
                    data = []
         
     | 
| 
       12 
     | 
    
         
            -
                    iri.each_statement do |statement|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    iri.try(:each_statement) do |statement|
         
     | 
| 
       13 
13 
     | 
    
         
             
                      next unless include_data_statement?(statement)
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                      statement.graph_name = ::RDF::Serializers.config.default_graph
         
     | 
| 
         @@ -41,6 +41,8 @@ module LinkedRails 
     | 
|
| 
       41 
41 
     | 
    
         
             
                  end
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
43 
     | 
    
         
             
                  def include_data_statement?(statement)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    return false if statement.subject.node? || statement.object.node?
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       44 
46 
     | 
    
         
             
                    statement.predicate != Vocab.rdfs.label &&
         
     | 
| 
       45 
47 
     | 
    
         
             
                      statement.predicate != Vocab.rdfs.range &&
         
     | 
| 
       46 
48 
     | 
    
         
             
                      statement.predicate != Vocab.rdfs.domain
         
     | 
| 
         @@ -12,10 +12,10 @@ module LinkedRails 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  def parent_class
         
     | 
| 
       15 
     | 
    
         
            -
                    if klass 
     | 
| 
      
 15 
     | 
    
         
            +
                    if klass&.superclass == ApplicationRecord
         
     | 
| 
       16 
16 
     | 
    
         
             
                      Vocab.schema.Thing
         
     | 
| 
       17 
17 
     | 
    
         
             
                    else
         
     | 
| 
       18 
     | 
    
         
            -
                      klass 
     | 
| 
      
 18 
     | 
    
         
            +
                      klass&.superclass.try(:iri) || Vocab.schema.Thing
         
     | 
| 
       19 
19 
     | 
    
         
             
                    end
         
     | 
| 
       20 
20 
     | 
    
         
             
                  end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
         @@ -26,7 +26,7 @@ module LinkedRails 
     | 
|
| 
       26 
26 
     | 
    
         
             
                  end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
                  def properties
         
     | 
| 
       29 
     | 
    
         
            -
                    @properties ||= klass 
     | 
| 
      
 29 
     | 
    
         
            +
                    @properties ||= klass&.predicate_mapping&.keys&.map { |key| LinkedRails.ontology_property_class.new(iri: key) }
         
     | 
| 
       30 
30 
     | 
    
         
             
                  end
         
     | 
| 
       31 
31 
     | 
    
         | 
| 
       32 
32 
     | 
    
         
             
                  class << self
         
     | 
| 
         @@ -4,13 +4,14 @@ module LinkedRails 
     | 
|
| 
       4 
4 
     | 
    
         
             
              class Ontology
         
     | 
| 
       5 
5 
     | 
    
         
             
                include ActiveModel::Model
         
     | 
| 
       6 
6 
     | 
    
         
             
                include LinkedRails::Model
         
     | 
| 
      
 7 
     | 
    
         
            +
                include LinkedRails::Model::Cacheable
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
                def classes
         
     | 
| 
       9 
     | 
    
         
            -
                  @classes ||=  
     | 
| 
      
 10 
     | 
    
         
            +
                  @classes ||= LinkedRails.linked_models.map do |klass|
         
     | 
| 
       10 
11 
     | 
    
         
             
                    iri = klass.iri.is_a?(Array) ? klass.iri.first : klass.iri
         
     | 
| 
       11 
12 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
                    LinkedRails.ontology_class_class.new(klass: klass, iri: iri)
         
     | 
| 
       13 
     | 
    
         
            -
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                    LinkedRails.ontology_class_class.new(klass: klass, iri: iri) if iri
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end.compact
         
     | 
| 
       14 
15 
     | 
    
         
             
                end
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
                def properties
         
     | 
| 
         @@ -26,8 +27,8 @@ module LinkedRails 
     | 
|
| 
       26 
27 
     | 
    
         
             
                    %i[classes properties]
         
     | 
| 
       27 
28 
     | 
    
         
             
                  end
         
     | 
| 
       28 
29 
     | 
    
         | 
| 
       29 
     | 
    
         
            -
                  def requested_resource( 
     | 
| 
       30 
     | 
    
         
            -
                    LinkedRails.ontology_class.new
         
     | 
| 
      
 30 
     | 
    
         
            +
                  def requested_resource(opts, _user_context)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    LinkedRails.ontology_class.new if opts[:iri].include?(new.root_relative_iri)
         
     | 
| 
       31 
32 
     | 
    
         
             
                  end
         
     | 
| 
       32 
33 
     | 
    
         
             
                end
         
     | 
| 
       33 
34 
     | 
    
         
             
              end
         
     |