Skip to content

Commit

Permalink
Merge branch 'release/19.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
jamescdavis committed Jan 3, 2019
2 parents 4f01be7 + 16088ea commit c962b82
Show file tree
Hide file tree
Showing 394 changed files with 7,367 additions and 1,670 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ module.exports = {
files: ['tests/**/*'],
rules: {
'no-await-in-loop': 'off',
'ember/avoid-leaking-state-in-components': 'off',
},
},
],
Expand Down
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.svg -diff linguist-generated=true
*.png -diff linguist-generated=true
*.jpg -diff linguist-generated=true
15 changes: 15 additions & 0 deletions .mergify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# see: https://doc.mergify.io/configuration.html

pull_request_rules:
- name: automatic strict merge on CI success and review
conditions:
- base~=^develop$|^release/ # only for PRs targeting develop or release branches
- status-success=continuous-integration/travis-ci/pr # must pass travis
- "#approved-reviews-by>0" # at least one approval from someone with write permission
- "#changes-requested-reviews-by=0" # no changes requested
- label!=no merge # use this label to prevent automatic merge
- -title~=\b[Ww][Ii][Pp]\b
actions:
merge:
method: merge # merge with a merge commit
strict: smart # make sure PR is up-to-date before merging (but queue updates)
1 change: 1 addition & 0 deletions .stylelintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ rules:
max-nesting-depth: 2
order/properties-alphabetical-order: null
scss/selector-no-redundant-nesting-selector: null
scss/percent-placeholder-pattern: null
selector-class-pattern: null
property-no-unknown:
- true
Expand Down
7 changes: 5 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@ cache:
jobs:
include:
- stage: "test"
if: |
branch ~= /^develop$|^master$|^\d+\.\d+\.\d+$|^release\/.+$/ OR \
type = pull_request OR \
env(RESTRICT_PUSH_BUILDS) != true
addons:
chrome: stable
firefox: latest
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
Expand All @@ -37,7 +40,7 @@ jobs:
if: |
branch = develop AND \
type != pull_request AND \
fork = false
repo = CenterForOpenScience/ember-osf-web
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash
- export PATH=$HOME/.yarn/bin:$PATH
Expand Down
82 changes: 82 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,72 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [19.0.0] - 2019-01-03
### Added
- Addons:
- `ember-onbeforeunload` - Handle warnings if we have unsaved changes on a page
- Components:
- `new-project-navigation-modal` - For navigating away to nodes. Or not.
- Handbook:
- `new-project-modal` component
- `new-project-navigation-modal` component
- Models:
- `user-email`
- Routes:
- `settings.profile` - redirects to `settings.profile.name`
- `settings.profile.education`
- `settings.profile.employment`
- `settings.profile.name` - Adds ability to change your name and name parts (with citation preview)
- `settings.profile.social`
- Tests:
- Integration:
- `settings.profile.name.-components.citation-preview`
- `new-project-navigation-modal` - component integration test
- Acceptance:
- `settings.profile.name`
- `guid-user/quickfiles` - acceptance tests around landing on the page and mostly move to project
- Add percy everywhere in the main app
- Helpers:
- `require-auth` - Mocks currentUser service to verify that routes that require auth redirect if unauthenticated
- Types:
- `ember-power-select/test-support` - types for useful functions
- Travis
- Remove Firefox Testing

### Changed
- Addons:
- `ember-code-snippet@2.3.1`
- Components:
- `node-navbar` - Choose links to display with the same logic as legacy
- `validated-model-form` - Add an optional hook for onWillDestroy
- `sign-up-form` - accept `campaign` as an optional argument and set on user-registration model
- Handbook:
- `validated-model-form` - Show how onWillDestroy works and use ember-onbeforeunload
- Models:
- `node`
- added `wikiEnabled` boolean attribute
- added `userHasReadPermission` computed property
- renamed `currentUserCanEdit` computed property to `userHasWritePermission`
- renamed `currentUserIsAdmin` computed property to `userHasAdminPermission`
- `user`
- added validations for name fields
- `provider` - made partial assets acceptable
- `preprint-provider` - added `documentType` computed property for preprint word lookup
- `user-registration` - added `campaign` property
- Routes:
- `settings` - redirects to `settings.profile.name`
- `register` - add branding for registries and preprint providers
- Tests:
- improved integration tests for `node-navbar` component
- Acceptance:
- `register` - acceptance tests for the sign up page
- Adapters:
- Added `parentRelationship` property to `osf-adapter`. Allows creating records at nested endpoints.
- Routes:
- Add email verification modal to application template
- Misc:
- Upgraded to `osf-style` 1.8.0

## [18.2.2] - 2018-12-18
### Added:
- Flags:
Expand Down Expand Up @@ -44,6 +110,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Engines:
- `registries` - page resetting and scrolling fixes

### Changed
- Components:
- `file-browser` - replaced project navigation modal with `new-project-navigation-modal` component
- `new-project-modal` - Made it smarter and more reusable
- `project-selector` - replaced project creation modal with `new-project-modal` component
- Pages:
- `dashboard` - replaced project creation modal with `new-project-modal` component
- Tests:
- `dashboard` - acceptance tests related to project creation workflow

## [18.1.0] - 2018-10-30
### Added
- Components:
Expand All @@ -61,6 +137,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `settings.applications` - list of developer apps
- `settings.applications.edit`
- `settings.applications.create`
- Decorators:
- `@layout(template, styles)` in `ember-osf-web/decorators/component`

### Changed
- Components:
Expand All @@ -75,6 +153,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- `root` factory now adds all feature flags, not just route flags
- `user` factory has 'withFiles' trait so non-current users can have files easily
- `user` serializer has default_region relationship (hardcoded to us)
- Decorators:
- `@requiredAction` moved to `ember-osf-web/decorators/component`
- Blueprints:
- `component` - use `@layout`, don't add `styles.scss` or `@localClassNames`

### Removed
- Flags:
Expand Down
114 changes: 78 additions & 36 deletions app/adapters/osf-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { service } from '@ember-decorators/service';
import { assert } from '@ember/debug';
import { underscore } from '@ember/string';
import DS from 'ember-data';
import config from 'ember-get-config';
Expand Down Expand Up @@ -39,9 +40,29 @@ enum RequestType {
* @extends DS.JSONAPIAdapter
* @uses GenericDataAdapterMixin
*/
export default class OsfAdapter extends JSONAPIAdapter.extend({
host,
namespace,
export default class OsfAdapter extends JSONAPIAdapter {
@service session!: Session;
@service currentUser!: CurrentUser;

host = host;
namespace = namespace;

/**
* When an object lives "under" another in the API, set `parentRelationship` to the name of
* the belongsTo that points to the parent object. Requests for creating new children will
* go to the nested route for that relationship.
*
* e.g. If the contributor adapter has `parentRelationship = 'node'`, creating a new contributor
* for node xyz will POST to /v2/nodes/xyz/contributors/
*
* TODO: `OsfAdapter<M extends OsfModel>`, `parentRelationship: RelationshipsFor<M> | null`
*/
parentRelationship: string | null = null;

get headers() {
// Not a computed; evaluate every time in case something changes
return this.currentUser.ajaxHeaders();
}

/**
* Overrides buildQuery method - Allows users to embed resources with findRecord
Expand All @@ -51,11 +72,11 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
*
* @method buildQuery
*/
buildQuery(this: OsfAdapter, snapshot: DS.Snapshot): object {
buildQuery(snapshot: DS.Snapshot): object {
const { query: adapterOptionsQuery = {} } = (snapshot.adapterOptions || {}) as AdapterOptions;

const query: { include?: any, embed?: any } = {
...this._super(snapshot),
...super.buildQuery(snapshot),
...adapterOptionsQuery,
};

Expand All @@ -64,32 +85,21 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
embed: query.include,
include: undefined,
};
},
}

buildURL(
this: OsfAdapter,
modelName: string,
modelName: string | undefined,
id: string | null,
snapshot: DS.Snapshot | null,
requestType: string,
query?: {},
): string {
let url: string = this._super(modelName, id, snapshot, requestType);
let url: string = super.buildURL(modelName, id, snapshot, requestType, query);

if (snapshot) {
const { record, adapterOptions } = snapshot;
const opts: AdapterOptions = adapterOptions || {};
if (requestType === 'deleteRecord') {
if (record && record.get('links.delete')) {
url = record.get('links.delete');
} else if (record && record.get('links.self')) {
url = record.get('links.self');
}
} else if (requestType === 'updateRecord' || requestType === 'findRecord') {
if (record && record.get('links.self')) {
url = record.get('links.self');
}
} else if (opts.url) {
url = opts.url; // eslint-disable-line prefer-destructuring
const { adapterOptions }: { adapterOptions?: { url?: string } } = snapshot;
if (adapterOptions && adapterOptions.url) {
url = adapterOptions.url; // eslint-disable-line prefer-destructuring
}
}

Expand All @@ -98,11 +108,51 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
if (url.lastIndexOf('/') !== url.length - 1) {
url += '/';
}

return url;
},
}

urlForFindRecord(id: string, modelName: string, snapshot: DS.Snapshot): string {
if (snapshot && snapshot.record && snapshot.record.links && snapshot.record.links.self) {
return snapshot.record.links.self;
}
return super.urlForFindRecord(id, modelName, snapshot);
}

urlForCreateRecord(modelName: string, snapshot: DS.Snapshot): string {
const { parentRelationship } = this;
if (!parentRelationship) {
return super.urlForCreateRecord(modelName, snapshot);
}

ajaxOptions(this: OsfAdapter, url: string, type: RequestType, options?: { isBulk?: boolean }): object {
const hash = this._super(url, type, options);
const parentObj = snapshot.record.belongsTo(parentRelationship).value();
const inverseRelation: string = snapshot.record.inverseFor(parentRelationship).name;

assert('To create a nested object, the parent must already be loaded.', parentObj);

const url = parentObj.get(`links.relationships.${inverseRelation}.links.related.href`);

assert(`Couldn't find create link for nested ${modelName}`, url);

return url;
}

urlForUpdateRecord(id: string, modelName: string, snapshot: DS.Snapshot): string {
const { links } = snapshot.record;
if (links && links.self) {
return links.self;
}
return super.urlForUpdateRecord(id, modelName, snapshot);
}

urlForDeleteRecord(id: string, modelName: string, snapshot: DS.Snapshot): string {
const { links } = snapshot.record;
const url = links.delete || links.self;
return url || super.urlForDeleteRecord(id, modelName, snapshot);
}

ajaxOptions(url: string, type: RequestType, options?: { isBulk?: boolean }): object {
const hash: any = super.ajaxOptions(url, type, options);

hash.xhrFields = {
withCredentials: true,
Expand All @@ -113,7 +163,7 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
}

return hash;
},
}

buildRelationshipURL(snapshot: DS.Snapshot, relationship: string): string {
const links = !!relationship && snapshot.record.get(`relationshipLinks.${underscore(relationship)}.links`);
Expand All @@ -123,19 +173,11 @@ export default class OsfAdapter extends JSONAPIAdapter.extend({
}

return '';
},
}

pathForType(modelName: string): string {
const underscored: string = underscore(modelName);
return pluralize(underscored);
},
}) {
@service session!: Session;
@service currentUser!: CurrentUser;

get headers() {
// Not a computed; evaluate every time in case something changes
return this.currentUser.ajaxHeaders();
}

handleResponse(
Expand Down
11 changes: 11 additions & 0 deletions app/adapters/user-email.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import OsfAdapter from './osf-adapter';

export default class UserEmailAdapter extends OsfAdapter {
parentRelationship = 'user';
}

declare module 'ember-data' {
interface AdapterRegistry {
'user-email': UserEmailAdapter;
}
}
9 changes: 7 additions & 2 deletions app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ const App = Application.extend({
dependencies: {
services: [
'analytics',
'current-user',
'features',
'i18n',
'router',
'store',
Expand All @@ -49,22 +51,25 @@ const App = Application.extend({
'features',
'head-data',
'i18n',
'media',
'page-title-list',
'ready',
'router',
'session',
'status-messages',
'store',
],
externalRoutes: {
registration: 'guid-registration',
'guid-registration': 'guid-registration',
'guid-registration.analytics': 'guid-registration.analytics',
'guid-registration.forks': 'guid-registration.forks',
},
},
},
analyticsPage: {
dependencies: {
services: [
'i18n',
'route-context',
'cookies',
'store',
'analytics',
Expand Down
Loading

0 comments on commit c962b82

Please sign in to comment.