Skip to content

Commit 3dd3afa

Browse files
authored
Merge pull request #2757 from ORCID/lmendoza/PD-5079
PD-5079
2 parents b0a1dfd + 5639c2a commit 3dd3afa

7 files changed

Lines changed: 85 additions & 18 deletions

File tree

projects/orcid-registry-ui/src/lib/components/import-works-dialog/import-works-dialog.component.html

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,7 @@
7272
*ngFor="let link of certifiedLinks"
7373
class="import-works-dialog__card import-works-dialog__card--certified"
7474
>
75-
<div
76-
class="import-works-dialog__card-icon"
77-
*ngIf="link.imageUrl || link.icon"
78-
>
75+
<div class="import-works-dialog__card-icon">
7976
<img
8077
*ngIf="link.imageUrl"
8178
[src]="link.imageUrl"
@@ -87,6 +84,18 @@
8784
[attr.aria-hidden]="true"
8885
>{{ link.icon }}</mat-icon
8986
>
87+
<ng-container *ngIf="!link.imageUrl && !link.icon">
88+
<img
89+
*ngIf="placeholderIconUrl"
90+
[src]="placeholderIconUrl"
91+
alt=""
92+
class="import-works-dialog__card-img import-works-dialog__card-img--placeholder"
93+
aria-hidden="true"
94+
/>
95+
<mat-icon *ngIf="!placeholderIconUrl" [attr.aria-hidden]="true"
96+
>link</mat-icon
97+
>
98+
</ng-container>
9099
</div>
91100
<div class="import-works-dialog__card-content">
92101
<p class="import-works-dialog__card-title">{{ link.name }}</p>
@@ -130,7 +139,12 @@
130139
aria-labelledby="import-works-more-heading"
131140
*ngIf="loading || moreServicesLinks.length"
132141
>
133-
<div class="import-works-dialog__more-panel">
142+
<div
143+
class="import-works-dialog__more-panel"
144+
[class.import-works-dialog__more-panel--collapsed]="
145+
!moreServicesExpanded
146+
"
147+
>
134148
<div
135149
class="import-works-dialog__more-header"
136150
(click)="toggleMoreServices()"

projects/orcid-registry-ui/src/lib/components/import-works-dialog/import-works-dialog.component.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@
118118
width: 48px;
119119
height: 48px;
120120
object-fit: contain;
121+
122+
&--placeholder {
123+
object-fit: contain;
124+
}
121125
}
122126

123127
mat-icon {
@@ -239,6 +243,10 @@
239243
border-bottom: 1px solid var(--orcid-ui-background-light, #eeeeee);
240244
border-radius: var(--orcid-space-1, 4px);
241245
overflow: hidden;
246+
247+
&--collapsed {
248+
border-bottom: none;
249+
}
242250
}
243251

244252
.import-works-dialog__more-header {

projects/orcid-registry-ui/src/lib/components/import-works-dialog/import-works-dialog.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ export class ImportWorksDialogComponent {
126126
return this.data?.moreServicesLinks ?? []
127127
}
128128

129+
/** URL for the placeholder icon when a service has no imageUrl or icon. */
130+
get placeholderIconUrl(): string | undefined {
131+
return this.data?.placeholderIconUrl
132+
}
133+
129134
openInNewTab(url: string): void {
130135
if (url) {
131136
window.open(url, '_blank', 'noopener,noreferrer')

projects/orcid-registry-ui/src/lib/components/import-works-dialog/import-works-dialog.types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,9 @@ export interface ImportWorksDialogData {
6767
certifiedLinks: ImportWorksCertifiedLink[]
6868
/** Ordered list of links shown under the more services heading. */
6969
moreServicesLinks: ImportWorksMoreLink[]
70+
/**
71+
* Optional URL for the placeholder icon shown when a service has no imageUrl or icon
72+
* (e.g. assets/vectors/CSPs/csp-placeholder.svg).
73+
*/
74+
placeholderIconUrl?: string
7075
}

src/app/core/record-works/record-works.service.spec.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,18 @@ describe('RecordWorksService', () => {
150150
done()
151151
})
152152

153-
const req = httpTestingController.expectOne(
153+
const wizardReq = httpTestingController.expectOne(
154154
runtimeEnvironment.API_WEB +
155155
'workspace/retrieve-works-search-and-link-wizard.json'
156156
)
157-
expect(req.request.method).toBe('GET')
158-
req.flush(listPayload)
157+
expect(wizardReq.request.method).toBe('GET')
158+
wizardReq.flush(listPayload)
159+
160+
// Service also requests localize .properties when CERTIFIED_LINKS_LOCALIZE_BASE_URL is set
161+
const localizeReqs = httpTestingController.match((req) =>
162+
req.url.includes('works-search-and-link') && req.url.endsWith('.properties')
163+
)
164+
localizeReqs.forEach((r) => r.flush(''))
159165
})
160166

161167
it('returns empty certified and more lists when API returns empty array', (done) => {
@@ -166,11 +172,16 @@ describe('RecordWorksService', () => {
166172
done()
167173
})
168174

169-
const req = httpTestingController.expectOne(
175+
const wizardReq = httpTestingController.expectOne(
170176
runtimeEnvironment.API_WEB +
171177
'workspace/retrieve-works-search-and-link-wizard.json'
172178
)
173-
req.flush([])
179+
wizardReq.flush([])
180+
181+
const localizeReqs = httpTestingController.match((req) =>
182+
req.url.includes('works-search-and-link') && req.url.endsWith('.properties')
183+
)
184+
localizeReqs.forEach((r) => r.flush(''))
174185
})
175186
})
176187
})

src/app/core/record-works/record-works.service.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ export class RecordWorksService {
614614
connectedAriaLabelTemplate: $localize`:@@works.connectedWithCsp:Connected with {{name}}`,
615615
certifiedLinks,
616616
moreServicesLinks,
617+
placeholderIconUrl: 'assets/vectors/CSPs/csp-placeholder.svg',
617618
}
618619
}
619620

@@ -645,7 +646,10 @@ export class RecordWorksService {
645646
return forkJoin({ list: list$, localize: localize$ }).pipe(
646647
map(({ list, localize }) => {
647648
const localizeByClientId = this._parsePropertiesFile(localize)
648-
const certifiedLinks: ImportWorksCertifiedLink[] = []
649+
const certifiedForList: Array<{
650+
link: ImportWorksCertifiedLink
651+
index: number
652+
}> = []
649653
const featuredForMore: Array<{
650654
link: ImportWorksMoreLink
651655
index: number
@@ -663,20 +667,29 @@ export class RecordWorksService {
663667
scopes,
664668
redirectUri
665669
)
666-
const imageUrl = item.redirectUriMetadata?.logoUrl
670+
// Backend returns redirectUriMetadata from DB as-is; logoUrl may be absent (Certified can have no logo)
671+
const rawLogoUrl = item.redirectUriMetadata?.logoUrl
672+
const imageUrl =
673+
typeof rawLogoUrl === 'string' && rawLogoUrl.trim() !== ''
674+
? rawLogoUrl.trim()
675+
: undefined
667676

668677
if (type === 'Certified') {
669678
const description =
670679
localizeByClientId[`${item.id}-client-description`] ??
671680
localizeByClientId[item.id] ??
672681
item.redirectUriMetadata?.defaultDescription ??
673682
''
674-
certifiedLinks.push({
675-
name,
676-
description,
677-
url: oauthUrl,
678-
connected,
679-
imageUrl,
683+
const index = item.redirectUriMetadata?.index ?? 999
684+
certifiedForList.push({
685+
link: {
686+
name,
687+
description,
688+
url: oauthUrl,
689+
connected,
690+
imageUrl,
691+
},
692+
index,
680693
})
681694
} else if (type === 'Featured') {
682695
const description =
@@ -695,7 +708,15 @@ export class RecordWorksService {
695708
}
696709
}
697710

711+
certifiedForList.sort((a, b) => a.index - b.index)
712+
const certifiedLinks: ImportWorksCertifiedLink[] = certifiedForList.map(
713+
(x) => x.link
714+
)
715+
698716
featuredForMore.sort((a, b) => a.index - b.index)
717+
defaultForMore.sort((a, b) =>
718+
a.name.localeCompare(b.name, undefined, { sensitivity: 'base' })
719+
)
699720
const moreServicesLinks: ImportWorksMoreLink[] = [
700721
...featuredForMore.map((x) => x.link),
701722
...defaultForMore,
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)