Skip to content

Commit

Permalink
Support for schema v2 (#198)
Browse files Browse the repository at this point in the history
* Add launch darkly addon

* Add slient side key to envs

* Configure launch darkly

* setup UI versioning

* setup variation for api urll v1 and v2

* Handle types, v2 returns lowecase value

* Add versioning to components

* Update model for name to names

* WIP: update template with new data

* Set name correctly

* Implement v2 view templates for v2, fix model to work with v2

* Update launch darkly with correct client side id for env

* removing key for anonymous user mode

* Update config to use remote flags

* Update the adapters to use remote flags

* Update the route to use remote flags

* Update the templates to use remote flags

* Fix bug with website fixes #218

* Fix other names display issue

* comma separate org types

* Update text for submitting a change request

* fix duplicate lang on othernames
  • Loading branch information
kaysiz committed Feb 20, 2024
1 parent 1e25211 commit eef6b0a
Show file tree
Hide file tree
Showing 18 changed files with 2,629 additions and 39 deletions.
4 changes: 3 additions & 1 deletion .env.dev
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
API_URL=https://api.dev.ror.org
API_URL_V1=https://api.dev.ror.org/v1
API_URL_V2=https://api.dev.ror.org/v2
SENTRY_DSN=https://1c334995f85448b1afa561c8ccf13791@sentry.io/1422597
BASE_URL=https://dev.ror.org
LAUNCH_DARKLY_CLIENT_SIDE_ID=6390f62d05087a11e466bfc9
4 changes: 3 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
API_URL=https://api.ror.org
API_URL_V1=https://api.ror.org/v1
API_URL_V2=https://api.ror.org/v2
SENTRY_DSN=https://1c334995f85448b1afa561c8ccf13791@sentry.io/1422597
BASE_URL=https://ror.org
LAUNCH_DARKLY_CLIENT_SIDE_ID=636d08a3d56cf611cc88019d
4 changes: 3 additions & 1 deletion .env.staging
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
API_URL=https://api.staging.ror.org
API_URL_V1=https://api.staging.ror.org/v1
API_URL_V2=https://api.staging.ror.org/v2
SENTRY_DSN=https://1c334995f85448b1afa561c8ccf13791@sentry.io/1422597
BASE_URL=https://staging.ror.org
LAUNCH_DARKLY_CLIENT_SIDE_ID=636d08a3d56cf611cc88019c
7 changes: 6 additions & 1 deletion app/adapters/application.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import DS from 'ember-data';
import ENV from 'ror-app/config/environment';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';

export default DS.JSONAPIAdapter.extend({
host: ENV.API_URL
launchDarkly: service(),
host: computed('launchDarkly.variation', function() {
return this.launchDarkly.variation('v2_ui') ? ENV.API_URL_V2 : ENV.API_URL_V1;
}),
});
9 changes: 7 additions & 2 deletions app/adapters/organization.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import DS from 'ember-data';
import ENV from 'ror-app/config/environment';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';

export default DS.JSONAPIAdapter.extend({
host: ENV.API_URL,
launchDarkly: service(),
host: computed('launchDarkly.variation', function() {
return this.launchDarkly.variation('v2_ui') ? ENV.API_URL_V2 : ENV.API_URL_V1;
}),

urlForFindRecord(id, modelName) {
return `${ENV.API_URL}/${modelName}s/ror.org/${id}`;
return `${this.host}/${modelName}s/ror.org/${id}`;
},

init() {
Expand Down
File renamed without changes.
131 changes: 131 additions & 0 deletions app/components/v2/organization-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { capitalize } from '@ember/string';

export default Component.extend({
INACTIVE_STATUSES: ['inactive', 'withdrawn'],
fundref: null,
grid: null,
isni: null,
wikidata: null,
relationships: {},
relationshipsCount: null,
router: service(),
isSearch: computed('router.currentURL', function() {
return this.router.currentURL.includes("search")
}),
inactiveStatus: false,
name: null,
lastModifiedDate: null,
otherNames: null,
organizationTypes: null,


// Convert label array into a dictionary with relationship type as key
// for variable fields in template
convertRelationships(relationships){
let formattedRelationships = {Parent:[], Child:[], Related:[], Successor:[], Predecessor:[]};
for (let i = 0; i < relationships.length; i++){
formattedRelationships[capitalize(relationships[i]["type"])].push({"label": relationships[i]["label"], "id": relationships[i]["id"]});
}
return formattedRelationships
},

convertOtherNames(names){
const groupedNames = names.reduce((result, name) => {
if (name.types.includes("ror_display")) {
return result;
}

const type = name.types.includes("label") ? "label" : name.types[0];
result[type] = result[type] || [];
result[type].push(name);

return result;
}, {});

if (groupedNames.label) {
groupedNames.label.forEach((label) => {
if (label.lang && !label.value.includes(`(${label.lang})`)) {
label.value = `${label.value} (${label.lang})`;
}
});
}

const values = Object.values(groupedNames).flat().map(item => item.value).join(', ');

return {values: values, groupedNames: groupedNames};
},

getName(names) {
let name = names.find(record => record.types.includes("ror_display"));

return name ? name.value : null;
},

didInsertElement() {
if(this.INACTIVE_STATUSES.indexOf(this.model.get('status')) > -1) {
this.set('inactiveStatus', true)
}
if(this.model.get('relationships')) {
this.set('relationshipsCount', this.model.get('relationships').length)
this.set('relationships', this.convertRelationships(this.model.get('relationships')))
}
if (this.model.get('external_ids')){
this.model.get('external_ids').forEach(externalId => {
switch (externalId.type) {
case 'grid':
if (externalId.preferred) {
this.set('grid', externalId.preferred);
}
break;

case 'isni':
if (externalId.preferred) {
let displayIsni = externalId.preferred;
let linkIsni = externalId.preferred.replace(/-|\s/g, "");
this.set('display_isni', displayIsni);
this.set('link_isni', linkIsni);
} else {
let displayIsni = externalId.all[0];
let linkIsni = externalId.all[0].replace(/-|\s/g, "");
this.set('display_isni', displayIsni);
this.set('link_isni', linkIsni);
}
break;

case 'fundref':
if (externalId.preferred) {
this.set('fundref', externalId.preferred);
} else {
this.set('fundref', externalId.all[0]);
}
break;

case 'wikidata':
if (externalId.preferred) {
this.set('wikidata', externalId.preferred);
} else {
this.set('wikidata', externalId.all[0]);
}
break;

default:
break;
}
});
}
if (this.model.get('names')){
let names = this.model.get('names');
this.set('name', this.getName(names));
this.set('otherNames', this.convertOtherNames(names));
}
if (this.model.get('admin.last_modified')) {
this.set('lastModifiedDate', this.model.get('admin.last_modified').date)
}
if (this.model.get('types')) {
this.set('organizationTypes', this.model.get('types').map(type => type.charAt(0).toUpperCase() + type.slice(1)).join(', '))
}
}
});
7 changes: 5 additions & 2 deletions app/models/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import DS from 'ember-data';
export default DS.Model.extend({
meta: DS.attr(),

name: DS.attr('string'),
name: DS.attr('string'), //TODO: Remove this when v1 has been retired
names: DS.attr(),
local: DS.attr('string'),
types: DS.attr(),
links: DS.attr(),
Expand All @@ -15,6 +16,8 @@ export default DS.Model.extend({
country: DS.attr(),
addresses: DS.attr(),
relationships: DS.attr(),
status: DS.attr('string')
status: DS.attr('string'),
admin: DS.attr(),
locations: DS.attr()
});

8 changes: 7 additions & 1 deletion app/routes/application.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import Route from '@ember/routing/route';

export default Route.extend({

beforeModel(){
let user = {
key: 'user-key-123abc',
anonymous: true
};
return this.launchDarkly.initialize(user);
}
});
156 changes: 156 additions & 0 deletions app/templates/components/v2/organization-item.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<div class="card-title">
<div class="row">
<div class="col-lg-9 col-sm-12">
<h1>
<img class="ror-id mb-1" src="/assets/ror-logo-small.png" alt="ROR ID"> {{#link-to "organizations.show" model.id class="card-link logo-link"}}https://ror.org/{{model.id}}{{/link-to}}
</h1>
</div>
<div class="col-lg-3 col-sm-12">
{{#if inactiveStatus}}
<span class="badge badge-status">{{model.status}}</span>
{{/if}}
</div>
</div>
</div>
<hr>
{{#if inactiveStatus}}
{{#if (not isSearch)}}
<div class="callout">
<span class="text-default"><em><b>This record has
{{#if (eq model.status "withdrawn")}}been {{/if}}{{#if (eq model.status "inactive")}}become {{/if}}
{{model.status}}
{{#if (eq model.status "withdrawn")}}from {{/if}}{{#if (eq model.status "inactive")}}in{{/if}}
ROR and is no longer actively maintained.
</b></em></span>
{{#each-in relationships as |relationshipType relationshipInstances|}}
{{#if (eq relationshipType "Successor")}}
{{#if relationshipInstances}}
<span class="text-default"><em>This organization is succeeded by
{{#each relationshipInstances as |relationshipInstance|}}
{{relationshipInstance.label}} (<a target="_blank" rel="noopener" class="card-link mt-1" href={{relationshipInstance.id}}>{{relationshipInstance.id}}</a>){{#if @index}}, {{/if}}.
{{/each}}
</em></span>
{{/if}}
{{/if}}
{{/each-in}}
<br><a target="_blank" rel="noopener" class="card-link mt-1" href="https://ror.readme.io/docs/ror-data-structure#status"><em>Learn more about {{model.status}} records</em></a>
</div>
{{/if}}
{{/if}}
<div class="font-weight-normal">
<div class="row">
<div class="col-md-12">
<h2 class="card-title text-default">{{name}}</h2>
</div>
{{#if isSearch}}
<div class="col-md-12">
{{#if otherNames.values}}
<h3 class="mt-3 mb-0 mr-2 d-inline-block">Other names: </h3>
<span class="text-default">
{{otherNames.values}}
</span>
{{/if}}
</div>
{{/if}}
<div class="col-md-6">
<h3 class="mt-3 mb-0">Organization types</h3>
<span class="text-default">{{capitalize organizationTypes}}</span><br />
{{#if (not isSearch)}}
{{#if otherNames.groupedNames}}
<h3 class="mt-3 mb-0 mr-2 d-inline-block">Other names</h3><br />
{{#each-in otherNames.groupedNames as |nameType nameInstances|}}
{{#if nameType}}
{{#if nameInstances}}
<span class="text-default mt-3 mb-3 font-weight-bold">{{capitalize (pluralize nameType)}}</span><br>
{{#each nameInstances as |nameInstance|}}
<span class="text-default">{{nameInstance.value}}</span><br />
{{/each}}
{{/if}}
{{/if}}
{{/each-in}}
{{/if}}
{{/if}}
</div>
<div class="col-md-6">
{{#if model.locations}}
<h3 class="mt-3 mb-0">Locations</h3>
{{#each model.locations as |location|}}
{{#if location.geonames_details.name}}
<span class="text-default">{{location.geonames_details.name}} (GeoNames ID <a target="_blank" rel="noopener" href="https://www.geonames.org/{{location.geonames_id}}" >{{location.geonames_id}}</a>), {{location.geonames_details.country_name}}</span><br>
{{/if}}
{{/each}}
{{/if}}
{{#if model.links}}
<h3 class="mt-3 mb-0">Website</h3>
{{#each model.links as |link|}}
{{#if (eq link.type 'website')}}
<a target="_blank" rel="noopener" class="card-link" href={{link.value}}>{{link.value}}</a><br>
{{/if}}
{{/each}}
{{/if}}
{{#if (or grid display_isni fundref wikidata)}}
<h3 class="mt-3 mb-0">Other Identifiers</h3>
{{#if grid}}
<span class="text-default">GRID</span> {{grid}}<br>
{{/if}}
{{#if display_isni}}
<span class="text-default">ISNI</span> <a target="_blank" rel="noopener" class="card-link" href="http://isni.org/isni/{{link_isni}}">{{display_isni}}</a><br>
{{/if}}
{{#if fundref}}
<span class="text-default">Crossref Funder ID</span> <a target="_blank" class="card-link" rel="noopener" href="https://api.crossref.org/funders/{{fundref}}">{{fundref}}</a><br>
{{/if}}
{{#if wikidata}}
<span class="text-default">Wikidata</span> <a target="_blank" rel="noopener" class="card-link" href="https://www.wikidata.org/wiki/{{wikidata}}">{{wikidata}}</a><br>
{{/if}}
{{/if}}
</div>
</div>
{{#if relationshipsCount}}
<div class="row">
{{#if isSearch}}
<div class="col-md-6">
<h3 class="mt-3 mb-0">Relationships ({{relationshipsCount}})</h3>
</div>
{{/if}}
{{#if (not isSearch)}}
<div class="col-md-12">
<h3 class="mt-3 mb-0">Relationships</h3>
{{#each-in relationships as |relationshipType relationshipInstances|}}
{{#if relationshipType}}
{{#if relationshipInstances}}
<span class="text-default mt-3 mb-3 font-weight-bold">{{relationshipType}} Organization(s)</span><br>
{{#each relationshipInstances as |relationshipInstance|}}
<a target="_blank" rel="noopener" class="card-link mt-1" href={{relationshipInstance.id}}>{{relationshipInstance.label}}</a><br>
{{/each}}
{{/if}}
{{/if}}
{{/each-in}}
</div>
{{/if}}
</div>
{{/if}}
</div>
<div class="footer text-left pb-0 ml-3">
{{#if isSearch}}
{{#link-to "organizations.show" model.id class="btn btn-sm btn-round"}}View details{{/link-to}}
{{/if}}
{{#if (not isSearch)}}
<p class="mt-3 mb-0"><i>Some record data is not displayed in this view. <a target="_blank" rel="noopener" href="https://api.ror.org/v2/organizations/{{model.id}}">See JSON view for full record data</a></i></p>
<p class="mt-3 mb-0">
<i>
{{#if lastModifiedDate}}
Record last modified {{ lastModifiedDate }}.
{{/if}}
Is there an issue with the data on this record? <a target="_blank" rel="noopener" href="http://curation-request.ror.org">Suggest a change</a>
</i>
</p>
{{/if}}
</div>
</div>
</div>
</div>
</div>
6 changes: 5 additions & 1 deletion app/templates/organizations/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
</div>
<div class="col-md-10 col-sm-12">
{{#each model as |organization|}}
{{organization-item model=organization}}
{{#if (variation "v2_ui")}}
{{v2/organization-item model=organization view="list"}}
{{else}}
{{v1/organization-item model=organization}}
{{/if}}
{{/each}}
</div>
{{#if (gt model.meta.totalPages 1)}}
Expand Down

0 comments on commit eef6b0a

Please sign in to comment.