-
Notifications
You must be signed in to change notification settings - Fork 42
Branding Phase 2 - Provider Domains [PREP-259] #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Branding Phase 2 - Provider Domains [PREP-259] #201
Conversation
…ints into feature/branding-phase2
Created error-page component and migrated forbidden, page-not-found, and resource-deleted to use error-page component Updated english translation to match error-component migration Removed unused reroute-guid template
Update provider route to use the redirect if the domain exists in the configuration Fix for asset loading in index.html\
Update default ember cli settings
Add translation with 'or' from index page
f2f9df6 to
d238433
Compare
…ints into feature/branding-phase2
…ints into feature/branding-phase2
…ints into feature/branding-phase2
…ints into feature/branding-phase2
abought
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not a complete review, but I have been called away to a number of Lookit tasks, and am submitting any notes so far "as is". No functional review has been performed yet.
Per discussion with Barrett today, first impressions are all around maintainability:
- Please add a few short YUIDoc strings on helpers to help document specific requirements being met
- Very strong preference for at least some tests. If we can fast track the factories PR, that would help with this. Maintainability is a challenge due to complexity of 4-state router requirements.
- If possible, a CDN for css assets would help us avoid some of the scattered code for asset paths. May be out of scope for this PR but would help with maintainability.
| }, | ||
| application: { | ||
| // Nothing to translate | ||
| separator: ` | ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this something we really need to expose to translations?
If the goal is only to DRY this code, consider using the ember-page-title addon config:
https://github.com/tim-evans/ember-page-title#api
| const configProvider = providers.find(p => p.id === providerId); | ||
|
|
||
| if (!configProvider) | ||
| throw new Error('Provider is not configured properly. Check the Ember configuration.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There does not appear to be any .catch statement associated with this promise. (aside from whatever ember will do internally if the afterModel hook returns a rejected promise)
- Is this an error the user should be notified about?
- If so, should there be a translation string here?
| if (providerIds.includes(slugLower)) { | ||
| const {domain} = providers.find(provider => provider.id === slugLower) || {}; | ||
|
|
||
| // This should be caught by the proxy, but we'll redirect just in case it is not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: "the proxy" refers to nginx handling domain redirect (before it hits ember)
| continue; | ||
|
|
||
| if (provider.id === 'osf') { | ||
| provider.domain = OSF_URL || 'localhost:5000'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please try to avoid hardcoding URLs and ports wherever possible, and strongly prefer fetching config from pre-existing sources. (ember osf config should already provide an OSF URL, for example)
| continue; | ||
| } | ||
|
|
||
| const suffix = DOMAIN_PREFIX ? '' : `:${PORT ? PORT : '4200'}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't seem to find a good way to determine port number, alas. At very least this could be shortened to PORT || '4200'.
But to be honest, that's bikeshedding over syntax. It seems like this code is trying to do a very large number of things simultaneously, which is inevitably going to add complexity.
| assets: { | ||
| enabled: true, | ||
| content: ` | ||
| <script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Future suggestion:
Consider using a CDN to serve assets like CSS. That would save us from this code because we would not need ember to construct CSS urls.
(ember locally would serve normally, and in production builds we'd use a CDN)
May not be in scope for this PR, but strongly worth future consideration. cos.io, for example, is already moving in this direction. This is a common pattern and I think any deployment challenges would be very solvable with automated DevOps support.
This code is a constructed string: it will be hidden from any tooling or bugfixing/ validation, and it causes url logic to be in many different places. By putting these specific assets on a different domain, the asset path wouldn't depend on URL- a CDN or "static asset domain" would help us avoid the necessity for some very gnarly code, and sidestep a potential long-term maintainability issue.
| guidPathPrefix: Ember.computed('isProvider', 'isDomain', 'id', function() { | ||
| let pathPrefix = '/'; | ||
|
|
||
| if (!this.get('isDomain') && this.get('isProvider')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See note elsewhere on CDN possibilities to simplify this code.
| @@ -0,0 +1,15 @@ | |||
| import Ember from 'ember'; | |||
|
|
|||
| export default Ember.Helper.extend({ | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per discussion- can you please add yuidoc comments to explain the purpose of this helper?
(eg driven by the requirements of the 4-state router)
| {{#each pair as |subject|}} | ||
| <div class="col-xs-12 col-sm-6 subject-item {{if (get subjectTooltips subject.text) 'hint--bottom hint--large'}}" aria-label={{get subjectTooltips subject.text}}> | ||
| {{#link-to (if theme.isProvider 'provider.discover' 'discover') (query-params subjectFilter=subject.text) class='btn btn-primary p-sm' invokeAction=(action "click" "link" (concat 'Preprints - Index - Browse ' subject.text))}} | ||
| {{#link-to (route-prefix 'discover') (query-params subjectFilter=subject.text) class='btn btn-primary p-sm' invokeAction=(action "click" "link" (concat 'Preprints - Index - Browse ' subject.text))}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a somewhat gnarly requirement. Have you taken a look at Route#renderTemplate? It seems to provide a way for one route to use the template or behavior of another. I'm not totally sure if it applies here, but might spark some ideas.
http://emberjs.com/api/classes/Ember.Route.html#method_renderTemplate
| @@ -0,0 +1,48 @@ | |||
| #!/usr/bin/env node | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No review performed on this script in initial round.
| .find(p => | ||
| // Check if the hostname includes: the domain, the domain with dashes instead of periods, or just the id | ||
| hostname.includes(p.domain) || | ||
| hostname.includes(p.domain.replace(/\./g, '-')) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When is this relevant, out of curiosity?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had a conversation with @icereval a while back about how we might deploy this on staging/test. agrixiv-org.staging.osf.io was a likely naming scheme. Putting a dot in a subdomain creates another subdomain.
hmoco
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick-ish run through. Looks good, just have a few questions about some choices made here. Nice work!
| this.route('content', {path: '/:preprint_id'}); | ||
| this.route('discover'); | ||
|
|
||
| if (provider) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does provider get recalculated properly when window.location changes? I would assume it does, since it works, but it seems weird that a const value changed would cause this Router.map to be rerun, assuming the preprint app is still a singleton across the different providers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since changing the provider requires a full page reload, the entire app, including the router, will be evaluated each time.
| session: Ember.inject.service(), | ||
|
|
||
| // If we're using a provider domain | ||
| isDomain: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not the biggest fan of this, could we possibly change it to something like hasDomain, isProvider, onProvider, onProviderDomain? Don't feel strongly about any of these, but was initially confused by isDomain (although the comment is super helpful)
| pathPrefix += 'preprints/'; | ||
|
|
||
| if (this.get('isProvider')) { | ||
| pathPrefix += `${this.get('id')}/`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, just realized that there's also something called isProvider. When would isDomain and isProvider not both be the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the providers will not use their own domain, and will stay under osf.io/preprints/whatever
isProvider is used to determine if the provider is OSF (for our default case) or not
isDomain is whether the provider is using a domain or not
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a case in which the provider being used has a domain but is not using it?
isProvider is true if, and only if, the current provider is not OSF?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the domain exists in the config (and domains are enabled), then using the domain is used. It has to be one or the other due to the requirements.
Yes, isProvider basically means not OSF.
| {{error-page | ||
| label='Forbidden' | ||
| translateKey='page-forbidden' | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really like this!
| const sectionFooter = '\n## /EMBER-PREPRINTS ##'; | ||
| const rgx = new RegExp(`(?:${sectionHeader})(.|\\s)*(?:${sectionFooter})`, 'm'); | ||
| const domainProviders = providers | ||
| .slice(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throughout this PR, there seems to be a lot of providers.slice(1). Is there any use for a separate config var that defines non-OSF providers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to avoid modifying the original config too much, which would have downstream changes--not ideal, but neither is creating a ton of merge conflicts if it can be avoided.
|
Functional testing looked good, although I was unable to test the redirect from |
|
Also, after reading through this, not really a request for a change, but a quick note for both future development and potential refactoring: our usage of the word |
|
I got set up locally and updated my osf.io PR. I would like avoid updating that again until we're serious about merging, because it needs a migration. My local copy is redirecting, so I'm not sure what's causing it to not redirect. It could be a container sync issue. I would like to come up with better semantics for provider. At this point, we've been using it in branded preprints since that was launched, so a refactor would need to be planned out. |
|
I think in the OSF world, a |
|
I'm not aware of any, but it would good to codify that somwhere |
See the spec for details.
Companion to:
Ticket
https://openscience.atlassian.net/browse/EOSF-327
TODO:
/preprints/:provider/:whateverredirect toprovider.domain/:whateverNotes for Reviewers:
If testing this PR without the changes from OSF, set environment variable
ENABLE_PROVIDER_DOMAINS='true'See the README section on how to populate the domains locally. The domains are defined in the ember config (config/environment.js). TLDR:
sudo ./scripts/add-domains.jsNotes for QA