-
Notifications
You must be signed in to change notification settings - Fork 20
Ingestion filters. Fixes #1192 #1201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
078a74a
154629d
ff960b1
0e74413
d0dfe3e
b30a068
006ea47
4142959
a19883a
f2b0854
09350a5
de60848
767872e
623e6e3
9b1da73
6b3bce6
2d0a19c
0e6cff3
4c35c7a
de8baae
474c2b5
6c01820
04395fd
2f4b272
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| var SourceFilters = { | ||
| lastId: function () { | ||
| var existing_list_item_ids = $(".source-filter-form").map(function (i, c) { return $(c).data("id-in-filter-list") }); | ||
| if (existing_list_item_ids.length == 0) return 0; | ||
| return Math.max.apply(null, existing_list_item_ids) + 1; | ||
| }, | ||
|
|
||
| add: function () { | ||
| var new_form = $($('#source-filter-template').clone().html().replace(/REPLACE_ME/g, SourceFilters.lastId())); | ||
| new_form.appendTo('#source-filter-list'); | ||
|
|
||
| return false; // Stop form being submitted | ||
| }, | ||
|
|
||
| addBlockFilter: function () { | ||
| var new_form = $($('#source-filter-template').clone().html().replace(/REPLACE_ME/g, SourceFilters.lastId()).replace(/allow/, 'block')); | ||
| new_form.appendTo('#source-block-list'); | ||
|
|
||
| return false; // Stop form being submitted | ||
| }, | ||
|
|
||
| delete: function () { | ||
| $(this).parents('.source-filter-form').fadeOut().find("input[name$='[_destroy]']").val("true"); | ||
| } | ||
| }; | ||
|
|
||
| document.addEventListener("turbolinks:load", function () { | ||
| $('#source-filters') | ||
| .on('click', '#add-source-filter-btn', SourceFilters.add) | ||
| .on('click', '#add-source-filter-btn-label', SourceFilters.add) | ||
| .on('click', '.delete-source-filter-btn', SourceFilters.delete); | ||
| $('#source-block-filters') | ||
| .on('click', '#add-source-block-filter-btn', SourceFilters.addBlockFilter) | ||
| .on('click', '#add-source-block-filter-btn-label', SourceFilters.addBlockFilter) | ||
| .on('click', '.delete-source-filter-btn', SourceFilters.delete); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| .source-filter-form { | ||
| display: flex; | ||
| gap: 1em; | ||
| margin-bottom: 4px; | ||
|
|
||
| label { | ||
| margin-right: 4px; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| class SourceFilter < ApplicationRecord | ||
| belongs_to :source | ||
|
|
||
| auto_strip_attributes :filter_value | ||
eilmiv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| validates :filter_mode, :filter_by, presence: true | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should validate presence of the value too? |
||
|
|
||
| enum :filter_by, { | ||
| target_audience: 'target_audience', | ||
| keyword: 'keyword', | ||
| title: 'title', | ||
| description: 'description', | ||
| description_contains: 'description_contains', | ||
| url: 'url', | ||
| url_prefix: 'url_prefix', | ||
| doi: 'doi', | ||
| license: 'license', | ||
| difficulty_level: 'difficulty_level', | ||
| resource_type: 'resource_type', | ||
| prerequisites_contains: 'prerequisites_contains', | ||
| learning_objectives_contains: 'learning_objectives_contains', | ||
| subtitle: 'subtitle', | ||
| subtitle_contains: 'subtitle_contains', | ||
| city: 'city', | ||
| country: 'country', | ||
| event_type: 'event_type', | ||
| timezone: 'timezone' | ||
| } | ||
|
|
||
| enum :filter_mode, { | ||
| allow: 'allow', | ||
| block: 'block' | ||
| } | ||
|
|
||
| def match(item) | ||
| return false unless item.respond_to?(filter_property) | ||
|
|
||
| val = item.send(filter_property) | ||
|
|
||
| # string match | ||
| if %w[title url doi description license difficulty_level subtitle city country timezone].include?(filter_by) | ||
| val.to_s.casecmp?(filter_value) | ||
| # prefix string match | ||
| elsif %w[url_prefix].include?(filter_by) | ||
| val.to_s.downcase.start_with?(filter_value.downcase) | ||
| # contains string match | ||
| elsif %w[description_contains prerequisites_contains learning_objectives_contains subtitle_contains].include?(filter_by) | ||
| val.to_s.downcase.include?(filter_value.downcase) | ||
| # array string match | ||
| elsif %w[target_audience keyword resource_type event_type].include?(filter_by) | ||
|
Comment on lines
+40
to
+49
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of doing this, lets declare all the possible filters along with their types in a constant or something, then lookup the type and do the appropriate comparison in this method. |
||
| val.any? { |i| i.to_s.casecmp?(filter_value) } | ||
eilmiv marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| else | ||
| false | ||
| end | ||
| end | ||
|
|
||
| def filter_property | ||
| { | ||
| 'event_type' => 'event_types', | ||
| 'keyword' => 'keywords', | ||
| 'url_prefix' => 'url', | ||
| 'description_contains' => 'description', | ||
| 'prerequisites_contains' => 'prerequisites', | ||
| 'learning_objectives_contains' => 'learning_objectives', | ||
| 'subtitle_contains' => 'subtitle', | ||
| 'license' => 'licence' | ||
| }.fetch(filter_by, filter_by) | ||
|
Comment on lines
+57
to
+66
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As above, the mapping from the filter name to the model attribute could also be part of the "possible filters" constant. |
||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <div class="form-inline source-filter-form" data-id-in-filter-list="<%= f.options[:child_index] %>"> | ||
| <%= f.input :filter_by, collection: SourceFilter.filter_bies.keys.map { |t| [t.humanize, t] }, include_blank: false, required: false %> | ||
|
|
||
| <%= f.input :filter_value %> | ||
|
|
||
| <%= f.input :filter_mode, collection: SourceFilter.filter_modes.keys.map { |m| [m.humanize, m] }, include_blank: false, as: :hidden %> | ||
|
|
||
| <%= f.input :_destroy, as: :hidden %> | ||
|
|
||
| <button type="button" class="btn btn-danger delete-source-filter-btn">Remove</button> | ||
| </div> |
Uh oh!
There was an error while loading. Please reload this page.