Skip to content

Commit a42e460

Browse files
authored
Merge pull request #270 from pattisdr/feature/provider-carousel
Feature/Preprint Provider Carousel [EOSF-499]
2 parents 6e13c97 + 543ec91 commit a42e460

File tree

7 files changed

+141
-21
lines changed

7 files changed

+141
-21
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import Ember from 'ember';
2+
import Analytics from '../mixins/analytics';
3+
4+
/**
5+
* @module ember-preprints
6+
* @submodule components
7+
*/
8+
9+
/**
10+
* Displays active preprint providers in a horizontal carousel with five providers per slide. Does not auto-advance.
11+
* Handles display on two pages: index (lightLogo=true) and discover (lightLogo=false). If using elsewhere, need to add more customization
12+
* around how provider logos and links are built.
13+
*
14+
* Sample usage:
15+
* ```handlebars
16+
* {{provider-carousel
17+
* providers=providers
18+
* lightLogo=true
19+
*}}
20+
* ```
21+
* @class provider-carousel
22+
*/
23+
export default Ember.Component.extend(Analytics, {
24+
_resizeListener: null,
25+
providers: Ember.A(), // Pass in preprint providers
26+
itemsPerSlide: 5, // Default
27+
lightLogo: true, // Light logos by default, for Index page.
28+
numProviders: Ember.computed('providers', function() {
29+
return this.get('providers').length;
30+
}),
31+
numSlides: Ember.computed('numProviders', 'itemsPerSlide', function() {
32+
return Math.ceil(this.get('numProviders') / this.get('itemsPerSlide'));
33+
}),
34+
slides: Ember.computed('numSlides', 'providers', 'itemsPerSlide', function() {
35+
const numSlides = this.get('numSlides');
36+
const itemsPerSlide = this.get('itemsPerSlide');
37+
return new Array(numSlides).fill().map((_, i) => this.get('providers').slice(i * itemsPerSlide, i * itemsPerSlide + itemsPerSlide));
38+
}),
39+
setSlideItems: function() {
40+
// On xs screens, show one provider per slide. Otherwise, five.
41+
if (window.innerWidth < 768) {
42+
this.set('itemsPerSlide', 1);
43+
} else {
44+
this.set('itemsPerSlide', 5);
45+
}
46+
},
47+
didInsertElement: function () {
48+
// On xs screen, display one provider per slide
49+
Ember.$('.carousel').carousel();
50+
},
51+
init: function() {
52+
// Set resize listener so number of providers per slide can be changed
53+
this._super(...arguments);
54+
this.setSlideItems();
55+
this._resizeListener = Ember.run.bind(this, this.setSlideItems);
56+
Ember.$(window).on('resize', this._resizeListener);
57+
},
58+
willDestroy: function() {
59+
// Unbinds _resizeListener
60+
if (this._resizeListener) {
61+
Ember.$(window).off('resize', this._resizeListener);
62+
}
63+
}
64+
});
65+

app/styles/app.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ ul.comma-list {
102102
/* INDEX page */
103103
/* Global to index */
104104

105+
.carousel-control.left, .carousel-control.right {
106+
background-image: none // Overrides bootstrap defaults for carousel background gradient
107+
}
108+
.icon-next.dark-control {
109+
color: black;
110+
}
111+
112+
.icon-prev.dark-control {
113+
color: black;
114+
}
105115

106116
/* Main header with search bar */
107117
.preprint-header{
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{{!Provider Carousel}}
2+
<div id="providerCarousel" class="carousel slide" data-ride="carousel" data-interval="false">
3+
<div class="carousel-inner" role="listbox">
4+
{{#each slides as |slide index|}}
5+
<div class={{if (not index) "item active" "item"}}>
6+
{{#each slide as |provider index|}}
7+
<div class={{if (not index) "col-sm-2 col-sm-offset-1" "col-sm-2"}}>
8+
{{#if lightLogo}}
9+
<a href="/preprints/{{provider.id}}"
10+
title={{provider.name}}
11+
onbeforeclick={{action 'click' 'link' (concat 'Index - Provider - ' provider.name)}}
12+
>
13+
<div class="provider-logo provider-{{provider.id}}"></div>
14+
</a>
15+
{{else}}
16+
<a href="/preprints/{{provider.id}}/discover"
17+
title={{provider.name}}
18+
onclick={{action 'click' 'link' (concat 'Preprints - Discover - Index ' provider.name)}}
19+
>
20+
<div class="discover-provider-logo provider-{{provider.id}}-dark"></div>
21+
</a>
22+
{{/if}}
23+
</div>
24+
{{/each}}
25+
</div>
26+
{{/each}}
27+
</div>
28+
<a class="left carousel-control" href="#providerCarousel" role="button" data-slide="prev">
29+
<span class={{concat "icon-prev fa fa-angle-left" (if (not lightLogo) " dark-control")}}></span>
30+
<span class="sr-only">Previous</span>
31+
</a>
32+
<a class="right carousel-control" href="#providerCarousel" role="button" data-slide="next">
33+
<span class={{concat "icon-next fa fa-angle-right" (if (not lightLogo) " dark-control")}}></span>
34+
<span class="sr-only">Next</span>
35+
</a>
36+
</div>
37+
38+

app/templates/discover.hbs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,15 @@
2626
</div>
2727
</div>
2828
<div class="row m-v-md">
29-
<div class="col-xs-8 col-xs-offset-2" style="text-align: center;">
29+
<div class="col-xs-10 col-xs-offset-1" style="text-align: center;">
3030
{{#if (not theme.isProvider)}}
3131
<h3>{{t "discover.search.partner"}}</h3>
3232
<div class="row">
33-
{{#each model as |provider|}}
34-
<a href="/preprints/{{provider.id}}/discover"
35-
title={{provider.name}}
36-
onclick={{action 'click' 'link' (concat 'Preprints - Discover - Index ' provider.name)}}
37-
>
38-
<div class="discover-provider-logo col-xs-4 provider-{{provider.id}}-dark"></div>
39-
</a>
40-
{{/each}}
33+
{{!CAROUSEL WITH PREPRINT PROVIDERS}}
34+
{{provider-carousel
35+
providers=model
36+
lightLogo=false
37+
}}
4138
</div>
4239
{{/if}}
4340
</div>

app/templates/index.hbs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,10 @@
6666
</div>
6767
</div>
6868
<div class="row p-v-md">{{!BRANDED ROW}}
69-
{{#each model.brandedProviders as |provider|}}
70-
<div class="col-sm-4">
71-
<a href="/preprints/{{provider.id}}"
72-
title={{provider.name}}
73-
onbeforeclick={{action 'click' 'link' (concat 'Index - Provider - ' provider.name)}}
74-
>
75-
<div class="provider-logo provider-{{provider.id}}"></div>
76-
</a>
77-
</div>
78-
{{/each}}
69+
{{!CAROUSEL WITH PREPRINT PROVIDERS}}
70+
{{provider-carousel
71+
providers=model.brandedProviders
72+
}}
7973
</div>
8074
<div class="row p-v-md">
8175
<div class="col-md-12 text-center">
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { moduleForComponent, test } from 'ember-qunit';
2+
import hbs from 'htmlbars-inline-precompile';
3+
4+
moduleForComponent('provider-carousel', 'Integration | Component | provider carousel', {
5+
integration: true
6+
});
7+
8+
test('it renders', function(assert) {
9+
10+
// Set any properties with this.set('myProperty', 'value');
11+
// Handle any actions with this.on('myAction', function(val) { ... });
12+
13+
this.render(hbs`{{provider-carousel}}`);
14+
15+
assert.equal(this.$().context.innerText, 'PreviousNext');
16+
});

yarn.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2135,9 +2135,9 @@ ember-new-computed@^1.0.2:
21352135
dependencies:
21362136
ember-cli-babel "^5.1.5"
21372137

2138-
"ember-osf@git+https://github.com/pattisdr/ember-osf.git#c4e87ff18b3f9125b87fbd3ce05e2c41eebdc3b6":
2138+
"ember-osf@git+https://github.com/CenterForOpenScience/ember-osf.git#97a4f00dd86f360b561f3ee63b77297b3e6e0f1e":
21392139
version "0.1.0"
2140-
resolved "git+https://github.com/pattisdr/ember-osf.git#c4e87ff18b3f9125b87fbd3ce05e2c41eebdc3b6"
2140+
resolved "git+https://github.com/CenterForOpenScience/ember-osf.git#97a4f00dd86f360b561f3ee63b77297b3e6e0f1e"
21412141
dependencies:
21422142
broccoli-funnel "^1.0.1"
21432143
broccoli-merge-trees "^1.1.1"

0 commit comments

Comments
 (0)