Skip to content

Commit 5e97fab

Browse files
committed
Merge branch 'release/0.109.0'
2 parents 42f304c + d06335e commit 5e97fab

File tree

119 files changed

+2196
-1943
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+2196
-1943
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "public/assets/osf-assets"]
2+
path = public/assets/osf-assets
3+
url = https://github.com/CenterForOpenScience/osf-assets.git

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
language: node_js
22

3-
sudo: false
3+
sudo: required
44
dist: trusty
5+
addons:
6+
chrome: stable
57

68
env:
79
global:

Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,31 @@ ENV GIT_COMMIT ${GIT_COMMIT}
5353

5454
ARG APP_ENV=production
5555
ENV APP_ENV ${APP_ENV}
56+
5657
ARG BACKEND=local
5758
ENV BACKEND ${BACKEND}
59+
60+
ARG OSF_URL=
61+
ENV OSF_URL ${OSF_URL}
62+
ARG OSF_API_URL=
63+
ENV OSF_API_URL ${OSF_API_URL}
64+
ARG OSF_RENDER_URL=
65+
ENV OSF_RENDER_URL ${OSF_RENDER_URL}
66+
ARG OSF_FILE_URL=
67+
ENV OSF_FILE_URL ${OSF_FILE_URL}
68+
ARG OSF_HELP_URL=
69+
ENV OSF_HELP_URL ${OSF_HELP_URL}
70+
ARG OSF_COOKIE_LOGIN_URL=
71+
ENV OSF_COOKIE_LOGIN_URL ${OSF_COOKIE_LOGIN_URL}
72+
ARG OSF_OAUTH_URL=
73+
ENV OSF_OAUTH_URL ${OSF_OAUTH_URL}
74+
ARG SHARE_BASE_URL=
75+
ENV SHARE_BASE_URL ${SHARE_BASE_URL}
76+
ARG SHARE_API_URL=
77+
ENV SHARE_API_URL ${SHARE_API_URL}
78+
ARG SHARE_SEARCH_URL=
79+
ENV SHARE_SEARCH_URL ${SHARE_SEARCH_URL}
80+
5881
RUN ./node_modules/ember-cli/bin/ember build --env ${APP_ENV}
5982

6083
CMD ["yarn", "test"]

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,23 @@ You will need the following things properly installed on your computer.
2323
## Installation
2424

2525
* `git clone` this repository
26+
* To pull in local preprint provider assets as well, use `git clone --recursive` instead (assuming you are using git >= 1.6.5).
2627
* `yarn install --pure-lockfile`
2728
* `bower install`
2829

30+
## Preprint Provider Assets
31+
32+
If you will be using local preprint provider assets (rather than the CDN):
33+
34+
1. If you did not clone the repository using --recursive, run: `git submodule update --init --recursive`
35+
2. Set the PROVIDER_ASSETS_URL environment variable to 'local'
36+
37+
### Updating Assets
38+
39+
* To refresh your local assets, run: `git submodule update`
40+
* To update the assets submodule to the latest assets, run: `npm run update-assets`
41+
* To update to the latest assets and create a hotfix, run: `npm run updates-assets-hotfix`
42+
2943
## Running / Development
3044
For local development, this is designed to run alongside (and from within) the flask application for osf.io.
3145

@@ -36,8 +50,9 @@ to your `website/settings/local.py` file. Uncomment `'/preprints/': 'http://loca
3650
4. Visit your app at http://localhost:5000/preprints/
3751

3852
### Provider Domains
39-
1. Run `sudo ./scripts/add-domains.js`. This will add the domains to your `/etc/hosts`.
40-
2. Visit your app at one of the provider domains with `https://local.<domain>:4200` (e.g. `http://local.socarxiv.org:4200`)
53+
1. Start the API server
54+
1. Run `sudo ./scripts/add-domains.js`. This will add the domains to your `/etc/hosts`. Use `--dry` for a dry run.
55+
1. Visit your app at one of the provider domains with `https://local.<domain>:4200` (e.g. `http://local.socarxiv.org:4200`)
4156

4257
If you encounter problems, make sure that your version of ember-osf is up to date. If login fails, try logging in from
4358
any other OSF page, then returning to the preprints app.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import Ember from 'ember';
2+
import Analytics from 'ember-osf/mixins/analytics';
3+
/**
4+
* @module ember-preprints
5+
* @submodule components
6+
*/
7+
8+
/**
9+
* Displays additional SHARE sources for preprints index page
10+
*
11+
* Sample usage:
12+
* ```handlebars
13+
* {{additional-provider-list
14+
* additionalProviders=additionalProviders
15+
* }}
16+
* ```
17+
* @class additional-provider-list
18+
*/
19+
export default Ember.Component.extend(Analytics, {
20+
theme: Ember.inject.service(),
21+
sortedList: Ember.computed('additionalProviders', function() {
22+
if (!this.get('additionalProviders')) {
23+
return;
24+
}
25+
const sortedList = this.get('additionalProviders').sort();
26+
const pairedList = [];
27+
for (let i = 0; i < sortedList.get('length'); i += 2) {
28+
let pair = [];
29+
pair.pushObject(sortedList.objectAt(i));
30+
if (sortedList.objectAt(i + 1)) {
31+
pair.pushObject(sortedList.objectAt(i + 1));
32+
}
33+
pairedList.pushObject(pair);
34+
}
35+
return pairedList;
36+
})
37+
});

app/components/provider-carousel.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import Ember from 'ember';
22
import Analytics from 'ember-osf/mixins/analytics';
3-
43
/**
54
* @module ember-preprints
65
* @submodule components
@@ -25,16 +24,25 @@ export default Ember.Component.extend(Analytics, {
2524
providers: Ember.A(), // Pass in preprint providers
2625
itemsPerSlide: 5, // Default
2726
lightLogo: true, // Light logos by default, for Index page.
28-
numProviders: Ember.computed('providers', function() {
29-
return this.get('providers').length;
27+
editedProviders: Ember.computed('providers', function() {
28+
let newProviders = Ember.A()
29+
for (const provider of this.get('providers')) {
30+
if (provider && provider.get('id')!== 'asu') {
31+
newProviders.pushObject(provider)
32+
}
33+
}
34+
return newProviders;
35+
}),
36+
numProviders: Ember.computed('editedProviders', function() {
37+
return this.get('editedProviders').length;
3038
}),
3139
numSlides: Ember.computed('numProviders', 'itemsPerSlide', function() {
3240
return Math.ceil(this.get('numProviders') / this.get('itemsPerSlide'));
3341
}),
34-
slides: Ember.computed('numSlides', 'providers', 'itemsPerSlide', function() {
42+
slides: Ember.computed('numSlides', 'editedProviders', 'itemsPerSlide', function() {
3543
const numSlides = this.get('numSlides');
3644
const itemsPerSlide = this.get('itemsPerSlide');
37-
return new Array(numSlides).fill().map((_, i) => this.get('providers').slice(i * itemsPerSlide, i * itemsPerSlide + itemsPerSlide));
45+
return new Array(numSlides).fill().map((_, i) => this.get('editedProviders').slice(i * itemsPerSlide, i * itemsPerSlide + itemsPerSlide));
3846
}),
3947
columnOffset: Ember.computed('numProviders', 'itemsPerSlide', function() {
4048
// If only one slide of providers, center the provider logos by adding a column offset.
@@ -86,4 +94,3 @@ export default Ember.Component.extend(Analytics, {
8694
}
8795
}
8896
});
89-

app/components/search-preprints.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import Ember from 'ember';
1717
*/
1818
export default Ember.Component.extend({
1919
metrics: Ember.inject.service(),
20+
theme: Ember.inject.service(),
2021
actions: {
2122
search() {
2223
let query = Ember.$.trim(this.$('#searchBox').val());

app/components/supplementary-file-browser.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,28 @@ export default Ember.Component.extend(Analytics, {
5959
this.set('indexes', this.get('files').map(each => each.id));
6060
});
6161
}.observes('preprint'),
62+
63+
selectedFileChanged: Ember.observer('selectedFile', function() {
64+
const eventData = {
65+
file_views: {
66+
preprint: {
67+
type: 'preprint',
68+
id: this.get('preprint.id')
69+
},
70+
file: {
71+
id: this.get('selectedFile.id'),
72+
primaryFile: this.get('preprint.primaryFile.id') === this.get('selectedFile.id'),
73+
version: this.get('selectedFile.currentVersion')
74+
}
75+
}
76+
};
77+
Ember.get(this, 'metrics').invoke('trackSpecificCollection', 'Keen', {
78+
collection: 'preprint-file-views',
79+
eventData: eventData,
80+
node: this.get('node'),
81+
});
82+
}),
83+
6284
_chosenFile: Ember.observer('chosenFile', 'indexes', function() {
6385
let fid = this.get('chosenFile');
6486
let index = this.get('indexes').indexOf(fid);

app/controllers/content/index.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ function queryStringify(queryParams) {
5353
export default Ember.Controller.extend(Analytics, {
5454
theme: Ember.inject.service(),
5555
fullScreenMFR: false,
56+
currentUser: Ember.inject.service(),
57+
expandedAuthors: true,
5658
showLicenseText: false,
5759
expandedAbstract: navigator.userAgent.includes('Prerender'),
5860
queryParams: {
@@ -207,6 +209,57 @@ export default Ember.Controller.extend(Analytics, {
207209

208210
window.open(href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,width=600,height=400');
209211
return false;
212+
},
213+
// Sends Event to GA/Keen as normal. Sends second event to Keen under "non-contributor-preprint-downloads" collection
214+
// to track non contributor preprint downloads specifically.
215+
dualTrackNonContributors(category, label, url, primary) {
216+
this.send('click', category, label, url); // Sends event to both Google Analytics and Keen.
217+
const authors = this.get('authors');
218+
let userIsContrib = false;
219+
220+
const eventData = {
221+
download_info: {
222+
preprint: {
223+
type: 'preprint',
224+
id: this.get('model.id')
225+
},
226+
file: {
227+
id: primary ? this.get('model.primaryFile.id') : this.get('activeFile.id'),
228+
primaryFile: primary,
229+
version: primary ? this.get('model.primaryFile.currentVersion') : this.get('activeFile.currentVersion')
230+
}
231+
},
232+
interaction: {
233+
category: category,
234+
action: 'click',
235+
label: `${label} as Non-Contributor`,
236+
url: url
237+
}
238+
};
239+
240+
const keenPayload = {
241+
collection: 'non-contributor-preprint-downloads',
242+
eventData: eventData,
243+
node: this.get('node'),
244+
};
245+
246+
this.get('currentUser').load()
247+
.then(user => {
248+
if (user) {
249+
const userId = user.id;
250+
authors.forEach((author) => {
251+
if (author.get('userId') === userId) {
252+
userIsContrib = true;
253+
}
254+
});
255+
}
256+
if (!userIsContrib) {
257+
Ember.get(this, 'metrics').invoke('trackSpecificCollection', 'Keen', keenPayload); // Sends event to Keen if logged-in user is not a contributor
258+
}
259+
})
260+
.catch(() => {
261+
Ember.get(this, 'metrics').invoke('trackSpecificCollection', 'Keen', keenPayload); // Sends event to Keen for non-authenticated user
262+
});
210263
}
211264
},
212265
});

app/controllers/discover.js

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,34 @@ export default Ember.Controller.extend(Analytics, {
1818
i18n: Ember.inject.service(),
1919
theme: Ember.inject.service(),
2020
activeFilters: { providers: [], subjects: [] },
21+
additionalProviders: Ember.computed('themeProvider', function() { // Do additionalProviders exist?
22+
// for now, using this property to alter many pieces of the landing/discover page
23+
return (this.get('themeProvider.additionalProviders') || []).length > 1;
24+
}),
2125
consumingService: 'preprints', // Consuming service - preprints here
2226
detailRoute: 'content', // Name of detail route for this application
23-
discoverHeader: Ember.computed('i18n', function() { // Header for preprints discover page
24-
return this.get('i18n').t('discover.search.heading');
27+
discoverHeader: Ember.computed('i18n', 'additionalProviders', function() { // Header for preprints discover page
28+
// If additionalProviders, use more generic Repository Search page title
29+
return this.get('additionalProviders') ? this.get('i18n').t('discover.search.heading_repository_search') : this.get('i18n').t('discover.search.heading');
30+
}),
31+
end: '', // End query param. Must be passed to component, so can be reflected in the URL
32+
externalProviders: Ember.computed('model', function() {
33+
return this.get('model').filter(item => item.id !== 'osf');
2534
}),
26-
facets: Ember.computed('i18n.locale', function() { //List of facets available for preprints
27-
return [
28-
{ key: 'sources', title: `${this.get('i18n').t('discover.main.providers')}`, component: 'search-facet-provider' },
29-
{ key: 'subjects', title: `${this.get('i18n').t('discover.main.subject')}`, component: 'search-facet-taxonomy' }]
35+
facets: Ember.computed('i18n.locale', 'additionalProviders', function() { // List of facets available for preprints
36+
if (this.get('additionalProviders')) { // if additionalProviders exist, use subset of SHARE facets
37+
return [
38+
{ key: 'sources', title: this.get('i18n').t('discover.main.source'), component: 'search-facet-source'},
39+
{ key: 'date', title: this.get('i18n').t('discover.main.date'), component: 'search-facet-daterange'},
40+
{ key: 'type', title: this.get('i18n').t('discover.main.type'), component: 'search-facet-worktype'},
41+
{ key: 'tags', title: this.get('i18n').t('discover.main.tag'), component: 'search-facet-typeahead'},
42+
];
43+
} else { // Regular preprints and branded preprints get provider and taxonomy facets
44+
return [
45+
{ key: 'sources', title: `${this.get('i18n').t('discover.main.providers')}`, component: 'search-facet-provider' },
46+
{ key: 'subjects', title: `${this.get('i18n').t('discover.main.subject')}`, component: 'search-facet-taxonomy' }
47+
]
48+
}
3049
}),
3150
filterMap: { // Map active filters to facet names expected by SHARE
3251
providers: 'sources',
@@ -38,15 +57,21 @@ export default Ember.Controller.extend(Analytics, {
3857
OSF: 'OSF Preprints',
3958
'Research Papers in Economics': 'RePEc'
4059
},
41-
lockedParams: {types: 'preprint'}, // Parameter names which cannot be changed
60+
lockedParams: Ember.computed('additionalProviders', function() { // Query parameters that cannot be changed.
61+
// if additionalProviders, open up search results to all types of results instead of just preprints.
62+
return this.get('additionalProviders') ? {} : {types: 'preprint'};
63+
}),
4264
page: 1, // Page query param. Must be passed to component, so can be reflected in URL
4365
provider: '', // Provider query param. Must be passed to component, so can be reflected in URL
4466
q: '', // q query param. Must be passed to component, so can be reflected in URL
45-
queryParams: ['page', 'q', 'subject', 'provider'], // Pass in the list of queryParams for this component
46-
searchPlaceholder: Ember.computed('i18n', function() { // Search bar placeholder
47-
return this.get('i18n').t('discover.search.placeholder');
67+
queryParams: ['page', 'q', 'sources', 'tags', 'type', 'start', 'end', 'subject', 'provider'], // Pass in the list of queryParams for this component
68+
searchPlaceholder: Ember.computed('i18n', 'additionalProviders', function() { // Search bar placeholder
69+
return this.get('additionalProviders') ? this.get('i18n').t('discover.search.repository_placeholder'): this.get('i18n').t('discover.search.placeholder');
70+
}),
71+
showActiveFilters: Ember.computed('additionalProviders', function() { // Whether Active Filters should be displayed.
72+
// additionalProviders are using SHARE facets which do not work with Active Filters at this time
73+
return !this.get('additionalProviders');
4874
}),
49-
showActiveFilters: true, // Whether Active Filters should be displayed.
5075
sortOptions: Ember.computed('i18n.locale', function() { // Sort options for preprints
5176
const i18n = this.get('i18n');
5277
return [{
@@ -60,7 +85,20 @@ export default Ember.Controller.extend(Analytics, {
6085
sortBy: '-date_updated'
6186
}];
6287
}),
63-
subject: '',// Subject query param. Must be passed to component, so can be reflected in URL,
88+
sources: '', // Sources query param. Must be passed to component, so can be reflected in the URL
89+
start: '', // Start query param. Must be passed to component, so can be reflected in the URL
90+
subject: '', // Subject query param. Must be passed to component, so can be reflected in URL
91+
tags: '', // Tags query param. Must be passed to component, so can be reflected in URL
92+
themeProvider: Ember.computed('model', function() { // Pulls the preprint provider from the already loaded model
93+
let themeProvider = null;
94+
this.get('model').forEach(provider => {
95+
if (provider.id === this.get('theme.id')) {
96+
themeProvider = provider;
97+
}
98+
});
99+
return themeProvider;
100+
}),
101+
type: '', //Type query param. Must be passed to component, so can be reflected in URL
64102
_clearFilters() {
65103
this.set('activeFilters', {
66104
providers: [],

0 commit comments

Comments
 (0)