Skip to content

Commit

Permalink
feat: introduce new dropdown selector
Browse files Browse the repository at this point in the history
  • Loading branch information
cmoinier committed Jul 12, 2024
1 parent 7c6b716 commit dacdb4a
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 5 deletions.
3 changes: 3 additions & 0 deletions apps/datahub/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { MelDataViewComponent } from './dataset/dataset-visualisation/data-view/
import { environment } from '../environments/environnment'
import { MelModule, MelEmbeddedTranslateLoader } from '@mel-dataplatform/mel'
import { MelFieldsService } from './search/service/fields.service'
import { MelDatahubDropdownRangeComponent } from './search/search-filters/mel-datahub-dropdown-range/mel-datahub-dropdown-range.component'

@NgModule({
declarations: [
Expand All @@ -86,6 +87,8 @@ import { MelFieldsService } from './search/service/fields.service'
DatasetVisualisationComponent,
MelMapViewComponent,
MelDataViewComponent,
MelDatahubDropdownRangeComponent,
MelDatahubDropdownRangeComponent,
],
imports: [
MelModule,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<button
class="mel-primary-button rounded-none"
class="mel-primary-button gap-0 rounded-none w-52"
[attr.aria-owns]="id"
(click)="openOverlay()"
(keydown)="handleTriggerKeydown($event)"
cdkOverlayOrigin
#overlayOrigin="cdkOverlayOrigin"
>
{{ title }}
<span>{{ title }}</span>
<div class="grow flex items-center mr-2 gap-2 overflow-hidden">
@if(hasSelectedChoices){
<div
class="shrink-0 rounded-full text-primary bg-white font-bold text-[12px] w-5 h-5 flex items-center justify-center mr-1 selected-count"
class="shrink-0 rounded-full text-primary bg-white font-bold text-[12px] w-5 h-5 flex items-center justify-center mr-1 selected-count ml-2"
>
{{ selected['length'] }}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
@if (fieldName === 'qualityScore'){
<mel-datahub-dropdown-range
class="w-full"
[title]="title"
[choices]="choices$ | async"
(selectValues)="onSelectedValues($event)"
[attr.data-cy-field]="fieldName"
></mel-datahub-dropdown-range>
} @else {
<mel-datahub-dropdown-multiselect
class="w-full"
[title]="title"
[maxRows]="6"
[choices]="choices$ | async"
[selected]="selected$ | async"
[allowSearch]="true"
(selectValues)="onSelectedValues($event)"
[attr.data-cy-field]="fieldName"
>
</mel-datahub-dropdown-multiselect>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<button
class="mel-primary-button gap-0 rounded-none w-52"
[attr.aria-owns]="id"
(click)="openOverlay()"
cdkOverlayOrigin
#overlayOrigin="cdkOverlayOrigin"
>
<span>{{ title }}</span>
<div class="grow flex items-center mr-2 gap-2 overflow-hidden">
@if(hasSelectedChoices){
<div
class="shrink-0 rounded-full text-primary bg-white font-bold text-[12px] w-5 h-5 flex items-center justify-center mr-1 selected-count ml-2"
>
{{ selected['length'] }}
</div>
}
</div>
<button class="h-6 w-6" data-cy="clearSelection">
@if(hasSelectedChoices && !overlayOpen){
<mat-icon
class="material-symbols-outlined shrink-0 opacity-40 mr-1.5 hover:opacity-80 transition-colors clear-btn"
(click)="clearSelection($event)"
>
close
</mat-icon>
}
</button>
<mat-icon class="material-symbols-outlined shrink-0">
@if(overlayOpen){
<ng-container>expand_less</ng-container>
} @else {
<ng-container>expand_more</ng-container>
}
</mat-icon>
</button>

<ng-template
cdkConnectedOverlay
cdkConnectedOverlayHasBackdrop
cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
[cdkConnectedOverlayOrigin]="overlayOrigin"
[cdkConnectedOverlayOpen]="overlayOpen"
[cdkConnectedOverlayPositions]="overlayPositions"
[cdkConnectedOverlayScrollStrategy]="scrollStrategy"
[cdkConnectedOverlayFlexibleDimensions]="true"
(overlayOutsideClick)="closeOverlay()"
(detach)="closeOverlay()"
>
<div
class="bg-white border border-gray-300 shadow-lg py-2 w-full overflow-x-hidden overflow-y-auto overlay-container"
[style.max-height]="overlayMaxHeight"
[style.width]="'300px'"
role="listbox"
tabindex="-1"
[attr.id]="id"
[attr.aria-multiselectable]="true"
[attr.aria-label]="title"
#overlayContainer
>
<div class="flex flex-col ml-3 gap-3">
<div class="mr-3">
<div class="text-primary" translate>
mel.datahub.search.filters.range.from
</div>
<gn-ui-text-input
class="w-64"
(valueChange)="lowValue = $event"
[value]="lowValue"
[hint]="'mel.datahub.search.filters.minValue' | translate"
></gn-ui-text-input>
</div>
<div class="mr-3">
<div class="text-primary" translate>
mel.datahub.search.filters.range.to
</div>
<gn-ui-text-input
class="w-64"
(valueChange)="highValue = $event"
[value]="highValue"
[hint]="'mel.datahub.search.filters.maxValue' | translate"
></gn-ui-text-input>
</div>
<mel-datahub-button
[disabled]="!lowValue || !highValue"
class="self-end mr-3"
[label]="'mel.datahub.search.filters.validate' | translate"
[icon]="'arrow'"
(click)="onValidate()"
></mel-datahub-button>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import {
CdkOverlayOrigin,
ConnectedPosition,
ScrollStrategyOptions,
} from '@angular/cdk/overlay'
import {
ChangeDetectionStrategy,
Component,
ElementRef,
EventEmitter,
Input,
Output,
ViewChild,
} from '@angular/core'
import { Choice, propagateToDocumentOnly } from 'geonetwork-ui'

@Component({
selector: 'mel-datahub-dropdown-range',
templateUrl: './mel-datahub-dropdown-range.component.html',
styles: ``,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MelDatahubDropdownRangeComponent {
lowValue = ''
highValue = ''
@Input() choices: Choice[]
@Input() title: string
@Input() selected: unknown[] = []
@Output() selectValues = new EventEmitter<unknown[]>()
@ViewChild('overlayOrigin') overlayOrigin: CdkOverlayOrigin
@ViewChild('overlayContainer', { read: ElementRef })
overlayContainer: ElementRef
overlayPositions: ConnectedPosition[] = [
{
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top',
offsetY: 8,
},
{
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'bottom',
offsetY: -8,
},
]
scrollStrategy = this.scrollStrategies.reposition()
overlayOpen = false
overlayWidth = 'auto'
overlayMaxHeight = 'none'
id = `dropdown-multiselect-${Math.floor(Math.random() * 10000)}`

get hasSelectedChoices() {
return this.selected.length > 0
}

constructor(private scrollStrategies: ScrollStrategyOptions) {}

openOverlay() {
this.overlayWidth =
this.overlayOrigin.elementRef.nativeElement.getBoundingClientRect()
.width + 'px'
this.overlayOpen = true
}

closeOverlay() {
this.overlayOpen = false
}

clearSelection(event: Event) {
this.selectValues.emit([])
this.highValue = ''
this.lowValue = ''
this.selected = []
propagateToDocumentOnly(event)
}

onValidate() {
const lowValue = Number(this.lowValue)
const highValue = Number(this.highValue)
this.selected = this.choices
.filter((choice) => {
const choiceNb = Number(choice.value)
if (lowValue && highValue) {
return choiceNb >= lowValue && choiceNb <= highValue
} else if (lowValue) {
return choiceNb >= lowValue
} else if (highValue) {
return choiceNb <= highValue
}
return true
})
.map((choice) => choice.value)
this.selectValues.emit(this.selected)
}
}

0 comments on commit dacdb4a

Please sign in to comment.