Skip to content

Commit

Permalink
rebase to main
Browse files Browse the repository at this point in the history
  • Loading branch information
gkeimeHDF committed Jul 5, 2023
1 parent 2404ff5 commit f13e429
Show file tree
Hide file tree
Showing 33 changed files with 562 additions and 17 deletions.
3 changes: 3 additions & 0 deletions apps/datahub/src/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ body {
margin: 0;
}

.container-xs {
max-width: 500px;
}
.container-sm {
max-width: 640px;
}
Expand Down
1 change: 1 addition & 0 deletions apps/search/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"results.sortBy.dateStamp": "Last updates",
"results.sortBy.popularity": "Popularity",
"results.sortBy.relevancy": "Relevancy",
"results.sortBy.qualityScore": "Quality score",
"search.field.any.placeholder": "Search datasets, services and maps ...",
"search.field.sortBy": "Sort by",
"search.loading": "Loading ..."
Expand Down
1 change: 1 addition & 0 deletions apps/webcomponents/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"results.sortBy.dateStamp": "Last updates",
"results.sortBy.popularity": "Popularity",
"results.sortBy.relevancy": "Relevancy",
"results.sortBy.qualityScore": "Quality score",
"search.field.any.placeholder": "Search datasets, services and maps ...",
"search.field.sortBy": "Sort by",
"search.loading": "Loading ..."
Expand Down
31 changes: 31 additions & 0 deletions conf/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ background_color = "#fdfbff"
# title_font = "'My Custom Title Font', fallback-font-title"
# fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&family=Permanent+Marker&display=swap"

# This optional parameter allow you to change the default class on progress bar, by default is font-bold
# progress_bar_text_class = 'font-normal'

### SEARCH SETTINGS

# This section contains settings used for fine-tuning the search experience
Expand All @@ -64,6 +67,34 @@ background_color = "#fdfbff"
# filter_geometry_url = "https://my.domain.org/assets/boundary.geojson"
# filter_geometry_data = '{ "coordinates": [...], "type": "Polygon" }'


### METADATA QUALITY SETTINGS

# This section contains settings used for fine-tuning the metadata quality experience
[metadata-quality]
# By default the widget is not activated to enable it, just add this parameter.
# enabled = true
# If u want to use metadata quality widget this configuration is required

# if you add an indexed field to calculate the qualityScore, the datahub search allow you to sort on this field with this parameter
# sortable = true

# by default the wudget appear in 2 location in search list and in detail page
# display_widget_in_detail = false // allow you to hide the widget in detail
# display_widget_in_search = false // allow you to hide the widget in search list
# If you want see the widget in the two location, don't fill theses configurations

# By default the window popup all fields to view if they are filled or not but you can hide some
# display_title = false
# display_description = false
# display_topic = false
# display_keywords = false
# display_legal_constraints = false
# display_contact = false
# display_update_frequency = false
# display_organisation = false
# If you want see all fields, don't fill theses configurations

### MAP SETTINGS

# The map section allows to customize how maps are configured.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
</gn-ui-metadata-info>
</div>
<div>
<gn-ui-metadata-quality *ngIf="hasMetadataQualityWidget" [metadata]="facade.metadata$ | async"></gn-ui-metadata-quality>
<gn-ui-metadata-contact
(contact)="onContactClick($event)"
[metadata]="facade.metadata$ | async"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { ErrorType } from '@geonetwork-ui/ui/elements'
import { BehaviorSubject, combineLatest } from 'rxjs'
import { filter, map, mergeMap, pluck } from 'rxjs/operators'
import { MdViewFacade } from '../state/mdview.facade'
import { MetadataContact, Organisation } from '@geonetwork-ui/util/shared'
import { MetadataContact } from '@geonetwork-ui/util/shared'
import { MetadataQualityConfig, getMetadataQualityConfig } from '@geonetwork-ui/util/app-config'

@Component({
selector: 'gn-ui-record-metadata',
Expand All @@ -17,6 +18,7 @@ import { MetadataContact, Organisation } from '@geonetwork-ui/util/shared'
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RecordMetadataComponent {
metadataQualityConfig: MetadataQualityConfig = getMetadataQualityConfig();
displayMap$ = combineLatest([
this.facade.mapApiLinks$,
this.facade.geoDataLinks$,
Expand Down Expand Up @@ -60,7 +62,11 @@ export class RecordMetadataComponent {
private searchService: SearchService,
private sourceService: SourcesService,
private orgsService: OrganisationsServiceInterface
) {}
) { }

get hasMetadataQualityWidget() {
return this.metadataQualityConfig.ENABLED && this.metadataQualityConfig.DISPLAY_WIDGET_IN_RECORD_METADATA !== false
}

onTabIndexChange(index: number): void {
this.selectedTabIndex$.next(index)
Expand Down
12 changes: 11 additions & 1 deletion libs/feature/search/src/lib/sort-by/sort-by.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { marker } from '@biesbjerg/ngx-translate-extract-marker'
import { SortByEnum } from '@geonetwork-ui/util/shared'
import { SearchFacade } from '../state/search.facade'
import { SearchService } from '../utils/service/search.service'
import { getMetadataQualityConfig } from '@geonetwork-ui/util/app-config'

marker('results.sortBy.relevancy')
marker('results.sortBy.dateStamp')
marker('results.sortBy.popularity')
marker('results.sortBy.qualityScore')

@Component({
selector: 'gn-ui-sort-by',
Expand All @@ -27,12 +29,20 @@ export class SortByComponent {
value: SortByEnum.POPULARITY,
},
]
metadataQualityConfig = getMetadataQualityConfig();
currentSortBy$ = this.facade.sortBy$

constructor(
private facade: SearchFacade,
private searchService: SearchService
) {}
) {
if (this.metadataQualityConfig.ENABLED && this.metadataQualityConfig.SORTABLE) {
this.choices.push({
label: 'results.sortBy.qualityScore',
value: SortByEnum.QUALITY_SCORE,
});
}
}

changeSortBy(criteria: any) {
if (typeof criteria === 'string') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
toDate,
} from '@geonetwork-ui/util/shared'
import { MetadataUrlService } from '../service/metadata-url.service'
import { MetadataQualityConfig, getMetadataQualityConfig } from '@geonetwork-ui/util/app-config'

type ESResponseSource = SourceWithUnknownProps

Expand All @@ -42,7 +43,8 @@ export class ElasticsearchFieldMapper {
uuid: (output, source) => {
const uuid = selectField<string>(source, 'uuid')
const metadataUrl = this.metadataUrlService.getUrl(uuid)
return { ...output, uuid, metadataUrl }
const qualityScore = this.calculateQualityScore(source)
return { ...output, uuid, metadataUrl, qualityScore }
},
resourceTitleObject: (output, source) => ({
...output,
Expand Down Expand Up @@ -71,6 +73,12 @@ export class ElasticsearchFieldMapper {
)
),
}),
cl_topic: (output, source) => ({
...output,
topic: getAsArray(
selectField<SourceWithUnknownProps[]>(source, 'cl_topic')
).map((cl_topic) => selectTranslatedValue<string>(cl_topic)),
}),
cl_status: (output, source) => ({
...output,
updateStatus: selectTranslatedValue(
Expand Down Expand Up @@ -130,13 +138,22 @@ export class ElasticsearchFieldMapper {
}),
MD_ConstraintsUseLimitationObject: (output, source) =>
this.constraintField('MD_ConstraintsUseLimitationObject', output, source),
MD_LegalConstraintsUseLimitationObject: (output, source) =>
this.constraintField(
'MD_LegalConstraintsUseLimitationObject',
output,
source
),
MD_LegalConstraintsOtherConstraintsObject: (output, source) =>
MD_LegalConstraintsUseLimitationObject: (output, source) => {
const legalConstraints = getAsArray(
selectField<SourceWithUnknownProps[]>(source, 'MD_LegalConstraintsUseLimitationObject')
).map((MD_LegalConstraintsUseLimitationObject) => selectTranslatedValue<string>(MD_LegalConstraintsUseLimitationObject));
let prevConstraints = output.constraints || [];
const constraints = {
...prevConstraints,
...legalConstraints
};
return {
...output,
legalConstraints,
constraints
}
},
MD_LegalConstraintsOtherConstraintsObject: (output, source) =>
this.constraintField(
'MD_LegalConstraintsOtherConstraintsObject',
output,
Expand Down Expand Up @@ -171,6 +188,66 @@ export class ElasticsearchFieldMapper {
}),
}

private calculateQualityScore = (source) => {
const qualityScore:number = selectField(source, 'qualityScore');
if (qualityScore != null) {
return qualityScore;
}
const metadataQualityConfig: MetadataQualityConfig = getMetadataQualityConfig();
let total = 0;
let success = 0;
const check = (name:string) => {
const display = metadataQualityConfig[`DISPLAY_${name}`] !== false;
if (display) total++;
return display;
}
if (check('TITLE')) {
if (selectField(source, 'resourceTitleObject')) {
success++;
}
}
if (check('DESCRIPTION')) {
if (selectFallback(selectTranslatedField(source, 'resourceAbstractObject'), 'no title')) {
success++;
}
}
const contact = mapContact(
getFirstValue(selectField(source, 'contact')),
source
);
if (check('ORGANISATION')) {
if (contact?.organisation) {
success++;
}
}
if (check('CONTACT')) {
if (contact?.email) {
success++;
}
}
if (check('TOPIC')) {
if (selectField<SourceWithUnknownProps[]>(source, 'cl_topic')?.length > 0) {
success++;
}
}
if (check('KEYWORDS')) {
if (selectField<SourceWithUnknownProps[]>(source, 'tag')?.length > 0) {
success++;
}
}
if (check('UPDATE_FREQUENCY')) {
if (getFirstValue(selectField(source, 'cl_maintenanceAndUpdateFrequency'))) {
success++;
}
}
if (check("LEGAL_CONSTRAINTS")) {
if (selectField<unknown[]>(source, 'MD_LegalConstraintsUseLimitationObject')?.length > 0) {
success++;
}
}
return Math.round(success * 100 / total);
}

private genericField = (output) => output

private constraintField = (fieldName: string, output, source) => ({
Expand Down
2 changes: 2 additions & 0 deletions libs/ui/elements/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ export * from './lib/ui-elements.module'
export * from './lib/metadata-info/metadata-info.component'
export * from './lib/metadata-contact/metadata-contact.component'
export * from './lib/metadata-catalog/metadata-catalog.component'
export * from './lib/metadata-quality/metadata-quality.component'
export * from './lib/metadata-quality-info/metadata-quality-info.component'
export * from './lib/search-results-error/search-results-error.component'
export * from './lib/thumbnail/thumbnail.component'
export * from './lib/content-ghost/content-ghost.component'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div *ngIf="display" class="metadata-quality-info ml-4 flex flex-row">
<mat-icon>{{ icon }}</mat-icon>
<p class="ml-2 text">
{{ labelKey | translate }}
</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'
import { UtilSharedModule } from '@geonetwork-ui/util/shared'
import { TranslateModule } from '@ngx-translate/core'
import { ContentGhostComponent } from '../content-ghost/content-ghost.component'
import { MetadataQualityInfoComponent } from './metadata-quality-info.component'

describe('MetadataQualityInfoComponent', () => {
let component: MetadataQualityInfoComponent
let fixture: ComponentFixture<MetadataQualityInfoComponent>

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), UtilSharedModule],
declarations: [MetadataQualityInfoComponent, ContentGhostComponent],
}).compileComponents()
})

beforeEach(() => {
fixture = TestBed.createComponent(MetadataQualityInfoComponent)
component = fixture.componentInstance
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
ChangeDetectionStrategy,
Component,
Input
} from '@angular/core'
import { MetadataQualityConfig, getMetadataQualityConfig } from '@geonetwork-ui/util/app-config';

@Component({
selector: 'gn-ui-metadata-quality-info',
templateUrl: './metadata-quality-info.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MetadataQualityInfoComponent {

metadataQualityConfig: MetadataQualityConfig = getMetadataQualityConfig();
@Input() name: string
@Input() value: boolean

get display() {
const name_snake_upper = this.name.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`).toUpperCase();
return this.metadataQualityConfig['DISPLAY_' + name_snake_upper] !== false;
}

get icon() {
return this.value ? 'check' : 'warning_amber'
}

get labelKey() {
return 'record.metadata.quality.' + this.name + '.' + (this.value ? 'success' : 'failed')
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
:host-context(.picto)>.metadata-quality {
margin-bottom: 0px;
}


:host-context(.picto) > .metadata-quality > .widget > p.text {
display: none;
}

:host-context(.picto) > .metadata-quality > .menu {
right: 0px;
}
:host-context(.picto)> .metadata-quality > .widget gn-ui-progress-bar {
line-height: 8px;
}

:host-context(.picto) ::ng-deep gn-ui-progress-bar .text-4 {
font-weight: normal;
font-size: 15px;
}

.menu {
position: absolute;
z-index: 1;
background-color: white;
border: 1px solid rgba(0, 0, 0, 0.35);
border-radius: 5px;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
padding: 20px;
white-space: nowrap;
}
Loading

0 comments on commit f13e429

Please sign in to comment.