Skip to content
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

fix: allow all chars on text filters #2093

Merged
merged 16 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/controllers/avo/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def index
end

# Apply filters to the current query

Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
filters_to_be_applied.each do |filter_class, filter_value|
@query = filter_class.safe_constantize.new(
arguments: @resource.get_filter_arguments(filter_class)
Expand Down Expand Up @@ -357,12 +358,12 @@ def set_actions
def set_applied_filters
reset_filters if params[:reset_filter]

@applied_filters = Avo::Filters::BaseFilter.decode_filters(fetch_filters)
return @applied_filters = {} if (fetched_filters = fetch_filters).blank?

@applied_filters = Avo::Filters::BaseFilter.decode_filters(fetched_filters)

# Some filters react to others and will have to be merged into this
@applied_filters = @applied_filters.merge reactive_filters
rescue
@applied_filters = {}
end

def reactive_filters
Expand Down
33 changes: 22 additions & 11 deletions app/javascript/js/controllers/filter_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,28 @@ export default class extends Controller {
return param
}

b64EncodeUnicode(str) {
// first we use encodeURIComponent to get percent-encoded UTF-8,
// then we convert the percent encodings into raw bytes which
// can be fed into btoa.
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
(match, p1) => String.fromCharCode(`0x${p1}`)))
decode(filters) {
return JSON.parse(
new TextDecoder().decode(
Uint8Array.from(
atob(
decodeURIComponent(filters)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
), (m) => m.codePointAt(0)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
);
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
}

b64DecodeUnicode(str) {
// Going backwards: from bytestream, to percent-encoding, to original string.
return decodeURIComponent(atob(str).split('').map((c) => `%${(`00${c.charCodeAt(0).toString(16)}`).slice(-2)}`).join(''))
encode(filtered) {
return encodeURIComponent(
btoa(
String.fromCodePoint(
...new TextEncoder().encode(
JSON.stringify(filtered)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
)
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
);
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
}

changeFilter() {
Expand All @@ -47,7 +58,7 @@ export default class extends Controller {

// Decode the filters
if (filters) {
filters = JSON.parse(this.b64DecodeUnicode(filters))
filters = this.decode(filters)
} else {
filters = {}
}
Expand All @@ -68,7 +79,7 @@ export default class extends Controller {

// Encode the filters and their values
if (filtered && Object.keys(filtered).length > 0) {
encodedFilters = this.b64EncodeUnicode(JSON.stringify(filtered))
encodedFilters = this.encode(filtered)
}

this.navigateToURLWithFilters(encodedFilters)
Expand Down
2 changes: 0 additions & 2 deletions lib/avo/filters/base_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ def current_user
class << self
def decode_filters(filter_params)
JSON.parse(Base64.decode64(filter_params))
rescue
{}
end

def encode_filters(filter_params)
Expand Down
25 changes: 23 additions & 2 deletions spec/system/avo/filters/filters_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,12 @@

let!(:team_without_members) { create :team, name: "Without Members" }
let!(:team_with_members) { create :team, name: "With Members" }
let!(:team_音楽) { create :team, name: "音楽 ✓" }

before do
team_with_members.team_members << user
team_without_members.team_members << user
team_音楽.team_members << user
Paul-Bob marked this conversation as resolved.
Show resolved Hide resolved
end

let(:url) { "/admin/resources/teams?view_type=table" }
Expand All @@ -288,7 +290,7 @@

it "filters by name" do
visit url
expect(page).to have_text("Displaying 2 item")
expect(page).to have_text("Displaying 3 item")

open_filters_menu
fill_in "avo_filters_name_filter", with: "With Members"
Expand All @@ -302,7 +304,26 @@

click_on "Reset filters"
wait_for_loaded
expect(page).to have_text("Displaying 2 item")
expect(page).to have_text("Displaying 3 item")
end

it "filters by 音楽 ✓" do
visit url
expect(page).to have_text("Displaying 3 item")

open_filters_menu
fill_in "avo_filters_name_filter", with: "音楽 ✓"
click_on "Filter by name"
wait_for_loaded
expect(page).to have_text("Displaying 1 item")

open_filters_menu
expect(page).to have_text "音楽 ✓"
expect(page).to have_link("Reset filters")

click_on "Reset filters"
wait_for_loaded
expect(page).to have_text("Displaying 3 item")
end
end
end
Expand Down
Loading