-
Notifications
You must be signed in to change notification settings - Fork 56
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
[ENG-4760] User secondary metadata #2031
[ENG-4760] User secondary metadata #2031
Conversation
const osfId = ids.find(id => id['@value'].includes(osfUrl))?.['@value']; | ||
if (osfId) { | ||
// remove osfUrl from id and any leading/trailing slashes | ||
return osfId.replace(osfUrl, '').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.
This feels like a fragile way of fetching the user guid. Any thoughts/feedback on this would be appreciated!
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.
would recommend startsWith
(instead of includes
) and slice
(instead of replace
), so the operation is anchored at the start of the string
for (const iri of ids.map(id => id['@value'])) {
if (iri && iri.startsWith(osfUrl)) {
return iri.slice(osfUrl.length).replace(/^\/|\/$/g, '');
}
}
(does this happen other places? in backend code using IRIs as data, this sort of thing was common enough to warrant shared utility functions)
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 suppose this could be done fairly simply with the URL object type by doing something like
for (const iri of irisArray ) {
const url = new URL(iri);
if (url.host === osfUrl) {
return url.pathname.slice(1); // remove leading slash. Could also be slice(1,6)??
}
}
Although this approach feels a bit too naive to make into a generalized util function
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 you want to compare hosts, yeah the built-in URL
seems better than parsing it yourself (tho you'd also need to extract the host from osfUrl
, since it's a full url) -- at the moment i'm more a fan of the primitive startswith/slice approach for iris within namespaces (one way to look at osf-id (osf-guid)), tho there's also the complication of osf-urls that are not osf-ids but are still used as identifiers...
for (const iri of ids.map(id => id['@value'])) {
if (iri && iri.startsWith(osfUrl)) {
const pathSegments = iri.slice(osfUrl.length).split('/').filter(Boolean);
if (pathSegments.length === 1) {
return pathSegments[0]; // one path segment; looks like osf-id
}
}
}
or using URL
and comparing hosts:
const osfHost = new URL(osfUrl).host;
for (const iri of ids.map(id => new URL(id['@value']))) {
if (iri.host === osfHost) {
const pathSegments = iri.pathname.split('/').filter(Boolean);
if (pathSegments.length === 1) {
return pathSegments[0]; // one path segment; looks like osf-id
}
}
}
(the two would have different behavior if there were ever an osfUrl
that had a non-empty path, which might be a nice future to aim for (supporting folks who want to deploy an instance at a subroute under their own domain) but is not the present we're in)
buuuut in any case, maybe the eventual helpful reusable thing would be a method on IndexCardModel
to extract an osf-id from this.resourceIdentifier
and/or this.resourceMetadata.identifier
(and maybe another method to fetch the ember-data model instance for it) -- no pressure to add that now, tho
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 would not have caught the subtle difference in these two approaches. I'll opt for the first one that uses startsWith
, as I think there may be some cases where the pathname
approach may cause problems. Will add this guid-extration method and a fetchOsfModel
, as I think that would be handy for possible future improvements
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.
Code looks good, but it doesn't look like the mockups. I'm guessing this is because of the data list? Can it be formatted to look like the mockups? If not, have you discussed that with Product?
Pull Request Test Coverage Report for Build 6591621712
💛 - Coveralls |
Just so we are talking about the same thing, do you mean that the title and description are too far apart? I noticed that and I can update the styles so they're closer together. We have opted not to use the mocks where some fields are on the same line (mocks here) |
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.
It was the stuff on the same line that I was talking about. If you've decided as a group not to do that, I'm good.
const osfId = ids.find(id => id['@value'].includes(osfUrl))?.['@value']; | ||
if (osfId) { | ||
// remove osfUrl from id and any leading/trailing slashes | ||
return osfId.replace(osfUrl, '').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.
would recommend startsWith
(instead of includes
) and slice
(instead of replace
), so the operation is anchored at the start of the string
for (const iri of ids.map(id => id['@value'])) {
if (iri && iri.startsWith(osfUrl)) {
return iri.slice(osfUrl.length).replace(/^\/|\/$/g, '');
}
}
(does this happen other places? in backend code using IRIs as data, this sort of thing was common enough to warrant shared utility functions)
lib/osf-components/addon/components/search-result-card/template.hbs
Outdated
Show resolved
Hide resolved
lib/osf-components/addon/components/search-result-card/component.ts
Outdated
Show resolved
Hide resolved
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.
One question, but it's fine if that's what we're doing.
{{#if this.user.employment.length}} | ||
<dt>{{t 'osf-components.search-result-card.employment'}}</dt> | ||
<dd>{{this.user.employment.[0].institution}}</dd> | ||
{{/if}} | ||
{{#if this.user.education.length}} | ||
<dt>{{t 'osf-components.search-result-card.education'}}</dt> | ||
<dd>{{this.user.education.[0].institution}}</dd> |
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.
Are we only doing the latest education/employment, rather than all of them or the one marked 'current'?
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.
Yea, I spoke with Eric, and he wants just the latest one, or more accurately, whichever one the users put at the top of the list
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.
Yea, I spoke with Eric, and he wants just the latest one, or more accurately, whichever one the users put at the top of the list
<CpPanel local-class='cp-panel' id={{secondaryMetadataPanelId}} @open={{this.isOpenSecondaryMetadata}} as |panel|> | ||
<panel.body> | ||
<hr> | ||
{{component this.secondaryMetadataComponent result=@result}} | ||
</panel.body> | ||
</CpPanel> | ||
{{component this.secondaryMetadataComponent | ||
wrapperClass=(local-class 'cp-panel') | ||
wrapperId=secondaryMetadataPanelId | ||
result=@result | ||
isOpen=this.isOpenSecondaryMetadata | ||
}} |
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 gather that <CpPanel>
was moved inside each secondaryMetadatComponent
so that user-secondary-metadata
knows when it's toggled and can fetch the user, but now there's duplicate <CpPanel>
invocations and a more complicated shared interface -- instead, could user-secondary-metadata
start fetching the user from its constructor
? (or is it bad practice to start tasks from constructor
? been a while)
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.
Yea, this refactor took a little bit of doing. I had to move the <CpPanel>
into the secondaryMetadata components, since the component would be destroyed every time the card was expaneded/closed if the <CpPanel>
lived on the parent search-result-card
component. If we tied the user fetching to the constructor
of the secondaryMetadataComponent, it would result in fetching the user every time the card is expanded (if the <CpPanel>
stays on the parent search-result-card component), or the search-result card is rendered. (Nothing inherently wrong with a task being associated with the constructor I think, but in this case, the component will get construct
ed a lot more frequently). Also ran into trouble using splattributes on the secondaryMetadataComponents when invoking it using the {{component}}
helper which was interesting
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.
just a lil nitpick
lib/osf-components/addon/components/search-result-card/user-secondary-metadata/component.ts
Outdated
Show resolved
Hide resolved
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.
🤺
Purpose
Summary of Changes
dt
anddd
are closerScreenshot(s)
Loading state
Loaded
other result cards (note bolded title and values are closer together)
Side Effects
QA Notes