card 1.93.5 → 1.93.6
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/VERSION +1 -1
- data/db/migrate_core_cards/data/1.12_stylesheets/classic_cards.scss +1 -1
- data/db/migrate_core_cards/data/1.12_stylesheets/traditional.scss +2 -1
- data/lib/card/format/nest.rb +4 -1
- data/lib/card/format/nest/mode.rb +11 -3
- data/lib/card/query.rb +6 -2
- data/lib/card/query/sorting.rb +21 -12
- data/lib/card/query/sql_statement.rb +1 -2
- data/lib/card/view/options.rb +17 -12
- data/mod/Modfile +1 -0
- data/mod/core/layout/simple_modal.html +3 -0
- data/mod/core/set/all/fetch_helper.rb +42 -30
- data/mod/core/spec/format/html_format_spec.rb +10 -17
- data/mod/core/spec/set/all/fetch_helper_spec.rb +48 -0
- data/mod/machines/file/all_script_machine_output/file.js +132 -18
- data/mod/machines/lib/javascript/decko.js.coffee +11 -2
- data/mod/machines/lib/javascript/decko_filter.js.coffee +116 -9
- data/mod/machines/lib/stylesheets/style_cards.scss +24 -3
- data/mod/pointer/lib/javascript/script_pointer_config.js.coffee +16 -6
- data/mod/pointer/set/abstract/00_paging_params.rb +17 -4
- data/mod/pointer/set/abstract/02_pointer/filtered.rb +48 -0
- data/mod/pointer/set/self/input_options.rb +1 -0
- data/mod/pointer/spec/set/self/input_options_spec.rb +1 -1
- data/mod/pointer/template/abstract/02_pointer/filtered/filter_items.haml +34 -0
- data/mod/pointer/template/abstract/02_pointer/filtered/filtered_list_input.haml +30 -0
- data/mod/search/lib/card/filter_query.rb +81 -0
- data/mod/search/set/abstract/00_filter_helper.rb +51 -0
- data/mod/search/set/abstract/01_filter_form_helper.rb +77 -0
- data/mod/search/set/abstract/01_search_params.rb +3 -11
- data/mod/search/set/abstract/02_filter_formgroups.rb +134 -0
- data/mod/search/set/abstract/03_filter.rb +117 -0
- data/mod/search/set/abstract/04_right_filter_form.rb +23 -0
- data/mod/search/set/abstract/search.rb +44 -10
- data/mod/search/set/abstract/wql_search.rb +22 -18
- data/mod/search/spec/set/{all → abstract}/filter_spec.rb +6 -5
- data/mod/search/template/{all/filter → abstract/03_filter}/_filter_input.haml +0 -0
- data/mod/search/template/{all/filter → abstract/03_filter}/filter_form.haml +9 -7
- data/mod/search/template/abstract/search/checkbox_item.haml +7 -0
- data/mod/search/template/abstract/search/select_item.haml +14 -0
- data/mod/standard/set/all/rich_html/editing.rb +4 -4
- data/mod/standard/set/all/rich_html/form_elements.rb +11 -2
- data/mod/standard/set/all/rich_html/modal.rb +26 -19
- data/mod/standard/set/all/rich_html/new.rb +8 -2
- data/mod/standard/set/all/rich_html/wrapper.rb +22 -18
- data/mod/standard/set/type/cardtype.rb +2 -2
- data/mod/standard/spec/set/all/rich_html/editing_spec.rb +0 -1
- data/mod/utility/set/abstract/utility.rb +13 -0
- data/mod/utility/spec/set/abstract/utility_spec.rb +16 -0
- metadata +21 -7
- data/mod/search/set/all/filter.rb +0 -9
@@ -0,0 +1,134 @@
|
|
1
|
+
include_set Abstract::FilterFormHelper
|
2
|
+
|
3
|
+
# FIXME: the vast majority of these need to be moved back to wikirate
|
4
|
+
format :html do
|
5
|
+
view :filter_name_formgroup, cache: :never do
|
6
|
+
text_filter :name
|
7
|
+
end
|
8
|
+
|
9
|
+
view :filter_project_formgroup, cache: :never do
|
10
|
+
select_filter_type_based :project
|
11
|
+
end
|
12
|
+
|
13
|
+
view :filter_year_formgroup, cache: :never do
|
14
|
+
select_filter :year, "Year", "most recent"
|
15
|
+
end
|
16
|
+
|
17
|
+
view :filter_wikirate_topic_formgroup, cache: :never do
|
18
|
+
# select_filter_type_based :wikirate_topic
|
19
|
+
autocomplete_filter :wikirate_topic
|
20
|
+
end
|
21
|
+
|
22
|
+
view :filter_metric_formgroup, cache: :never do
|
23
|
+
# select_filter_type_based :metric
|
24
|
+
autocomplete_filter :metric
|
25
|
+
end
|
26
|
+
|
27
|
+
view :filter_wikirate_company_formgroup, cache: :never do
|
28
|
+
# select_filter_type_based :wikirate_company
|
29
|
+
autocomplete_filter :wikirate_company
|
30
|
+
end
|
31
|
+
|
32
|
+
view :filter_research_policy_formgroup, cache: :never do
|
33
|
+
multiselect_filter :research_policy, "Research Policy"
|
34
|
+
end
|
35
|
+
|
36
|
+
def research_policy_select
|
37
|
+
select_filter_type_based :research_policy
|
38
|
+
end
|
39
|
+
|
40
|
+
view :filter_metric_type_formgroup, cache: :never do
|
41
|
+
multiselect_filter :metric_type, "Metric Type"
|
42
|
+
end
|
43
|
+
|
44
|
+
def metric_type_select
|
45
|
+
select_filter :metric_type, "Metric Type"
|
46
|
+
end
|
47
|
+
|
48
|
+
view :filter_metric_value_formgroup, cache: :never do
|
49
|
+
select_filter :metric_value, "Value", "exists"
|
50
|
+
end
|
51
|
+
|
52
|
+
view :filter_designer_formgroup, cache: :never do
|
53
|
+
select_filter :designer, "Designer"
|
54
|
+
end
|
55
|
+
|
56
|
+
view :filter_importance_formgroup, cache: :never do
|
57
|
+
multiselect_filter :importance, "My Vote", %w[upvotes novotes]
|
58
|
+
end
|
59
|
+
|
60
|
+
view :filter_industry_formgroup, cache: :never do
|
61
|
+
select_filter :industry, "Industry"
|
62
|
+
end
|
63
|
+
|
64
|
+
def sort_options
|
65
|
+
{}
|
66
|
+
end
|
67
|
+
|
68
|
+
def default_year_option
|
69
|
+
{ "Most Recent" => "latest" }
|
70
|
+
end
|
71
|
+
|
72
|
+
def year_options
|
73
|
+
type_options(:year, "desc").each_with_object(default_year_option) do |v, h|
|
74
|
+
h[v] = v
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def metric_value_options
|
79
|
+
opts = {
|
80
|
+
"All" => "all",
|
81
|
+
"Researched" => "exists",
|
82
|
+
"Known" => "known",
|
83
|
+
"Unknown" => "unknown",
|
84
|
+
"Not Researched" => "none",
|
85
|
+
"Edited today" => "today",
|
86
|
+
"Edited this week" => "week",
|
87
|
+
"Edited this month" => "month",
|
88
|
+
"Outliers" => "outliers"
|
89
|
+
}
|
90
|
+
return opts unless filter_param(:range)
|
91
|
+
opts.each_with_object({}) do |(k, v), h|
|
92
|
+
h[add_range(k, v)] = v
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_range key, _value
|
97
|
+
key # unless selected_value?(value)
|
98
|
+
# range = filter_param :range
|
99
|
+
# "#{range[:from]} <= #{key} < #{range[:to]}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def selected_value? value
|
103
|
+
(filter_param(:metric_value) && value == filter_param(:metric_value)) ||
|
104
|
+
value == "exists"
|
105
|
+
end
|
106
|
+
|
107
|
+
def metric_type_options
|
108
|
+
%i[researched formula wiki_rating].map { |n| Card.quick_fetch(n).name }
|
109
|
+
end
|
110
|
+
|
111
|
+
def research_policy_options
|
112
|
+
type_options :research_policy
|
113
|
+
end
|
114
|
+
|
115
|
+
def importance_options
|
116
|
+
{ "I voted FOR" => :upvotes,
|
117
|
+
"I voted AGAINST" => :downvotes,
|
118
|
+
"I did NOT vote" => :novotes }
|
119
|
+
end
|
120
|
+
|
121
|
+
def industry_options
|
122
|
+
card_name = CompanyFilterQuery::INDUSTRY_METRIC_NAME
|
123
|
+
Card[card_name].value_options
|
124
|
+
end
|
125
|
+
|
126
|
+
def designer_options
|
127
|
+
metrics = Card.search type_id: MetricID, return: :name
|
128
|
+
metrics.map do |m|
|
129
|
+
names = m.to_name.parts
|
130
|
+
# score metric?
|
131
|
+
names.length == 3 ? names[2] : names[0]
|
132
|
+
end.uniq!(&:downcase).sort_by!(&:downcase)
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
include_set Abstract::FilterFormgroups
|
2
|
+
include_set Abstract::Utility
|
3
|
+
|
4
|
+
def filter_class
|
5
|
+
Card::FilterQuery
|
6
|
+
end
|
7
|
+
|
8
|
+
def filter_and_sort_wql
|
9
|
+
sort? ? filter_wql.merge(sort_wql) : filter_wql
|
10
|
+
end
|
11
|
+
|
12
|
+
def filter_wql
|
13
|
+
return {} if filter_hash.empty?
|
14
|
+
filter_wql_from_params
|
15
|
+
end
|
16
|
+
|
17
|
+
# separate method is needed for tests
|
18
|
+
def filter_wql_from_params
|
19
|
+
filter_class.new(filter_keys_with_values, blocked_id_wql).to_wql
|
20
|
+
end
|
21
|
+
|
22
|
+
def sort_wql
|
23
|
+
return {} if !sort? || sort_param.blank?
|
24
|
+
sort_hash
|
25
|
+
end
|
26
|
+
|
27
|
+
def sort?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_sort
|
32
|
+
sort_param || default_sort_option
|
33
|
+
end
|
34
|
+
|
35
|
+
def blocked_id_wql
|
36
|
+
not_ids = filter_param :not_ids
|
37
|
+
not_ids.present? ? { id: ["not in", not_ids.split(",")] } : {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def advanced_filter_keys
|
41
|
+
[]
|
42
|
+
end
|
43
|
+
|
44
|
+
# all filter keys in the order they were selected
|
45
|
+
def all_filter_keys
|
46
|
+
@all_filter_keys ||= filter_keys_from_params | filter_keys | advanced_filter_keys
|
47
|
+
end
|
48
|
+
|
49
|
+
def filter_keys
|
50
|
+
[:name]
|
51
|
+
end
|
52
|
+
|
53
|
+
def filter_keys_from_params
|
54
|
+
filter_hash.keys.map(&:to_sym) - [:not_ids]
|
55
|
+
end
|
56
|
+
|
57
|
+
format :html do
|
58
|
+
delegate :filter_hash, to: :card
|
59
|
+
|
60
|
+
def filter_fields slot_selector: nil, sort_field: nil
|
61
|
+
form_args = { action: filter_action_path, class: "slotter" }
|
62
|
+
form_args["data-slot-selector"] = slot_selector if slot_selector
|
63
|
+
filter_form filter_form_data, sort_field, form_args
|
64
|
+
end
|
65
|
+
|
66
|
+
def filter_form_data
|
67
|
+
all_filter_keys.each_with_object({}) do |cat, h|
|
68
|
+
h[cat] = { label: filter_label(cat),
|
69
|
+
input_field: _render("filter_#{cat}_formgroup"),
|
70
|
+
active: show_filter_field?(cat) }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def show_filter_field? field
|
75
|
+
filter_hash.present? ? filter_hash[field] : card.default_filter_option[field]
|
76
|
+
end
|
77
|
+
|
78
|
+
def filter_label field
|
79
|
+
return "Keyword" if field.to_sym == :name
|
80
|
+
Card.fetch_name(field) { field.to_s.capitalize }
|
81
|
+
end
|
82
|
+
|
83
|
+
def filter_action_path
|
84
|
+
path
|
85
|
+
end
|
86
|
+
|
87
|
+
view :filter_form, cache: :never do
|
88
|
+
filter_fields slot_selector: "._filter-result-slot",
|
89
|
+
sort_field: _render(:sort_formgroup)
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param data [Hash] the filter categories. The hash needs for every category
|
93
|
+
# a hash with a label and a input_field entry.
|
94
|
+
def filter_form data={}, sort_input_field=nil, form_args={}
|
95
|
+
haml :filter_form, categories: data,
|
96
|
+
sort_input_field: sort_input_field,
|
97
|
+
form_args: form_args
|
98
|
+
end
|
99
|
+
|
100
|
+
def sort_options
|
101
|
+
{
|
102
|
+
"Alphabetical": :name,
|
103
|
+
"Recently Updated": :updated_at
|
104
|
+
}
|
105
|
+
end
|
106
|
+
|
107
|
+
view :sort_formgroup, cache: :never do
|
108
|
+
select_tag "sort",
|
109
|
+
options_for_select(sort_options, card.current_sort),
|
110
|
+
class: "pointer-select _filter-sort",
|
111
|
+
"data-minimum-results-for-search": "Infinity"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def default_sort_option
|
116
|
+
wql_from_content[:sort]
|
117
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# To be included in a field card to get a filter for the parent.
|
2
|
+
# The core view renders a filter for the left card.
|
3
|
+
|
4
|
+
include_set Set::Abstract::Filter
|
5
|
+
|
6
|
+
def virtual?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
format :html do
|
11
|
+
def filter_action_path
|
12
|
+
path mark: card.name.left, view: filter_view
|
13
|
+
end
|
14
|
+
|
15
|
+
# FIXME: wikirate-specific reference in selector
|
16
|
+
view :core, cache: :never do
|
17
|
+
filter_fields slot_selector: ".RIGHT-all_metric_value.filter_result-view"
|
18
|
+
end
|
19
|
+
|
20
|
+
def filter_view
|
21
|
+
:filter_result
|
22
|
+
end
|
23
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
include_set Abstract::SearchParams
|
2
2
|
include_set Abstract::Paging
|
3
|
+
include_set Abstract::Filter
|
3
4
|
|
4
5
|
def search _args={}
|
5
6
|
raise Error, "search not overridden"
|
@@ -106,26 +107,59 @@ format :csv do
|
|
106
107
|
end
|
107
108
|
|
108
109
|
format :html do
|
109
|
-
|
110
|
+
def with_results
|
110
111
|
return render_no_search_results if search_with_params.empty?
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
yield
|
113
|
+
end
|
114
|
+
|
115
|
+
view :card_list do
|
116
|
+
with_results do
|
117
|
+
search_result_list "search-result-list" do |item_card|
|
118
|
+
card_list_item item_card
|
117
119
|
end
|
118
120
|
end
|
119
121
|
end
|
120
122
|
|
121
|
-
def
|
123
|
+
def card_list_item item_card
|
124
|
+
nest_item item_card, size: voo.size do |rendered, item_view|
|
125
|
+
%(<div class="search-result-item item-#{item_view}">#{rendered}</div>)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def search_result_list klass
|
122
130
|
with_paging do
|
123
|
-
wrap_with :div, class:
|
124
|
-
|
131
|
+
wrap_with :div, class: klass do
|
132
|
+
search_with_params.map do |item_card|
|
133
|
+
yield item_card
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
view :select_item, cache: :never do
|
140
|
+
wrap do
|
141
|
+
haml :select_item
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def default_select_item_args _args
|
146
|
+
class_up "card-slot", "_filter-result-slot"
|
147
|
+
end
|
148
|
+
|
149
|
+
view :checkbox_list, cache: :never do
|
150
|
+
with_results do
|
151
|
+
search_result_list "_search-checkbox-list" do |item_card|
|
152
|
+
checkbox_item item_card
|
125
153
|
end
|
126
154
|
end
|
127
155
|
end
|
128
156
|
|
157
|
+
def checkbox_item item_card
|
158
|
+
subformat(item_card).wrap do
|
159
|
+
haml :checkbox_item, unique_id: unique_id, item_card: item_card
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
129
163
|
def closed_limit
|
130
164
|
[search_params[:limit].to_i, Card.config.closed_search_limit].min
|
131
165
|
end
|
@@ -8,34 +8,38 @@ def search args={}
|
|
8
8
|
query.run
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
query = content
|
15
|
-
query = query.is_a?(Hash) ? query : parse_json_query(query)
|
16
|
-
query.symbolize_keys
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def query_args args={}
|
21
|
-
wql_hash.merge args
|
11
|
+
def fetch_query args={}
|
12
|
+
@query ||= {}
|
13
|
+
@query[args.to_s] ||= query(args.clone) # cache query
|
22
14
|
end
|
23
15
|
|
24
16
|
def query args={}
|
25
17
|
Query.new standardized_query_args(args), name
|
26
18
|
end
|
27
19
|
|
28
|
-
def fetch_query args={}
|
29
|
-
@query ||= {}
|
30
|
-
@query[args.to_s] ||= query(args.clone) # cache query
|
31
|
-
end
|
32
|
-
|
33
20
|
def standardized_query_args args
|
34
21
|
args = query_args(args).symbolize_keys
|
35
22
|
args[:context] ||= name
|
36
23
|
args
|
37
24
|
end
|
38
25
|
|
26
|
+
# override this to define search
|
27
|
+
def wql_hash
|
28
|
+
@wql_hash ||= wql_from_content.merge filter_and_sort_wql
|
29
|
+
end
|
30
|
+
|
31
|
+
def wql_from_content
|
32
|
+
@wql_from_content ||= begin
|
33
|
+
query = content
|
34
|
+
query = query.is_a?(Hash) ? query : parse_json_query(query)
|
35
|
+
query.symbolize_keys
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def query_args args={}
|
40
|
+
wql_hash.merge args
|
41
|
+
end
|
42
|
+
|
39
43
|
def parse_json_query query
|
40
44
|
empty_query_error! if query.empty?
|
41
45
|
JSON.parse query
|
@@ -49,8 +53,8 @@ def empty_query_error!
|
|
49
53
|
end
|
50
54
|
|
51
55
|
format do
|
52
|
-
def
|
53
|
-
|
56
|
+
def default_limit
|
57
|
+
card_content_limit || super
|
54
58
|
end
|
55
59
|
|
56
60
|
def card_content_limit
|
@@ -1,9 +1,10 @@
|
|
1
|
-
describe Card::Set::
|
1
|
+
describe Card::Set::Abstract::Filter do
|
2
2
|
subject do
|
3
|
-
Card
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
search_card = Card.new type: "Search"
|
4
|
+
search_card.format.filter_form a: { input_field: "<input id='a'/>", label: "A" },
|
5
|
+
b: { input_field: "<select id='b'/>", label: "B" },
|
6
|
+
c: { input_field: "<select id='c'/>", label: "C",
|
7
|
+
active: true }
|
7
8
|
end
|
8
9
|
|
9
10
|
specify "#filter_form" do
|
File without changes
|
@@ -8,9 +8,11 @@
|
|
8
8
|
- unless category[:active]
|
9
9
|
= haml_partial :filter_input, key: key, category: category
|
10
10
|
|
11
|
-
%form._filter-form{form_args, "accept-charset"
|
12
|
-
|
13
|
-
|
11
|
+
%form._filter-form{form_args, "accept-charset": "UTF-8",
|
12
|
+
"data-remote": "true",
|
13
|
+
method: "get"}
|
14
|
+
- not_ids = params.dig :filter, :not_ids
|
15
|
+
%input{ type: :hidden, name: "filter[not_ids]", class: "_not-ids", value: not_ids }
|
14
16
|
.d-flex.flex-row
|
15
17
|
- if sort_input_field
|
16
18
|
%i.material-icons.text-muted.md-24.p-2 sort
|
@@ -25,10 +27,10 @@
|
|
25
27
|
= haml_partial :filter_input, key: key, category: category
|
26
28
|
|
27
29
|
.dropdown._add-filter-dropdown
|
28
|
-
%button.btn.btn-secondary.dropdown-toggle{"aria-expanded"
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
%button.btn.btn-secondary.dropdown-toggle{"aria-expanded": "false",
|
31
|
+
"aria-haspopup": "true",
|
32
|
+
"data-toggle": "dropdown",
|
33
|
+
type: "button" }
|
32
34
|
Add filter
|
33
35
|
.dropdown-menu
|
34
36
|
- categories.each do |key, category|
|