geonetwork-ui 2.6.0-dev.502fa026d → 2.6.0-dev.b306f1194
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/libs/common/domain/src/lib/model/record/metadata.model.mjs +1 -1
- package/esm2022/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.mjs +3 -3
- package/esm2022/libs/ui/elements/src/index.mjs +2 -1
- package/esm2022/libs/ui/elements/src/lib/api-card/api-card.component.mjs +27 -6
- package/esm2022/libs/ui/elements/src/lib/download-item/download-item.component.mjs +22 -6
- package/esm2022/libs/ui/elements/src/lib/downloads-list/downloads-list.component.mjs +3 -3
- package/esm2022/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.mjs +163 -0
- package/esm2022/libs/ui/elements/src/lib/link-card/link-card.component.mjs +29 -7
- package/esm2022/libs/ui/elements/src/lib/metadata-catalog/metadata-catalog.component.mjs +3 -3
- package/esm2022/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.mjs +3 -3
- package/esm2022/libs/ui/elements/src/lib/record-api-form/record-api-form.component.mjs +3 -2
- package/esm2022/libs/ui/elements/src/lib/ui-elements.module.mjs +10 -4
- package/esm2022/libs/ui/layout/src/lib/carousel/carousel.component.mjs +3 -3
- package/esm2022/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.mjs +3 -3
- package/esm2022/libs/util/shared/src/lib/links/link-utils.mjs +21 -19
- package/esm2022/translations/de.json +7 -0
- package/esm2022/translations/en.json +8 -1
- package/esm2022/translations/es.json +7 -0
- package/esm2022/translations/fr.json +7 -0
- package/esm2022/translations/it.json +7 -1
- package/esm2022/translations/nl.json +7 -0
- package/esm2022/translations/pt.json +7 -0
- package/fesm2022/geonetwork-ui.mjs +315 -55
- package/fesm2022/geonetwork-ui.mjs.map +1 -1
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts +1 -0
- package/libs/common/domain/src/lib/model/record/metadata.model.d.ts.map +1 -1
- package/libs/ui/elements/src/index.d.ts +1 -0
- package/libs/ui/elements/src/index.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/api-card/api-card.component.d.ts +9 -1
- package/libs/ui/elements/src/lib/api-card/api-card.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/download-item/download-item.component.d.ts +8 -1
- package/libs/ui/elements/src/lib/download-item/download-item.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts +43 -0
- package/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.d.ts.map +1 -0
- package/libs/ui/elements/src/lib/link-card/link-card.component.d.ts +10 -2
- package/libs/ui/elements/src/lib/link-card/link-card.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/record-api-form/record-api-form.component.d.ts.map +1 -1
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts +2 -1
- package/libs/ui/elements/src/lib/ui-elements.module.d.ts.map +1 -1
- package/libs/util/shared/src/lib/links/link-utils.d.ts +16 -16
- package/libs/util/shared/src/lib/links/link-utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/libs/common/domain/src/lib/model/record/metadata.model.ts +1 -0
- package/src/libs/feature/search/src/lib/favorites/favorite-star/favorite-star.component.html +1 -1
- package/src/libs/ui/elements/src/index.ts +1 -0
- package/src/libs/ui/elements/src/lib/api-card/api-card.component.html +64 -38
- package/src/libs/ui/elements/src/lib/api-card/api-card.component.ts +26 -2
- package/src/libs/ui/elements/src/lib/download-item/download-item.component.html +17 -17
- package/src/libs/ui/elements/src/lib/download-item/download-item.component.ts +20 -2
- package/src/libs/ui/elements/src/lib/downloads-list/downloads-list.component.html +7 -6
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.css +0 -0
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.html +156 -0
- package/src/libs/ui/elements/src/lib/internal-link-card/internal-link-card.component.ts +190 -0
- package/src/libs/ui/elements/src/lib/link-card/link-card.component.html +27 -29
- package/src/libs/ui/elements/src/lib/link-card/link-card.component.ts +33 -3
- package/src/libs/ui/elements/src/lib/metadata-catalog/metadata-catalog.component.html +1 -1
- package/src/libs/ui/elements/src/lib/metadata-quality/metadata-quality.component.html +4 -2
- package/src/libs/ui/elements/src/lib/record-api-form/record-api-form.component.ts +2 -1
- package/src/libs/ui/elements/src/lib/ui-elements.module.ts +3 -0
- package/src/libs/ui/layout/src/lib/carousel/carousel.component.css +0 -4
- package/src/libs/ui/widgets/src/lib/progress-bar/progress-bar.component.html +2 -2
- package/src/libs/util/shared/src/lib/links/link-utils.ts +20 -18
- package/tailwind.base.css +34 -1
- package/translations/de.json +7 -0
- package/translations/en.json +8 -1
- package/translations/es.json +7 -0
- package/translations/fr.json +7 -0
- package/translations/it.json +7 -1
- package/translations/nl.json +7 -0
- package/translations/pt.json +7 -0
- package/translations/sk.json +7 -0
|
@@ -9,7 +9,9 @@ import { DatasetOnlineResource } from '../../../../../../libs/common/domain/src/
|
|
|
9
9
|
import { TranslateModule } from '@ngx-translate/core'
|
|
10
10
|
import { CommonModule } from '@angular/common'
|
|
11
11
|
import { NgIcon, provideIcons } from '@ng-icons/core'
|
|
12
|
-
import {
|
|
12
|
+
import { iconoirDownload } from '@ng-icons/iconoir'
|
|
13
|
+
|
|
14
|
+
type CardSize = 'L' | 'M' | 'S' | 'XS'
|
|
13
15
|
|
|
14
16
|
@Component({
|
|
15
17
|
selector: 'gn-ui-download-item',
|
|
@@ -20,15 +22,31 @@ import { matCloudDownloadOutline } from '@ng-icons/material-icons/outline'
|
|
|
20
22
|
standalone: true,
|
|
21
23
|
viewProviders: [
|
|
22
24
|
provideIcons({
|
|
23
|
-
|
|
25
|
+
iconoirDownload,
|
|
24
26
|
}),
|
|
25
27
|
],
|
|
26
28
|
})
|
|
27
29
|
export class DownloadItemComponent {
|
|
30
|
+
private _size: 'L' | 'M' | 'S' | 'XS'
|
|
28
31
|
@Input() link: DatasetOnlineResource
|
|
29
32
|
@Input() color: string
|
|
30
33
|
@Input() format: string
|
|
31
34
|
@Input() isFromApi: boolean
|
|
35
|
+
private readonly sizeClassMap: Record<CardSize, string> = {
|
|
36
|
+
L: 'gn-ui-card-l py-2 px-5',
|
|
37
|
+
M: 'gn-ui-card-m py-2 px-5',
|
|
38
|
+
S: 'gn-ui-card-s p-4',
|
|
39
|
+
XS: 'gn-ui-card-xs py-2 px-5',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Input() set size(value: CardSize) {
|
|
43
|
+
this._size = value
|
|
44
|
+
this.cardClass = this.sizeClassMap[value]
|
|
45
|
+
}
|
|
46
|
+
get size(): 'L' | 'M' | 'S' | 'XS' {
|
|
47
|
+
return this._size
|
|
48
|
+
}
|
|
49
|
+
cardClass = ''
|
|
32
50
|
@Output() exportUrl = new EventEmitter<string>()
|
|
33
51
|
|
|
34
52
|
openUrl() {
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
<div
|
|
2
|
-
class="flex flex-wrap justify-between
|
|
2
|
+
class="flex flex-wrap justify-between items-center pb-4"
|
|
3
3
|
*ngIf="links && links.length > 0"
|
|
4
4
|
>
|
|
5
|
-
<
|
|
6
|
-
class="font-title text-
|
|
5
|
+
<div
|
|
6
|
+
class="font-title text-xl text-title font-medium mr-4 text-center sm:text-left"
|
|
7
7
|
translate
|
|
8
8
|
>
|
|
9
9
|
record.metadata.download
|
|
10
|
-
</
|
|
10
|
+
</div>
|
|
11
11
|
<div
|
|
12
|
-
class="flex flex-wrap justify-start sm:justify-end
|
|
12
|
+
class="flex flex-wrap justify-start sm:justify-end"
|
|
13
13
|
data-cy="download-format-filters"
|
|
14
14
|
>
|
|
15
15
|
<gn-ui-button
|
|
16
16
|
class="m-1 format-filter"
|
|
17
17
|
[extraClass]="
|
|
18
18
|
'!px-[12px] !py-[8px] !text-[15px]' +
|
|
19
|
-
(isFilterActive(format) ? ' opacity-100' : ' opacity-
|
|
19
|
+
(isFilterActive(format) ? ' opacity-100' : ' opacity-60')
|
|
20
20
|
"
|
|
21
21
|
(buttonClick)="toggleFilterFormat(format)"
|
|
22
22
|
[attr.data-format]="format"
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
</div>
|
|
29
29
|
<div class="mb-2 sm:mb-3" *ngFor="let link of filteredLinks">
|
|
30
30
|
<gn-ui-download-item
|
|
31
|
+
size="L"
|
|
31
32
|
[link]="link"
|
|
32
33
|
[color]="getLinkColor(link)"
|
|
33
34
|
[format]="getLinkFormat(link)"
|
|
File without changes
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class="rounded-lg group card-shadow cursor-pointer overflow-hidden hover:bg-gray-50"
|
|
3
|
+
[ngClass]="cardClass"
|
|
4
|
+
>
|
|
5
|
+
<div class="flex flex-row justify-between w-full">
|
|
6
|
+
<div
|
|
7
|
+
*ngIf="shouldShowThumbnail"
|
|
8
|
+
[ngClass]="thumbnailContainerClass"
|
|
9
|
+
class="mr-4 flex flex-col"
|
|
10
|
+
>
|
|
11
|
+
<gn-ui-thumbnail
|
|
12
|
+
class="w-full h-full object-cover"
|
|
13
|
+
[thumbnailUrl]="record.overviews?.[0]?.url?.toString() || ''"
|
|
14
|
+
[fit]="'cover'"
|
|
15
|
+
></gn-ui-thumbnail>
|
|
16
|
+
</div>
|
|
17
|
+
<div
|
|
18
|
+
class="flex flex-col flex-1 relative"
|
|
19
|
+
[ngClass]="{
|
|
20
|
+
'justify-between': record.ownerOrganization?.name && size !== 'XS',
|
|
21
|
+
}"
|
|
22
|
+
>
|
|
23
|
+
<div class="flex items-center space-x-2">
|
|
24
|
+
<span
|
|
25
|
+
*ngIf="getKindInfo().text"
|
|
26
|
+
class="badge-btn text-white text-xs px-2 py-0.5 font-bold shrink-0 bg-primary leading-tight flex items-center justify-evenly h-6 min-h-6"
|
|
27
|
+
>
|
|
28
|
+
<ng-icon
|
|
29
|
+
class="text-[0.9em] text-white mr-1"
|
|
30
|
+
[name]="getKindInfo().icon"
|
|
31
|
+
></ng-icon>
|
|
32
|
+
<span class="font-medium text-white text-xs" translate>
|
|
33
|
+
{{ getKindInfo().text }}
|
|
34
|
+
</span>
|
|
35
|
+
</span>
|
|
36
|
+
<span
|
|
37
|
+
*ngIf="isGeodata"
|
|
38
|
+
class="badge-btn text-black text-xs px-2 py-0.5 font-bold shrink-0 bg-primary-white leading-tight flex items-center justify-evenly h-6 min-h-6"
|
|
39
|
+
[ngClass]="size === 'L' ? 'w-[164px]' : 'w-8'"
|
|
40
|
+
>
|
|
41
|
+
<ng-icon
|
|
42
|
+
class="text-[0.9em] text-primary-darkest"
|
|
43
|
+
name="matLocationSearchingOutline"
|
|
44
|
+
></ng-icon>
|
|
45
|
+
<ng-container *ngIf="size === 'L'">
|
|
46
|
+
<span
|
|
47
|
+
class="font-medium text-primary-darkest text-xs ml-1"
|
|
48
|
+
translate
|
|
49
|
+
>
|
|
50
|
+
record.metadata.type
|
|
51
|
+
</span>
|
|
52
|
+
</ng-container>
|
|
53
|
+
</span>
|
|
54
|
+
<div class="flex items-center">
|
|
55
|
+
<gn-ui-metadata-quality
|
|
56
|
+
[smaller]="true"
|
|
57
|
+
[metadata]="record"
|
|
58
|
+
[metadataQualityDisplay]="metadataQualityDisplay"
|
|
59
|
+
></gn-ui-metadata-quality>
|
|
60
|
+
</div>
|
|
61
|
+
<div class="absolute top-0 right-0 items-center">
|
|
62
|
+
<ng-container
|
|
63
|
+
*ngIf="size !== 'XS'"
|
|
64
|
+
[ngTemplateOutlet]="favoriteTemplate"
|
|
65
|
+
[ngTemplateOutletContext]="{ $implicit: record }"
|
|
66
|
+
></ng-container>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
<div
|
|
70
|
+
class="font-medium text-title group-hover:text-primary overflow-hidden break-words"
|
|
71
|
+
[ngClass]="getTitleClass()"
|
|
72
|
+
>
|
|
73
|
+
{{ record.title }}
|
|
74
|
+
</div>
|
|
75
|
+
<div
|
|
76
|
+
*ngIf="size === 'L'"
|
|
77
|
+
class="mt-1 mb-2 font-normal text-xs text-gray-900 line-clamp-2 overflow-hidden"
|
|
78
|
+
>
|
|
79
|
+
<gn-ui-markdown-parser
|
|
80
|
+
[textContent]="abstract"
|
|
81
|
+
[whitoutStyles]="true"
|
|
82
|
+
></gn-ui-markdown-parser>
|
|
83
|
+
</div>
|
|
84
|
+
<div
|
|
85
|
+
*ngIf="size !== 'XS' && record.ownerOrganization?.name"
|
|
86
|
+
class="flex items-center justify-evenly bg-gray-50 rounded-lg h-[53px] px-2"
|
|
87
|
+
>
|
|
88
|
+
<div class="flex items-center flex-1 min-w-0">
|
|
89
|
+
<div
|
|
90
|
+
class="w-[45px] h-[45px] rounded-lg overflow-hidden shrink-0 mr-3"
|
|
91
|
+
>
|
|
92
|
+
<gn-ui-thumbnail
|
|
93
|
+
[thumbnailUrl]="
|
|
94
|
+
record.ownerOrganization?.logoUrl?.toString() || ''
|
|
95
|
+
"
|
|
96
|
+
[fit]="'contain'"
|
|
97
|
+
class="w-full h-full rounded-lg"
|
|
98
|
+
></gn-ui-thumbnail>
|
|
99
|
+
</div>
|
|
100
|
+
<div *ngIf="organization?.name" class="flex-1 w-0 overflow-hidden">
|
|
101
|
+
<div
|
|
102
|
+
class="text-xs text-black font-normal leading-tight truncate"
|
|
103
|
+
translate
|
|
104
|
+
>
|
|
105
|
+
record.card.metadata.contact
|
|
106
|
+
</div>
|
|
107
|
+
<div class="text-xl text-primary-black font-medium truncate">
|
|
108
|
+
{{ organization.name }}
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
<div *ngIf="size === 'L'" class="ml-2 flex space-x-2">
|
|
113
|
+
<div *ngIf="organization?.website" class="flex">
|
|
114
|
+
<button
|
|
115
|
+
[title]="organization.website"
|
|
116
|
+
class="w-[40px] h-[32px] flex items-center justify-center rounded-lg border border-[#D4D3D7] px-[8px] py-[4px] hover:bg-primary-lightest"
|
|
117
|
+
(click)="openExternalUrl($event, organization.website)"
|
|
118
|
+
>
|
|
119
|
+
<ng-icon name="iconoirInternet"></ng-icon>
|
|
120
|
+
</button>
|
|
121
|
+
</div>
|
|
122
|
+
<div *ngIf="contacts[0]?.email" class="flex">
|
|
123
|
+
<button
|
|
124
|
+
[title]="contacts[0].email"
|
|
125
|
+
class="w-[40px] h-[32px] flex items-center justify-center rounded-lg border border-[#D4D3D7] px-[8px] py-[4px] hover:bg-primary-lightest"
|
|
126
|
+
data-cy="contact-email"
|
|
127
|
+
(click)="openMailto($event, contacts[0].email)"
|
|
128
|
+
>
|
|
129
|
+
<ng-icon name="matEmailOutline"></ng-icon>
|
|
130
|
+
</button>
|
|
131
|
+
</div>
|
|
132
|
+
<div *ngIf="contacts[0]?.phone" class="flex">
|
|
133
|
+
<button
|
|
134
|
+
[title]="'Copy to clipboard'"
|
|
135
|
+
class="w-[40px] h-[32px] flex items-center justify-center rounded-lg border border-[#D4D3D7] px-[8px] py-[4px] hover:bg-primary-lightest relative group"
|
|
136
|
+
data-cy="contact-phone"
|
|
137
|
+
(click)="copyToClipboard($event, contacts[0].phone)"
|
|
138
|
+
>
|
|
139
|
+
<ng-icon name="matPhoneOutline"></ng-icon>
|
|
140
|
+
</button>
|
|
141
|
+
</div>
|
|
142
|
+
<div *ngIf="contacts[0]?.address" class="flex">
|
|
143
|
+
<button
|
|
144
|
+
[title]="'Copy to clipboard'"
|
|
145
|
+
class="w-[40px] h-[32px] flex items-center justify-center rounded-lg border border-[#D4D3D7] px-[8px] py-[4px] hover:bg-primary-lightest relative group"
|
|
146
|
+
data-cy="contact-phone"
|
|
147
|
+
(click)="copyToClipboard($event, contacts[0].address)"
|
|
148
|
+
>
|
|
149
|
+
<ng-icon name="matLocationOnOutline"></ng-icon>
|
|
150
|
+
</button>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
Input,
|
|
4
|
+
TemplateRef,
|
|
5
|
+
OnInit,
|
|
6
|
+
Output,
|
|
7
|
+
EventEmitter,
|
|
8
|
+
ElementRef,
|
|
9
|
+
} from '@angular/core'
|
|
10
|
+
import {
|
|
11
|
+
CatalogRecord,
|
|
12
|
+
Organization,
|
|
13
|
+
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
14
|
+
import { NgClass, NgIf, NgTemplateOutlet } from '@angular/common'
|
|
15
|
+
import { MarkdownParserComponent } from '../markdown-parser/markdown-parser.component'
|
|
16
|
+
import { MetadataQualityComponent } from '../metadata-quality/metadata-quality.component'
|
|
17
|
+
import { ThumbnailComponent } from '../thumbnail/thumbnail.component'
|
|
18
|
+
import {
|
|
19
|
+
propagateToDocumentOnly,
|
|
20
|
+
removeWhitespace,
|
|
21
|
+
stripHtml,
|
|
22
|
+
} from '../../../../../../libs/util/shared/src'
|
|
23
|
+
import {
|
|
24
|
+
NgIconComponent,
|
|
25
|
+
provideIcons,
|
|
26
|
+
provideNgIconsConfig,
|
|
27
|
+
} from '@ng-icons/core'
|
|
28
|
+
import {
|
|
29
|
+
matLocationSearchingOutline,
|
|
30
|
+
matEmailOutline,
|
|
31
|
+
matPhoneOutline,
|
|
32
|
+
matLocationOnOutline,
|
|
33
|
+
} from '@ng-icons/material-icons/outline'
|
|
34
|
+
import { matCode } from '@ng-icons/material-icons/baseline'
|
|
35
|
+
import { iconoirDatabase, iconoirMap, iconoirInternet } from '@ng-icons/iconoir'
|
|
36
|
+
import { TranslateModule } from '@ngx-translate/core'
|
|
37
|
+
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
|
|
38
|
+
import { fromEvent, Subscription } from 'rxjs'
|
|
39
|
+
|
|
40
|
+
marker('record.kind.dataset')
|
|
41
|
+
marker('record.kind.reuse')
|
|
42
|
+
marker('record.kind.service')
|
|
43
|
+
|
|
44
|
+
type CardSize = 'L' | 'M' | 'S' | 'XS'
|
|
45
|
+
|
|
46
|
+
@Component({
|
|
47
|
+
selector: 'gn-ui-internal-link-card',
|
|
48
|
+
standalone: true,
|
|
49
|
+
imports: [
|
|
50
|
+
NgClass,
|
|
51
|
+
NgIf,
|
|
52
|
+
ThumbnailComponent,
|
|
53
|
+
MetadataQualityComponent,
|
|
54
|
+
NgTemplateOutlet,
|
|
55
|
+
NgIconComponent,
|
|
56
|
+
TranslateModule,
|
|
57
|
+
MarkdownParserComponent,
|
|
58
|
+
],
|
|
59
|
+
providers: [
|
|
60
|
+
provideIcons({
|
|
61
|
+
matLocationSearchingOutline,
|
|
62
|
+
matCode,
|
|
63
|
+
iconoirDatabase,
|
|
64
|
+
iconoirMap,
|
|
65
|
+
iconoirInternet,
|
|
66
|
+
matEmailOutline,
|
|
67
|
+
matPhoneOutline,
|
|
68
|
+
matLocationOnOutline,
|
|
69
|
+
}),
|
|
70
|
+
provideNgIconsConfig({
|
|
71
|
+
size: '1.2em',
|
|
72
|
+
}),
|
|
73
|
+
],
|
|
74
|
+
templateUrl: './internal-link-card.component.html',
|
|
75
|
+
styleUrls: ['./internal-link-card.component.css'],
|
|
76
|
+
})
|
|
77
|
+
export class InternalLinkCardComponent implements OnInit {
|
|
78
|
+
@Input() record: CatalogRecord
|
|
79
|
+
@Input() metadataQualityDisplay: boolean
|
|
80
|
+
@Input() favoriteTemplate: TemplateRef<{ $implicit: CatalogRecord }>
|
|
81
|
+
@Input() linkHref: string = null
|
|
82
|
+
@Input() isGeodata: boolean
|
|
83
|
+
@Input() set size(value: CardSize) {
|
|
84
|
+
this._size = value
|
|
85
|
+
this.cardClass = this.sizeClassMap[value] || ''
|
|
86
|
+
this.thumbnailContainerClass = this.thumbnailSizeClassMap[value] || 'hidden'
|
|
87
|
+
}
|
|
88
|
+
get size(): CardSize {
|
|
89
|
+
return this._size
|
|
90
|
+
}
|
|
91
|
+
@Output() mdSelect = new EventEmitter<CatalogRecord>()
|
|
92
|
+
subscription = new Subscription()
|
|
93
|
+
|
|
94
|
+
abstract: string
|
|
95
|
+
|
|
96
|
+
cardClass = ''
|
|
97
|
+
thumbnailContainerClass = ''
|
|
98
|
+
|
|
99
|
+
private _size: CardSize = 'M'
|
|
100
|
+
|
|
101
|
+
private readonly sizeClassMap: Record<CardSize, string> = {
|
|
102
|
+
L: 'min-h-[190px] md:w-[992px] py-3 px-3 flex items-start gap-5',
|
|
103
|
+
M: 'min-h-[140px] md:w-[570px] py-3 px-3 flex items-start gap-4',
|
|
104
|
+
S: 'min-h-[220px] md:w-[370px] py-3 px-3 flex gap-4',
|
|
105
|
+
XS: 'min-h-[108px] md:w-[570px] py-3 px-3 flex gap-4',
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private readonly thumbnailSizeClassMap: Record<CardSize, string> = {
|
|
109
|
+
L: 'w-[190px] h-[180px] rounded-lg overflow-hidden shrink-0',
|
|
110
|
+
M: 'w-[110px] h-[140px] rounded-lg overflow-hidden shrink-0',
|
|
111
|
+
S: 'hidden',
|
|
112
|
+
XS: 'hidden',
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private readonly titleClassMap: Record<CardSize, string> = {
|
|
116
|
+
L: 'text-xl line-clamp-2',
|
|
117
|
+
M: 'text-base line-clamp-2',
|
|
118
|
+
S: 'text-base line-clamp-3',
|
|
119
|
+
XS: 'text-base mt-3 line-clamp-2',
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
constructor(protected elementRef: ElementRef) {}
|
|
123
|
+
|
|
124
|
+
ngOnInit(): void {
|
|
125
|
+
this.abstract = removeWhitespace(stripHtml(this.record?.abstract))
|
|
126
|
+
this.subscription.add(
|
|
127
|
+
fromEvent(this.elementRef.nativeElement, 'click').subscribe(
|
|
128
|
+
(event: Event) => {
|
|
129
|
+
event.preventDefault()
|
|
130
|
+
propagateToDocumentOnly(event)
|
|
131
|
+
this.mdSelect.emit(this.record)
|
|
132
|
+
}
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
get organization(): Organization {
|
|
138
|
+
return this.record.ownerOrganization
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
get contacts() {
|
|
142
|
+
return (
|
|
143
|
+
(this.record.kind === 'dataset'
|
|
144
|
+
? this.record.contactsForResource
|
|
145
|
+
: this.record.contacts) || []
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getTitleClass() {
|
|
150
|
+
return (
|
|
151
|
+
this.titleClassMap[this._size] +
|
|
152
|
+
' ' +
|
|
153
|
+
(this.record.ownerOrganization?.name ? '' : 'mt-3') || ''
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
openExternalUrl(event: Event, url: URL): void {
|
|
158
|
+
event.stopPropagation()
|
|
159
|
+
window.open(url, '_blank')
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
openMailto(event: Event, email: string): void {
|
|
163
|
+
event.stopPropagation()
|
|
164
|
+
window.open(`mailto:${email}`, '_blank')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
copyToClipboard(event: Event, text: string): void {
|
|
168
|
+
event.stopPropagation()
|
|
169
|
+
navigator.clipboard.writeText(text)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get shouldShowThumbnail(): boolean {
|
|
173
|
+
return this.size === 'L' || this.size === 'M'
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
getKindInfo(): { text: string; icon: string } {
|
|
177
|
+
if (!this.record?.kind) return { text: '', icon: '' }
|
|
178
|
+
|
|
179
|
+
switch (this.record.kind.toLowerCase()) {
|
|
180
|
+
case 'dataset':
|
|
181
|
+
return { text: 'record.kind.dataset', icon: 'iconoirDatabase' }
|
|
182
|
+
case 'reuse':
|
|
183
|
+
return { text: 'record.kind.reuse', icon: 'iconoirMap' }
|
|
184
|
+
case 'service':
|
|
185
|
+
return { text: 'record.kind.service', icon: 'matCode' }
|
|
186
|
+
default:
|
|
187
|
+
return { text: '', icon: '' }
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
@@ -1,39 +1,37 @@
|
|
|
1
1
|
<a
|
|
2
2
|
[href]="link.url"
|
|
3
3
|
target="_blank"
|
|
4
|
-
class="flex flex-
|
|
5
|
-
[ngClass]="
|
|
4
|
+
class="group flex flex-row justify-between card-shadow cursor-pointer rounded overflow-hidden"
|
|
5
|
+
[ngClass]="cardClass"
|
|
6
6
|
[title]="title"
|
|
7
7
|
>
|
|
8
|
-
<
|
|
9
|
-
<div class="
|
|
10
|
-
|
|
11
|
-
class="font-title font-medium text-21 text-black break-words mb-1 line-clamp-2"
|
|
12
|
-
>
|
|
13
|
-
{{ link.name }}
|
|
14
|
-
</p>
|
|
15
|
-
<p class="font-medium text-sm break-words">
|
|
16
|
-
{{ link.description }}
|
|
17
|
-
</p>
|
|
18
|
-
<p
|
|
19
|
-
*ngIf="!link.name && !link.description"
|
|
20
|
-
class="font-medium text-sm break-words truncate"
|
|
21
|
-
>
|
|
22
|
-
{{ link.url }}
|
|
23
|
-
</p>
|
|
8
|
+
<div class="flex flex-col justify-between">
|
|
9
|
+
<div class="gn-ui-card-title">
|
|
10
|
+
{{ link.description || link.name }}
|
|
24
11
|
</div>
|
|
25
|
-
<div>
|
|
26
|
-
|
|
12
|
+
<div class="gn-ui-card-detail">
|
|
13
|
+
{{ link.name }}
|
|
27
14
|
</div>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
<p *ngIf="!link.name && !link.description" class="gn-ui-card-title">
|
|
16
|
+
{{ link.url }}
|
|
17
|
+
</p>
|
|
18
|
+
<div class="pt-1">
|
|
19
|
+
<span
|
|
20
|
+
class="inline-flex items-center justify-center px-2 py-1 text-13 font-medium leading-none text-white rounded transition-opacity opacity-70 group-hover:opacity-100"
|
|
21
|
+
[style.background-color]="getLinkColor(link)"
|
|
22
|
+
data-cy="download-format"
|
|
23
|
+
>{{
|
|
24
|
+
getLinkFormat(link) || ('downloads.format.unknown' | translate)
|
|
25
|
+
}}</span
|
|
33
26
|
>
|
|
34
|
-
{{ link.name || link.description }}
|
|
35
|
-
</p>
|
|
36
|
-
<ng-icon class="card-icon flex-shrink-0" name="matOpenInNew"></ng-icon>
|
|
37
27
|
</div>
|
|
38
|
-
</
|
|
28
|
+
</div>
|
|
29
|
+
<div class="flex" [ngClass]="size === 'S' ? 'items-end' : 'items-center'">
|
|
30
|
+
<div class="gn-ui-card-icon">
|
|
31
|
+
<ng-icon
|
|
32
|
+
class="inline-block card-icon align-middle"
|
|
33
|
+
name="matOpenInNew"
|
|
34
|
+
></ng-icon>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
39
37
|
</a>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
DatasetDownloadDistribution,
|
|
4
|
+
DatasetOnlineResource,
|
|
5
|
+
DatasetServiceDistribution,
|
|
6
|
+
} from '../../../../../../libs/common/domain/src/lib/model/record'
|
|
3
7
|
import { CommonModule } from '@angular/common'
|
|
4
8
|
import {
|
|
5
9
|
NgIconComponent,
|
|
@@ -7,14 +11,17 @@ import {
|
|
|
7
11
|
provideNgIconsConfig,
|
|
8
12
|
} from '@ng-icons/core'
|
|
9
13
|
import { matOpenInNew } from '@ng-icons/material-icons/baseline'
|
|
14
|
+
import { getBadgeColor, getFileFormat } from '../../../../../../libs/util/shared/src'
|
|
15
|
+
import { TranslateModule } from '@ngx-translate/core'
|
|
10
16
|
|
|
17
|
+
type CardSize = 'L' | 'M' | 'S' | 'XS'
|
|
11
18
|
@Component({
|
|
12
19
|
selector: 'gn-ui-link-card',
|
|
13
20
|
templateUrl: './link-card.component.html',
|
|
14
21
|
styleUrls: ['./link-card.component.css'],
|
|
15
22
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16
23
|
standalone: true,
|
|
17
|
-
imports: [CommonModule, NgIconComponent],
|
|
24
|
+
imports: [CommonModule, NgIconComponent, TranslateModule],
|
|
18
25
|
providers: [
|
|
19
26
|
provideIcons({
|
|
20
27
|
matOpenInNew,
|
|
@@ -23,8 +30,23 @@ import { matOpenInNew } from '@ng-icons/material-icons/baseline'
|
|
|
23
30
|
],
|
|
24
31
|
})
|
|
25
32
|
export class LinkCardComponent {
|
|
33
|
+
private _size: 'L' | 'M' | 'S' | 'XS'
|
|
26
34
|
@Input() link: DatasetOnlineResource
|
|
27
|
-
|
|
35
|
+
private readonly sizeClassMap: Record<CardSize, string> = {
|
|
36
|
+
L: 'gn-ui-card-l py-2 px-5',
|
|
37
|
+
M: 'gn-ui-card-m py-2 px-5',
|
|
38
|
+
S: 'gn-ui-card-s p-4',
|
|
39
|
+
XS: 'gn-ui-card-xs py-2 px-5',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Input() set size(value: CardSize) {
|
|
43
|
+
this._size = value
|
|
44
|
+
this.cardClass = this.sizeClassMap[value]
|
|
45
|
+
}
|
|
46
|
+
get size(): 'L' | 'M' | 'S' | 'XS' {
|
|
47
|
+
return this._size
|
|
48
|
+
}
|
|
49
|
+
cardClass = ''
|
|
28
50
|
|
|
29
51
|
get title() {
|
|
30
52
|
if (this.link.name && this.link.description) {
|
|
@@ -32,4 +54,12 @@ export class LinkCardComponent {
|
|
|
32
54
|
}
|
|
33
55
|
return this.link.name || this.link.description || ''
|
|
34
56
|
}
|
|
57
|
+
|
|
58
|
+
getLinkFormat(link: any) {
|
|
59
|
+
return getFileFormat(link)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getLinkColor(link: any) {
|
|
63
|
+
return getBadgeColor(getFileFormat(link))
|
|
64
|
+
}
|
|
35
65
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
<div *ngIf="metadataQualityDisplay" class="
|
|
1
|
+
<div *ngIf="metadataQualityDisplay" class="metadata-quality">
|
|
2
2
|
<div
|
|
3
3
|
class="flex items-center"
|
|
4
|
-
[class]="
|
|
4
|
+
[class]="
|
|
5
|
+
smaller ? 'leading-[8px] min-w-[120px] m-h-[120px]' : 'min-w-[200px]'
|
|
6
|
+
"
|
|
5
7
|
>
|
|
6
8
|
<gn-ui-progress-bar
|
|
7
9
|
tabindex="0"
|
|
@@ -162,7 +162,7 @@ export class RecordApiFormComponent {
|
|
|
162
162
|
limit: limit !== '-1' ? Number(limit) : -1,
|
|
163
163
|
offset: offset !== '' ? Number(offset) : undefined,
|
|
164
164
|
outputCrs:
|
|
165
|
-
format
|
|
165
|
+
format.toLowerCase().indexOf('json') > -1 ? 'EPSG:4326' : undefined,
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
if (this.endpoint instanceof WfsEndpoint) {
|
|
@@ -170,6 +170,7 @@ export class RecordApiFormComponent {
|
|
|
170
170
|
options.maxFeatures = limit !== '-1' ? Number(limit) : undefined
|
|
171
171
|
return this.endpoint.getFeatureUrl(this.apiFeatureType, options)
|
|
172
172
|
} else {
|
|
173
|
+
delete options.outputCrs
|
|
173
174
|
return await this.endpoint.getCollectionItemsUrl(
|
|
174
175
|
this.apiFeatureType,
|
|
175
176
|
options
|
|
@@ -20,6 +20,7 @@ import { ThumbnailComponent } from './thumbnail/thumbnail.component'
|
|
|
20
20
|
import { TimeSincePipe } from './user-feedback-item/time-since.pipe'
|
|
21
21
|
import { UserPreviewComponent } from './user-preview/user-preview.component'
|
|
22
22
|
import { ApplicationBannerComponent } from './application-banner/application-banner.component'
|
|
23
|
+
import { InternalLinkCardComponent } from './internal-link-card/internal-link-card.component'
|
|
23
24
|
|
|
24
25
|
@NgModule({
|
|
25
26
|
imports: [
|
|
@@ -42,6 +43,7 @@ import { ApplicationBannerComponent } from './application-banner/application-ban
|
|
|
42
43
|
TextInputComponent,
|
|
43
44
|
ImageInputComponent,
|
|
44
45
|
ApplicationBannerComponent,
|
|
46
|
+
InternalLinkCardComponent,
|
|
45
47
|
],
|
|
46
48
|
providers: [
|
|
47
49
|
provideNgIconsConfig({
|
|
@@ -56,6 +58,7 @@ import { ApplicationBannerComponent } from './application-banner/application-ban
|
|
|
56
58
|
MarkdownParserComponent,
|
|
57
59
|
ImageInputComponent,
|
|
58
60
|
ApplicationBannerComponent,
|
|
61
|
+
InternalLinkCardComponent,
|
|
59
62
|
],
|
|
60
63
|
})
|
|
61
64
|
export class UiElementsModule {}
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
>
|
|
9
9
|
{{ progress }}%
|
|
10
10
|
</div>
|
|
11
|
-
<div class="flex-grow h-[
|
|
11
|
+
<div class="flex-grow h-[4px] w-[52px] {{ color.outerBar }} rounded-full">
|
|
12
12
|
<div
|
|
13
13
|
[style.width.%]="progress"
|
|
14
14
|
class="{{ color.innerBar }} transition-width duration-500
|
|
15
|
-
ease-in-out rounded-full shadow-sm h-
|
|
15
|
+
ease-in-out rounded-full shadow-sm w-[52px] h-[4px]"
|
|
16
16
|
></div>
|
|
17
17
|
</div>
|
|
18
18
|
</div>
|