Merge lp:~stephen-stewart/snapweb/remote-and-local-collections-with-sorting-and-filtering into lp:~snappy-dev/snapweb/trunk

Proposed by Stephen Stewart on 2015-05-27
Status: Merged
Approved by: Sergio Schvezov on 2015-05-29
Approved revision: 157
Merged at revision: 150
Proposed branch: lp:~stephen-stewart/snapweb/remote-and-local-collections-with-sorting-and-filtering
Merge into: lp:~snappy-dev/snapweb/trunk
Prerequisite: lp:~stephen-stewart/snapweb/repent-harlequin-said-the-ticktockman
Diff against target: 393 lines (+209/-29)
14 files modified
www/src/css/button.css (+50/-0)
www/src/css/headline.css (+6/-0)
www/src/css/snaplist.css (+11/-2)
www/src/js/collections/snaplist.js (+4/-1)
www/src/js/controllers/store.js (+3/-3)
www/src/js/templates/home.hbs (+0/-5)
www/src/js/templates/snaplist.hbs (+23/-0)
www/src/js/templates/store.hbs (+1/-1)
www/src/js/templates/storelist-item.hbs (+11/-0)
www/src/js/views/home.js (+10/-4)
www/src/js/views/snaplist.js (+61/-10)
www/src/js/views/store.js (+12/-3)
www/src/js/views/storelist-item.js (+10/-0)
www/src/js/views/storelist.js (+7/-0)
To merge this branch: bzr merge lp:~stephen-stewart/snapweb/remote-and-local-collections-with-sorting-and-filtering
Reviewer Review Type Date Requested Status
Sergio Schvezov 2015-05-27 Approve on 2015-05-29
Review via email: mp+260305@code.launchpad.net

This proposal supersedes a proposal from 2015-05-27.

Commit Message

* add sorting
* allow user to change list style
* split out collections

Description of the Change

* add sorting
* allow user to change list style
* split out collections

To post a comment you must log in.
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'www/src/css/button.css'
2--- www/src/css/button.css 1970-01-01 00:00:00 +0000
3+++ www/src/css/button.css 2015-05-27 15:47:41 +0000
4@@ -0,0 +1,50 @@
5+/** @define b-button; weak */
6+
7+.b-button__group {
8+ display:flex;
9+}
10+
11+.b-button__group + .b-button__group {
12+ margin-left:8px;
13+}
14+
15+.b-button__group > * {
16+ padding:3px 10px;
17+}
18+
19+.b-button__group .b-button {
20+ border:1px solid #ccc;
21+ border-radius:3px;
22+ background-color:#efefef;
23+ color:#666;
24+ user-select: none;
25+ cursor: pointer;
26+}
27+
28+.b-button__group .b-button_active {
29+ background-color:#fff;
30+}
31+
32+.b-button__group .b-button:hover {
33+ background-color:#fff;
34+}
35+
36+.b-button__group .b-button:nth-of-type(1) {
37+ border-right:none;
38+ border-top-right-radius:0;
39+ border-bottom-right-radius:0;
40+}
41+
42+.b-button__group .b-button:nth-last-of-type(1) {
43+ border-top-left-radius:0;
44+ border-bottom-left-radius:0;
45+}
46+
47+.b-button__group .b-button:not(:nth-of-type(1)):not(:nth-last-of-type(1)) {
48+ border-right:none;
49+ border-radius:0;
50+}
51+
52+.b-button__group .b-button:nth-of-type(1):nth-last-of-type(1) {
53+ border-radius:3px;
54+}
55
56=== modified file 'www/src/css/headline.css'
57--- www/src/css/headline.css 2015-05-27 15:47:41 +0000
58+++ www/src/css/headline.css 2015-05-27 15:47:41 +0000
59@@ -3,7 +3,13 @@
60 .b-headline {
61 }
62
63+.b-headline .b-layout__container {
64+ display:flex;
65+ align-items: baseline;
66+}
67+
68 .b-headline__h1 {
69+ flex:1;
70 font-size:18px;
71 font-weight:400;
72 margin:20px 15px 5px 15px;
73
74=== modified file 'www/src/css/snaplist.css'
75--- www/src/css/snaplist.css 2015-05-27 15:47:41 +0000
76+++ www/src/css/snaplist.css 2015-05-27 15:47:41 +0000
77@@ -7,6 +7,12 @@
78 cursor: pointer;
79 }
80
81+.b-snaplist__actions {
82+ display:flex;
83+ font-size: 11px;
84+ justify-content: flex-end;
85+}
86+
87 /** grid style **/
88
89 .b-snaplist_grid {
90@@ -54,7 +60,10 @@
91 font-size:10px;
92 }
93
94-.b-snaplist_grid .b-snaplist__size ~ * {
95+.b-snaplist_grid .b-snaplist__version,
96+.b-snaplist_grid .b-snaplist__type,
97+.b-snaplist_grid .b-snaplist__origin,
98+.b-snaplist_grid .b-snaplist__actions {
99 display:none;
100 }
101
102@@ -79,7 +88,7 @@
103 /** row style **/
104
105 .b-snaplist_row {
106- margin:3em;
107+ margin:1em 0;
108 }
109
110 .b-snaplist_row .b-snaplist__item {
111
112=== modified file 'www/src/js/collections/snaplist.js'
113--- www/src/js/collections/snaplist.js 2015-04-24 11:15:41 +0000
114+++ www/src/js/collections/snaplist.js 2015-05-27 15:47:41 +0000
115@@ -7,5 +7,8 @@
116
117 module.exports = Backbone.Collection.extend({
118 url: CONF.PACKAGES,
119- model: Snap
120+ model: Snap,
121+ comparator: function(model) {
122+ return model.get('name');
123+ }
124 });
125
126=== modified file 'www/src/js/controllers/store.js'
127--- www/src/js/controllers/store.js 2015-04-24 11:15:41 +0000
128+++ www/src/js/controllers/store.js 2015-05-27 15:47:41 +0000
129@@ -2,14 +2,14 @@
130 var Marionette = require('backbone.marionette');
131 var Radio = require('backbone.radio');
132 var StoreLayoutView = require('../views/store.js');
133-var Bask = require('../collections/snaplist.js');
134+var Snaplist = require('../collections/snaplist.js');
135
136 module.exports = {
137 index: function() {
138 var chan = Radio.channel('root');
139- var storeBask = new Bask();
140+ var storeSnaplist = new Snaplist();
141
142- storeBask.fetch({
143+ storeSnaplist.fetch({
144 success: function(snaplist) {
145 var view = new StoreLayoutView({
146 collection: snaplist
147
148=== modified file 'www/src/js/templates/home.hbs'
149--- www/src/js/templates/home.hbs 2015-05-27 15:47:41 +0000
150+++ www/src/js/templates/home.hbs 2015-05-27 15:47:41 +0000
151@@ -1,6 +1,1 @@
152-<div class="b-headline">
153- <div class="b-layout__container">
154- <h1 class="b-headline__h1">Installed snaps</h1>
155- </div>
156-</div>
157 <div class="region-installed"></div>
158
159=== added file 'www/src/js/templates/snaplist.hbs'
160--- www/src/js/templates/snaplist.hbs 1970-01-01 00:00:00 +0000
161+++ www/src/js/templates/snaplist.hbs 2015-05-27 15:47:41 +0000
162@@ -0,0 +1,23 @@
163+{{#if title}}
164+<div class="b-headline">
165+ <div class="b-layout__container">
166+ <h1 class="b-headline__h1">{{ title }}</h1>
167+ <div class="b-snaplist__actions">
168+ {{#if canSort}}
169+ <div class="b-button__group">
170+ <div id="sortAlpha" class="b-button b-button_small{{#if isAlpha}} b-button_active{{/if}}">A-Z</div>
171+ <div id="sortBytes" class="b-button b-button_small{{#unless isAlpha}} b-button_active{{/unless}}">kB</div>
172+ </div>
173+ {{/if}}
174+ {{#if canStyle}}
175+ <div class="b-button__group">
176+ <div id="styleGrid" class="b-button b-button_small{{#if isGrid}} b-button_active{{/if}}">Grid</div>
177+ <div id="styleRow" class="b-button b-button_small{{#unless isGrid}} b-button_active{{/unless}}">Row</div>
178+ </div>
179+ {{/if}}
180+ </div>
181+ </div>
182+</div>
183+{{/if}}
184+<div class="b-snaplist b-snaplist_{{#if isGrid}}grid{{else}}row{{/if}}">
185+</div>
186
187=== modified file 'www/src/js/templates/store.hbs'
188--- www/src/js/templates/store.hbs 2015-05-27 15:47:41 +0000
189+++ www/src/js/templates/store.hbs 2015-05-27 15:47:41 +0000
190@@ -1,1 +1,1 @@
191-<div class="region-product"></div>
192+<div class="region-snaplist"></div>
193
194=== added file 'www/src/js/templates/storelist-item.hbs'
195--- www/src/js/templates/storelist-item.hbs 1970-01-01 00:00:00 +0000
196+++ www/src/js/templates/storelist-item.hbs 2015-05-27 15:47:41 +0000
197@@ -0,0 +1,11 @@
198+<div class="b-icon" data-type="{{type}}">
199+ <img src="{{ icon }}" width="90" height="90">
200+</div>
201+<div class="b-snaplist__name">{{ name }}</div>
202+{{!-- only name is shown in grid view, everything after is hidden --}}
203+<div class="b-snaplist__version">{{ version }}</div>
204+<div class="b-snaplist__type">{{ type }}</div>
205+<div class="b-snaplist__origin">{{ origin }}</div>
206+<div class="b-snaplist__actions">
207+ {{> installer}}
208+</div>
209
210=== modified file 'www/src/js/views/home.js'
211--- www/src/js/views/home.js 2015-05-27 15:47:41 +0000
212+++ www/src/js/views/home.js 2015-05-27 15:47:41 +0000
213@@ -1,7 +1,7 @@
214 // home view
215 var Backbone = require('backbone');
216 var Marionette = require('backbone.marionette');
217-var BaskView = require('./snaplist.js');
218+var SnapListView = require('./snaplist.js');
219 var template = require('../templates/home.hbs');
220
221 module.exports = Backbone.Marionette.LayoutView.extend({
222@@ -14,9 +14,15 @@
223
224 onBeforeShow: function() {
225 // TODO if collection empty use emptyView
226- this.showChildView('installedRegion', new BaskView({
227- collection: this.collection,
228- style: 'grid'
229+ this.showChildView('installedRegion', new SnapListView({
230+ model: new Backbone.Model({
231+ title: 'Installed snaps',
232+ isGrid: true,
233+ isAlpha: true,
234+ canSort: true,
235+ canStyle: true
236+ }),
237+ collection: this.collection
238 }));
239 },
240
241
242=== modified file 'www/src/js/views/snaplist.js'
243--- www/src/js/views/snaplist.js 2015-05-08 20:03:48 +0000
244+++ www/src/js/views/snaplist.js 2015-05-27 15:47:41 +0000
245@@ -1,21 +1,72 @@
246 // snaplist view
247 var _ = require('lodash');
248+var $ = require('jquery');
249 var Backbone = require('backbone');
250+Backbone.$ = $;
251 var Marionette = require('backbone.marionette');
252 var SnaplistItemView = require('../views/snaplist-item.js');
253 var EmptySnaplistView = require('./empty-snaplist.js');
254+var template = require('../templates/snaplist.hbs');
255 var CONF = require('../config.js');
256
257-module.exports = Marionette.CollectionView.extend({
258-
259- className: function() {
260- var style = this.options.style || 'row';
261-
262- if (style === 'row') {
263- return 'b-snaplist b-snaplist_row';
264- } else if (style === 'grid') {
265- return 'b-snaplist b-snaplist_grid';
266- }
267+module.exports = Marionette.CompositeView.extend({
268+
269+ childViewContainer: '.b-snaplist',
270+
271+ template : function(model) {
272+ return template(model);
273+ },
274+
275+ ui: {
276+ 'sortAlpha': '#sortAlpha',
277+ 'sortBytes': '#sortBytes',
278+ 'styleRow': '#styleRow',
279+ 'styleGrid': '#styleGrid'
280+ },
281+
282+ events: {
283+ 'click @ui.sortBytes': 'sortBytes',
284+ 'click @ui.sortAlpha': 'sortAlpha',
285+ 'click @ui.styleRow': 'styleRow',
286+ 'click @ui.styleGrid': 'styleGrid'
287+ },
288+
289+ sortAlpha: function() {
290+ this.model.set('isAlpha', true);
291+ this.viewComparator = function(model) {
292+ return model.get('name');
293+ };
294+ this.render();
295+ },
296+
297+ sortBytes: function() {
298+ this.model.set('isAlpha', false);
299+ this.viewComparator = function(model) {
300+ return -model.get('installed_size');
301+ };
302+ this.render();
303+ },
304+
305+ styleGrid: function() {
306+ this.model.set('isGrid', true);
307+
308+ this.$('.b-snaplist')
309+ .removeClass('b-snaplist_row')
310+ .addClass('b-snaplist_grid');
311+
312+ this.$('#styleRow').removeClass('b-button_active');
313+ this.$('#styleGrid').addClass('b-button_active');
314+ },
315+
316+ styleRow: function() {
317+ this.model.set('isGrid', false);
318+
319+ this.$('.b-snaplist')
320+ .removeClass('b-snaplist_grid')
321+ .addClass('b-snaplist_row');
322+
323+ this.$('#styleGrid').removeClass('b-button_active');
324+ this.$('#styleRow').addClass('b-button_active');
325 },
326
327 childView: SnaplistItemView,
328
329=== modified file 'www/src/js/views/store.js'
330--- www/src/js/views/store.js 2015-04-24 20:47:44 +0000
331+++ www/src/js/views/store.js 2015-05-27 15:47:41 +0000
332@@ -1,22 +1,31 @@
333 // store layout view
334 var Backbone = require('backbone');
335 var Marionette = require('backbone.marionette');
336-var BaskView = require('./snaplist.js');
337+var StorelistView = require('./storelist.js');
338 var template = require('../templates/store.hbs');
339
340 module.exports = Backbone.Marionette.LayoutView.extend({
341
342+ className: 'b-layout__container',
343+
344 template : function() {
345 return template();
346 },
347
348 onBeforeShow: function() {
349- this.showChildView('productRegion', new BaskView({
350+ this.showChildView('store', new StorelistView({
351+ model: new Backbone.Model({
352+ title: 'Store snaps',
353+ isGrid: false,
354+ isAlpha: true,
355+ canSort: false,
356+ canStyle: true
357+ }),
358 collection: this.collection
359 }));
360 },
361
362 regions: {
363- productRegion: '.region-product'
364+ store: '.region-snaplist'
365 }
366 });
367
368=== added file 'www/src/js/views/storelist-item.js'
369--- www/src/js/views/storelist-item.js 1970-01-01 00:00:00 +0000
370+++ www/src/js/views/storelist-item.js 2015-05-27 15:47:41 +0000
371@@ -0,0 +1,10 @@
372+// store list item view
373+
374+var SnapListItemView = require('./snaplist-item.js');
375+var template = require('../templates/storelist-item.hbs');
376+
377+module.exports = SnapListItemView.extend({
378+ template: function(model) {
379+ return template(model);
380+ }
381+});
382
383=== added file 'www/src/js/views/storelist.js'
384--- www/src/js/views/storelist.js 1970-01-01 00:00:00 +0000
385+++ www/src/js/views/storelist.js 2015-05-27 15:47:41 +0000
386@@ -0,0 +1,7 @@
387+// storelist view
388+var Snaplist = require('./snaplist.js');
389+var StorelistItemView = require('./storelist-item.js');
390+
391+module.exports = Snaplist.extend({
392+ childView: StorelistItemView
393+});

Subscribers

People subscribed via source and target branches