Skip to content

Commit c2145ab

Browse files
committed
WIP adding specs and docs for collection component, fixed toggle naming
1 parent 97f5827 commit c2145ab

File tree

12 files changed

+524
-21
lines changed

12 files changed

+524
-21
lines changed

app/concepts/matestack/ui/core/collection/filter/filter.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@ const componentDef = {
1414
methods: {
1515
submitFilter: function(){
1616
var url;
17+
var filter = this.filter
1718
for (var key in this.filter) {
18-
url = this.updateQueryParams(this.componentConfig["id"] + "-filter-" + key, this.filter[key])
19-
url = this.updateQueryParams(this.componentConfig["id"] + "-offset", 0, url)
19+
url = this.updateQueryParams(this.componentConfig["id"] + "-filter-" + key, this.filter[key], url)
2020
}
21+
url = this.updateQueryParams(this.componentConfig["id"] + "-offset", 0, url)
2122
window.history.pushState({matestackApp: true, url: url}, null, url);
2223
matestackEventHub.$emit(this.componentConfig["id"] + "-update")
2324
},
2425
resetFilter: function(){
2526
var url;
2627
for (var key in this.filter) {
27-
url = this.updateQueryParams(this.componentConfig["id"] + "-filter-" + key, null)
28+
url = this.updateQueryParams(this.componentConfig["id"] + "-filter-" + key, null, url)
2829
this.filter[key] = null;
2930
this.$forceUpdate();
3031
}

app/concepts/matestack/ui/core/collection/order/order.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const componentDef = {
1212
}
1313
},
1414
methods: {
15-
toggelOrder: function(key){
15+
toggleOrder: function(key){
1616
if (this.ordering[key] == undefined) {
1717
this.ordering[key] = "asc"
1818
} else if (this.ordering[key] == "asc") {

app/concepts/matestack/ui/core/collection/order/toggel/toggel.haml

Lines changed: 0 additions & 3 deletions
This file was deleted.

app/concepts/matestack/ui/core/collection/order/toggel/toggel.rb

Lines changed: 0 additions & 6 deletions
This file was deleted.

app/concepts/matestack/ui/core/collection/order/toggel/indicator/indicator.rb renamed to app/concepts/matestack/ui/core/collection/order/toggle/indicator/indicator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module Matestack::Ui::Core::Collection::Order::Toggel::Indicator
1+
module Matestack::Ui::Core::Collection::Order::Toggle::Indicator
22
class Indicator < Matestack::Ui::Core::Component::Static
33

44
def response
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
%a{@tag_attributes, "@click": "toggleOrder(\"#{@component_config[:key]}\")"}
2+
- if block_given?
3+
= yield
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Matestack::Ui::Core::Collection::Order::Toggle
2+
class Toggle < Matestack::Ui::Core::Component::Static
3+
4+
5+
end
6+
end

docs/components/collection.md

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# matestack core component: Collection
2+
3+
Show [specs](../../spec/usage/components/collection_spec.rb)
4+
5+
The `collection` component is designed:
6+
7+
- to display instances from a model (Active Record or similar)
8+
- filter the displayed instances without full page reload
9+
- paginate the displayed instances without full page reload
10+
- order the displayed instances without full page reload
11+
12+
The `collection` component should be as flexible as possible while still reducing the complexity of implementing all classic collection features by hand
13+
14+
## Prerequisites
15+
16+
We use a ActiveRecord Model in the following examples. This Model has two columns: `id` and `title`.
17+
18+
## Examples
19+
20+
### Filterable collection
21+
22+
In this example, we want to display ALL instances of `DummyModel` and filter the collection by title using a text input.
23+
24+
```ruby
25+
class Pages::MyApp::Collection < Matestack::Ui::Page
26+
27+
include Matestack::Ui::Core::Collection::Helper
28+
29+
def prepare
30+
my_collection_id = "my-first-collection"
31+
32+
current_filter = get_collection_filter(my_collection_id)
33+
34+
my_base_query = DummyModel.all
35+
36+
my_filtered_query = my_base_query
37+
.where("title LIKE ?", "%#{current_filter[:title]}%")
38+
39+
@my_collection = set_collection({
40+
id: my_collection_id,
41+
data: my_filtered_query
42+
})
43+
end
44+
45+
def response
46+
components {
47+
heading size: 2, text: "My Collection"
48+
49+
partial :filter
50+
partial :content
51+
}
52+
end
53+
54+
def filter
55+
partial {
56+
collection_filter @my_collection.config do
57+
58+
collection_filter_input key: :title, type: :text, placeholder: "Filter by Title"
59+
collection_filter_submit do
60+
button text: "filter"
61+
end
62+
collection_filter_reset do
63+
button text: "reset"
64+
end
65+
66+
end
67+
}
68+
end
69+
70+
def content
71+
partial {
72+
collection_content @my_collection.config do
73+
ul do
74+
@my_collection.data.each do |dummy|
75+
li do
76+
plain dummy.title
77+
end
78+
end
79+
end
80+
end
81+
}
82+
end
83+
84+
end
85+
```
86+
87+
### Filtered & paginated collection
88+
89+
In this example, we want to display only a limited (10) amount of instances of `DummyModel` at once and filter the collection by title using a text input. We want to display the classic pagination buttons and information below the list of paginated instances.
90+
91+
```ruby
92+
class Pages::MyApp::Collection < Matestack::Ui::Page
93+
94+
include Matestack::Ui::Core::Collection::Helper
95+
96+
def prepare
97+
my_collection_id = "my-first-collection"
98+
99+
current_filter = get_collection_filter(my_collection_id)
100+
101+
my_base_query = DummyModel.all
102+
103+
my_filtered_query = my_base_query
104+
.where("title LIKE ?", "%#{current_filter[:title]}%")
105+
106+
@my_collection = set_collection({
107+
id: my_collection_id,
108+
data: my_filtered_query,
109+
init_limit: 10, #set a limit
110+
filtered_count: my_filtered_query.count, #tell the component how to count the filtered result
111+
base_count: my_base_query.count #tell the component how to count the total amount
112+
})
113+
end
114+
115+
def response
116+
components {
117+
heading size: 2, text: "My Collection"
118+
119+
partial :filter
120+
partial :content
121+
}
122+
end
123+
124+
def filter
125+
partial {
126+
collection_filter @my_collection.config do
127+
128+
collection_filter_input key: :title, type: :text, placeholder: "Filter by Title"
129+
collection_filter_submit do
130+
button text: "filter"
131+
end
132+
collection_filter_reset do
133+
button text: "reset"
134+
end
135+
136+
end
137+
}
138+
end
139+
140+
def content
141+
partial {
142+
collection_content @my_collection.config do
143+
ul do
144+
# now we use paginated_data!
145+
@my_collection.paginated_data.each do |dummy|
146+
li do
147+
plain dummy.title
148+
end
149+
end
150+
end
151+
partial :paginator #has to be placed within `collection_content`!
152+
end
153+
}
154+
end
155+
156+
def paginator
157+
partial {
158+
plain "showing #{@my_collection.from}"
159+
plain "to #{@my_collection.to}"
160+
plain "of #{@my_collection.filtered_count}"
161+
plain "from total #{@my_collection.base_count}"
162+
163+
collection_content_previous do
164+
button text: "previous"
165+
end
166+
167+
@my_collection.pages.each do |page|
168+
collection_content_page_link page: page do
169+
button text: page
170+
end
171+
end
172+
173+
collection_content_next do
174+
button text: "next"
175+
end
176+
}
177+
end
178+
179+
180+
end
181+
```
182+
183+
### Filtered & paginated & ordered collection
184+
185+
In this example, we want to display only a limited (10) amount of instances of `DummyModel` at once and filter the collection by title using a text input. We want to display the classic pagination buttons and information below the list of paginated instances. Additionally, we want to order the collection by title ascending or descending.
186+
187+
```ruby
188+
class Pages::MyApp::Collection < Matestack::Ui::Page
189+
190+
include Matestack::Ui::Core::Collection::Helper
191+
192+
def prepare
193+
my_collection_id = "my-first-collection"
194+
195+
current_filter = get_collection_filter(my_collection_id)
196+
current_order = get_collection_order(my_collection_id) #now we need the current order state from the url params
197+
198+
my_base_query = DummyModel.all
199+
200+
my_filtered_query = my_base_query
201+
.where("title LIKE ?", "%#{current_filter[:title]}%")
202+
.order(current_order) # and apply the state to the query
203+
204+
@my_collection = set_collection({
205+
id: my_collection_id,
206+
data: my_filtered_query,
207+
init_limit: 10,
208+
filtered_count: my_filtered_query.count,
209+
base_count: my_base_query.count
210+
})
211+
end
212+
213+
def response
214+
components {
215+
heading size: 2, text: "My Collection"
216+
217+
partial :filter
218+
partial :ordering
219+
partial :content
220+
}
221+
end
222+
223+
def filter
224+
partial {
225+
collection_filter @my_collection.config do
226+
227+
collection_filter_input key: :title, type: :text, placeholder: "Filter by Title"
228+
collection_filter_submit do
229+
button text: "filter"
230+
end
231+
collection_filter_reset do
232+
button text: "reset"
233+
end
234+
235+
end
236+
}
237+
end
238+
239+
def ordering
240+
partial {
241+
collection_order @my_collection.config do
242+
243+
plain "sort by:"
244+
collection_order_toggle key: :title do
245+
button do
246+
# we want to use an "arrow up (unicode: &#8593;)"
247+
# and and an "arrow down (unicode: &#8595;)" in order to
248+
# visualize the current order state
249+
collection_order_toggle_indicator key: :title, asc: '&#8593;', desc: '&#8595;'
250+
plain "title"
251+
end
252+
end
253+
254+
end
255+
}
256+
end
257+
258+
def content
259+
partial {
260+
collection_content @my_collection.config do
261+
ul do
262+
@my_collection.paginated_data.each do |dummy|
263+
li do
264+
plain dummy.title
265+
end
266+
end
267+
end
268+
partial :paginator
269+
end
270+
}
271+
end
272+
273+
def paginator
274+
partial {
275+
plain "showing #{@my_collection.from}"
276+
plain "to #{@my_collection.to}"
277+
plain "of #{@my_collection.filtered_count}"
278+
plain "from total #{@my_collection.base_count}"
279+
280+
collection_content_previous do
281+
button text: "previous"
282+
end
283+
284+
@my_collection.pages.each do |page|
285+
collection_content_page_link page: page do
286+
button text: page
287+
end
288+
end
289+
290+
collection_content_next do
291+
button text: "next"
292+
end
293+
}
294+
end
295+
296+
297+
end
298+
```
299+
300+
### Action enriched collection

spec/dummy/app/matestack/pages/my_app/collection.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def filter
3737
collection_filter @my_collection.config do
3838

3939
collection_filter_input key: :title, type: :text, placeholder: "Filter by Title"
40+
collection_filter_input id: "my-description-filter-input", key: :description, type: :text, placeholder: "Filter by description"
4041
collection_filter_submit do
4142
button text: "filter"
4243
end
@@ -52,9 +53,9 @@ def ordering
5253
partial {
5354
collection_order @my_collection.config do
5455
plain "sort by: "
55-
collection_order_toggel key: :title do
56+
collection_order_toggle key: :title do
5657
button do
57-
collection_order_toggel_indicator key: :title, asc: '&#8593;', desc: '&#8595;'
58+
collection_order_toggle_indicator key: :title, asc: '&#8593;', desc: '&#8595;'
5859
plain "title"
5960
end
6061
end

0 commit comments

Comments
 (0)