Skip to content

Commit 76f745e

Browse files
committed
Merge branch 'release/0.5.1'
2 parents cbec298 + 225e067 commit 76f745e

File tree

45 files changed

+354
-134
lines changed

Some content is hidden

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

45 files changed

+354
-134
lines changed

.vscode/settings.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
2-
"typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false
3-
}
2+
"typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
3+
"files.exclude": {
4+
"**/.git": true,
5+
"**/.DS_Store": true,
6+
"tmp/**": true,
7+
},
8+
"search.exclude": {
9+
"**/node_modules": true,
10+
"**/bower_components": true,
11+
"tmp/**": true,
12+
},
13+
}

.watchmanconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"ignore_dirs": ["tmp", "dist"]
2+
"ignore_dirs": ["tmp", "dist", "node_modules"]
33
}

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [0.5.1] - 2018-07-10
8+
### Added
9+
- Missing analytics:
10+
- Institutions landing page (page and event tracking)
11+
- Dashboard filtering
12+
- User quick files page (more event tracking)
13+
- Quick files detail page (event tracking)
14+
15+
### Changed
16+
- Components:
17+
- `simple-paginator` - use > and < instead of font-awesome chevrons
18+
- Engines:
19+
- `analytics` - set page title to "OSF | [node title] Analytics"
20+
- DX:
21+
- Test assertions: Collapse all whitespace characters to a single space
22+
723
## [0.5.0] - 2018-06-29
824
### Added
925
- Routes:

README.md

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,83 @@
88
`develop` Build Status: [![Build Status](https://travis-ci.org/CenterForOpenScience/ember-osf-web.svg?branch=develop)](https://travis-ci.org/CenterForOpenScience/ember-osf-web)
99
[![Coverage Status](https://coveralls.io/repos/github/CenterForOpenScience/ember-osf-web/badge.svg?branch=develop)](https://coveralls.io/github/CenterForOpenScience/ember-osf-web?branch=develop)
1010

11-
This README outlines the details of collaborating on this Ember application.
12-
A short introduction of this app could easily go here.
11+
A front end for [osf.io](https://github.com/CenterForOpenScience/osf.io).
1312

1413
## Prerequisites
1514

1615
You will need the following things properly installed on your computer.
1716

17+
* [osf.io back end](https://github.com/CenterForOpenScience/osf.io)
1818
* [Git](https://git-scm.com/)
1919
* [Node.js](https://nodejs.org/) (with NPM)
2020
* [Ember CLI](https://ember-cli.com/)
21+
* [Watchman](https://facebook.github.io/watchman/)
2122

2223
## Installation
2324

24-
* `git clone <repository-url>` this repository
25+
* `git clone https://github.com/CenterForOpenScience/ember-osf-web.git`
2526
* `cd ember-osf-web`
2627
* `yarn --frozen-lockfile`
2728

2829
## Running / Development
2930

31+
### Mac OS File Descriptor Limits
32+
33+
Watchman [states](https://facebook.github.io/watchman/docs/install.html#mac-os-file-descriptor-limits) "*Only applicable on OS X 10.6 and earlier*". Though it's been observed this setting can remain incorrect on systems where the operation system was upgraded from a legacy version.
34+
35+
> Putting the following into a file named /etc/sysctl.conf on OS X will cause these values to persist across reboots:
36+
37+
```bash
38+
kern.maxfiles=10485760
39+
kern.maxfilesperproc=1048576
40+
```
41+
42+
### Development
43+
44+
Configure the application for local development, add the following to your `config/local.js`:
45+
```ts
46+
module.exports = {
47+
// an ally audit can use 100% of your browsers cpu, so use it wisely
48+
A11Y_AUDIT: false,
49+
// toggle on/off the engine applications you will be working on
50+
COLLECTIONS_ENABLED: false,
51+
// sourcemaps are useful if you need to step through typescript code in the browser
52+
SOURCEMAPS_ENABLED: true,
53+
};
54+
```
55+
3056
* `ember serve`
31-
* Visit your app at [http://localhost:4200](http://localhost:4200).
57+
* View the ember app (alone) at [localhost:4200](http://localhost:4200)
58+
59+
To integrate with the legacy front end at [localhost:5000](http://localhost:5000), you have two options:
60+
* Enable the waffle flags for each page in your [local OSF Admin](http://localhost:8001/admin/waffle/flag)
61+
* Add routes to your `osf.io/website/settings/local.py`:
62+
```py
63+
EXTERNAL_EMBER_APPS = {
64+
'ember_osf_web': {
65+
# ...
66+
'routes': [
67+
'handbook',
68+
'dashboard',
69+
# ...
70+
],
71+
},
72+
# ...
73+
```
74+
75+
### Developer Handbook
76+
77+
To enable the [developer handbook](https://centerforopenscience.github.io/ember-osf-web/handbook) locally,
78+
add the following to your `config/local.js`:
79+
```ts
80+
module.exports = {
81+
HANDBOOK_ENABLED: true,
82+
};
83+
```
84+
The handbook will be available at [http://localhost:4200/handbook](http://localhost:4200/handbook).
85+
86+
To enable (experimental) auto-generated docs in the handbook, you can also set
87+
`HANDBOOK_DOC_GENERATION_ENABLED: true` in your local config.
3288

3389
### Code Generators
3490

@@ -44,10 +100,6 @@ Make use of the many generators for code, try `ember help generate` for more det
44100
* `ember build` (development)
45101
* `ember build --environment production` (production)
46102

47-
### Deploying
48-
49-
Specify what it takes to deploy your app.
50-
51103
## Further Reading / Useful Links
52104

53105
* [ember.js](http://emberjs.com/)

app/app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ const App = Application.extend({
3636
'store',
3737
'analytics',
3838
'ready',
39+
'page-title-list',
40+
'head-data',
3941
],
4042
externalRoutes: {
4143
nodeForks: 'guid-node.forks',

app/dashboard/controller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ export default class Dashboard extends Controller {
4848
filterNodes = task(function *(this: Dashboard, filter: string) {
4949
yield timeout(500);
5050
this.setProperties({ filter });
51+
this.analytics.track('list', 'filter', 'Dashboard - Search projects');
5152
yield this.get('findNodes').perform();
5253
}).restartable();
5354

app/guid-file/controller.ts

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -64,59 +64,56 @@ export default class GuidFile extends Controller {
6464

6565
@computed('currentUser', 'user.id')
6666
get canEdit(this: GuidFile): boolean {
67-
const modelUserId = this.get('user').get('id');
67+
const modelUserId = this.user.id;
6868

69-
return !!modelUserId && modelUserId === this.get('currentUser').get('currentUserId');
69+
return !!modelUserId && modelUserId === this.currentUser.currentUserId;
7070
}
7171

7272
@computed('revision', 'file.currentVersion')
7373
get mfrVersion(this: GuidFile): number {
74-
return this.get('revision') || this.get('file').get('currentVersion');
74+
return this.revision || this.file.currentVersion;
7575
}
7676

7777
// TODO: get this from the model
7878
@computed('file.currentVersion')
7979
get fileVersions(this: GuidFile): Promise<any> {
8080
return (async () => {
81-
const { data } = await $.getJSON(`${this.get('downloadLink')}?revisions=&`);
81+
const { data } = await $.getJSON(`${this.downloadLink}?revisions=&`);
8282
return data;
8383
})();
8484
}
8585

8686
@computed('file.name')
8787
get isEditableFile(this: GuidFile): boolean {
88-
const filename = this.get('file').get('name');
88+
const filename = this.file.name;
8989
const mimeType = mime.lookup(filename);
9090
return !!mimeType && /^text\//.test(mimeType);
9191
}
9292

9393
@computed('file.currentVersion')
9494
get fileText(this: GuidFile) {
95-
const file: File = this.get('file');
96-
return !!file && file.getContents();
95+
return Boolean(this.file) && this.file.getContents();
9796
}
9897

9998
updateFilter = task(function *(this: GuidFile, filter: string) {
10099
yield timeout(250);
101100
this.setProperties({ filter });
102-
}).drop();
101+
this.analytics.track('list', 'filter', 'Quick Files - Filter file browser');
102+
}).restartable();
103103

104104
@computed('allFiles.[]', 'filter', 'sort')
105105
get files(this: GuidFile) {
106-
const filter: string = this.get('filter');
107-
const sort: string = this.get('sort');
106+
let results: File[] = this.allFiles;
108107

109-
let results: File[] = this.get('allFiles');
110-
111-
if (filter) {
112-
const filterLowerCase = filter.toLowerCase();
113-
results = results.filter(file => file.get('name').toLowerCase().includes(filterLowerCase));
108+
if (this.filter) {
109+
const filterLowerCase = this.filter.toLowerCase();
110+
results = results.filter(file => file.name.toLowerCase().includes(filterLowerCase));
114111
}
115112

116-
if (sort) {
117-
const reverse: boolean = sort.slice(0, 1) === '-';
113+
if (this.sort) {
114+
const reverse: boolean = this.sort.slice(0, 1) === '-';
118115

119-
results = A(results).sortBy(sort.slice(+reverse));
116+
results = A(results).sortBy(this.sort.slice(+reverse));
120117

121118
if (reverse) {
122119
results = results.reverse();
@@ -128,77 +125,84 @@ export default class GuidFile extends Controller {
128125

129126
@action
130127
download(this: GuidFile, version: number) {
131-
const url = `${this.get('downloadLink')}?revision=${version}`;
128+
// analytics sent in template, since this is used twice
129+
const url = `${this.downloadLink}?revision=${version}`;
132130
window.location.href = url;
133131
}
134132

135133
@action
136134
async delete(this: GuidFile) {
137135
this.set('deleteModalOpen', false);
136+
this.analytics.click('button', 'Quick Files - Delete file');
138137

139138
try {
140-
await this.get('file').destroyRecord();
141-
this.transitionToRoute('guid-user.quickfiles', this.get('user').get('id'));
142-
const message: string = this.get('i18n').t('file_detail.delete_success');
143-
return this.get('toast').success(message);
139+
await this.file.destroyRecord();
140+
this.transitionToRoute('guid-user.quickfiles', this.user.id);
141+
const message: string = this.i18n.t('file_detail.delete_success');
142+
return this.toast.success(message);
144143
} catch (e) {
145-
const message: string = this.get('i18n').t('file_detail.delete_fail');
146-
return this.get('toast').error(message);
144+
const message: string = this.i18n.t('file_detail.delete_fail');
145+
return this.toast.error(message);
147146
}
148147
}
149148

150149
@action
151150
openDeleteModal(this: GuidFile) {
152151
this.set('deleteModalOpen', true);
152+
this.analytics.click('button', 'Quick Files - Open delete modal');
153153
}
154154

155155
@action
156156
closeDeleteModal(this: GuidFile) {
157157
this.set('deleteModalOpen', false);
158+
this.analytics.click('button', 'Quick Files - Close delete modal');
158159
}
159160

160161
@action
161162
changeView(this: GuidFile, button: string) {
162-
const show = lookupTable[this.get('show')][button];
163+
const show = lookupTable[this.show][button];
163164

164165
if (show) {
165166
this.set('show', show);
166167
}
168+
this.analytics.click('button', `Quick Files - Change view - ${show}`);
167169
}
168170

169171
@action
170172
async save(this: GuidFile, text: string) {
171-
const toast = this.get('toast');
172-
const i18n = this.get('i18n');
173+
this.analytics.click('button', 'Quick Files - Save');
173174

174175
try {
175-
await this.get('file').updateContents(text);
176-
return toast.success(i18n.t('file_detail.save_success'));
176+
await this.file.updateContents(text);
177+
return this.toast.success(this.i18n.t('file_detail.save_success'));
177178
} catch (e) {
178-
return toast.error(i18n.t('file_detail.save_fail'));
179+
return this.toast.error(this.i18n.t('file_detail.save_fail'));
179180
}
180181
}
181182

182183
@action
183184
async openFile(this: GuidFile, file: File) {
184-
const guid = file.get('guid') || await file.getGuid();
185+
const guid = file.guid || await file.getGuid();
185186

186187
this.set('revision', null);
187188
this.transitionToRoute('guid-file', guid, { queryParams: { show: 'view' } });
189+
this.analytics.click('link', 'Quick Files - Open file');
188190
}
189191

190192
@action
191193
addTag(this: GuidFile, tag: string) {
192-
const model = this.get('file');
193-
model.set('tags', [...this.get('tags').slice(), tag].sort());
194+
const model = this.file;
195+
model.set('tags', [...this.tags.slice(), tag].sort());
194196
model.save();
197+
this.analytics.click('button', 'Quick Files - Add tag');
195198
}
196199

197200
@action
198201
removeTagAtIndex(this: GuidFile, index: number) {
199-
const model = this.get('file');
200-
model.set('tags', this.get('tags').slice().removeAt(index));
202+
const model = this.file;
203+
model.set('tags', this.tags.slice().removeAt(index));
201204
model.save();
205+
this.analytics.click('button', 'Quick Files - Remove tag');
202206
}
203207

204208
@action

app/guid-file/template.hbs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@
5555
</div>
5656
</div>
5757
{{#bs-modal open=deleteModalOpen onSubmit=(action 'delete') onHidden=(action 'closeDeleteModal') as |modal|}}
58-
{{#modal.header onClose=(action 'closeDeleteModal')}}
58+
{{#modal.header}}
5959
<h4 class="modal-title">{{t "file_detail.delete_file.question"}}</h4>
6060
{{/modal.header}}
6161
{{#modal.body}}
6262
<p>{{t 'file_detail.delete_file.confirm' file-name=model.file.name}}</p>
6363
{{/modal.body}}
6464
{{#modal.footer}}
65-
{{#bs-button onClick=(action 'closeDeleteModal') type='default'}}
65+
{{#bs-button onClick=(action modal.close) type='default'}}
6666
{{t 'general.cancel'}}
6767
{{/bs-button}}
6868
{{#bs-button onClick=(action modal.submit) type='danger'}}
@@ -100,7 +100,12 @@
100100
readOnly=(unless canEdit true false)
101101
as |tag|
102102
}}
103-
<a href='{{searchUrl}}?q=(tags:"{{tag}}")'>{{tag}}</a>
103+
<a
104+
href='{{searchUrl}}?q=(tags:"{{tag}}")'
105+
onclick={{action 'click' 'link' 'Quick Files - Search by tag' target=analytics}}
106+
>
107+
{{tag}}
108+
</a>
104109
{{/tag-input}}
105110
<div class="tags_clear"></div>
106111
</div>

0 commit comments

Comments
 (0)