Skip to content

Commit

Permalink
feat: service as resource add layer suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
AlitaBernachot committed Feb 11, 2025
1 parent 2804667 commit 82df975
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ <h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
class="flex flex-row gap-[8px]"
[(ngModel)]="service.accessServiceProtocol"
[disabled]="disabled"
(change)="resetLayersSuggestion()"
>
<mat-radio-button
*ngFor="let protocolOption of protocolOptions"
Expand All @@ -30,29 +31,59 @@ <h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
<div class="flex flex-col gap-4">
<gn-ui-url-input
class="w-full"
(valueChange)="handleUrlChange($event)"
(uploadClick)="handleUploadClick($event)"
(valueChange)="handleUrlValueChange($event)"
[disabled]="disabled"
[value]="url"
[showValidateButton]="false"
[showValidateButton]="activeLayerSuggestion"
>
<ng-icon name="iconoirCloudUpload"></ng-icon>
<ng-content *ngIf="activeLayerSuggestion">
<ng-icon name="iconoirCloudUpload"></ng-icon>
</ng-content>
</gn-ui-url-input>

<p class="text-sm text-red-500 pl-4" *ngIf="errorMessage" translate>
editor.record.form.field.onlineResource.edit.identifier.error
</p>

<gn-ui-text-input
class="grow border-b border-gray-300 pb-4"
[(value)]="service.identifierInService"
[placeholder]="getIdentifierPlaceholder() | translate"
data-cy="identifier-in-service"
[disabled]="disabled"
*ngIf="
!activeLayerSuggestion ||
(url && errorMessage) ||
(modifyMode && layers === undefined)
"
></gn-ui-text-input>

<gn-ui-dropdown-selector
class="border-b border-gray-300 pb-4"
[showTitle]="false"
[title]="
'editor.record.form.field.onlineResource.edit.identifier.select.label'
| translate
"
[choices]="layers || []"
*ngIf="activeLayerSuggestion && layers !== undefined"
[selected]="service.identifierInService"
(selectValue)="handleSelectValue($event)"
>
</gn-ui-dropdown-selector>
<gn-ui-button
(buttonClick)="submitIdentifier(service.identifierInService)"
[disabled]="disabled || !service.identifierInService || !url"
[disabled]="disabled || !service.identifierInService"
type="primary"
*ngIf="
!modifyMode &&
((activeLayerSuggestion && layers) ||
!activeLayerSuggestion ||
(url && errorMessage))
"
>
<span class="text-white font-bold" translate
>editor.record.form.field.onlineResource.edit.identifier.submit</span
<span class="text-white font-bold" translate>
editor.record.form.field.onlineResource.edit.identifier.submit</span
>
</gn-ui-button>
</div>
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { CommonModule } from '@angular/common'
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
} from '@angular/core'
import { FormsModule } from '@angular/forms'
Expand All @@ -17,6 +19,8 @@ import {
} from '@geonetwork-ui/common/domain/model/record'
import {
ButtonComponent,
DropdownChoice,
DropdownSelectorComponent,
TextInputComponent,
UrlInputComponent,
} from '@geonetwork-ui/ui/inputs'
Expand All @@ -27,6 +31,7 @@ import {
provideNgIconsConfig,
} from '@ng-icons/core'
import { iconoirCloudUpload } from '@ng-icons/iconoir'
import { getLayers } from '@geonetwork-ui/util/shared'

@Component({
selector: 'gn-ui-online-service-resource-input',
Expand All @@ -35,6 +40,7 @@ import { iconoirCloudUpload } from '@ng-icons/iconoir'
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
DropdownSelectorComponent,
ButtonComponent,
CommonModule,
FormsModule,
Expand All @@ -52,18 +58,21 @@ import { iconoirCloudUpload } from '@ng-icons/iconoir'
}),
],
})
export class OnlineServiceResourceInputComponent implements OnChanges {
@Input() service: Omit<DatasetServiceDistribution, 'url'>
export class OnlineServiceResourceInputComponent implements OnChanges, OnInit {
@Input() service: DatasetServiceDistribution
@Input() protocolHint?: string
@Input() disabled? = false
@Input() modifyMode? = false
@Output() urlChange: EventEmitter<string> = new EventEmitter()
@Output() identifierSubmit: EventEmitter<{
url: string
identifier: string
}> = new EventEmitter()

errorMessage = false
selectedProtocol: ServiceProtocol
url: string
layers: DropdownChoice[] | undefined = undefined

protocolOptions: {
label: string
Expand Down Expand Up @@ -99,15 +108,65 @@ export class OnlineServiceResourceInputComponent implements OnChanges {
},
]

constructor(private cdr: ChangeDetectorRef) {}

get activeLayerSuggestion() {
return !['wps', 'GPFDL', 'esriRest', 'other'].includes(
this.service.accessServiceProtocol
)
}

ngOnChanges() {
this.selectedProtocol =
this.protocolOptions.find(
(option) => option.value === this.service.accessServiceProtocol
)?.value ?? 'other'
}

handleUrlChange(url: string) {
ngOnInit() {
if (this.service.url) {
this.url = this.service.url.toString()
}
}

handleUrlValueChange(url: string) {
this.url = url
this.service.url = new URL(url)
this.resetLayersSuggestion()
this.urlChange.emit(this.url)
}

async handleUploadClick(url: string) {
this.url = url

try {
const layers = await getLayers(url, this.service.accessServiceProtocol)
this.layers = layers.map((l) => {
return {
label: l.title ? `${l.title} ${l.name ? `(${l.name})` : ''}` : l.name,
value: l.name || l.title,
}
})

if (this.layers.length === 0) {
throw new Error('No layers found')
}
} catch (e) {
this.errorMessage = true
this.layers = undefined
}

this.cdr.detectChanges()
}

handleSelectValue(val: string) {
this.service.identifierInService = val
}

resetLayersSuggestion() {
this.errorMessage = false
this.layers = undefined
this.service.identifierInService = null
}

submitIdentifier(identifier: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
<gn-ui-online-service-resource-input
[service]="newService"
[disabled]="disabled$ | async"
(urlChange)="handleServiceUrlChange($event)"
(identifierSubmit)="handleIdentifierSubmit($event)"
></gn-ui-online-service-resource-input>
</div>
Expand Down Expand Up @@ -55,19 +54,22 @@ <h3 class="text-[16px] font-bold text-main mb-[12px]" translate>
[(value)]="onlineResource.description"
></gn-ui-text-area>
</div>
<ng-container *ngIf="onlineResource.type === 'service'">
<ng-container *ngIf="onlineResource.type === 'service'; else urlInput">
<span class="w-full border-b border-gray-300"></span>
<gn-ui-online-service-resource-input
[service]="onlineResource"
[modifyMode]="true"
></gn-ui-online-service-resource-input>
</ng-container>
<span class="w-full border-b border-gray-300"></span>
<gn-ui-url-input
class="w-full"
[disabled]="true"
[value]="onlineResource.url"
[showValidateButton]="false"
></gn-ui-url-input>
<ng-template #urlInput>
<span class="w-full border-b border-gray-300"></span>
<gn-ui-url-input
class="w-full"
[disabled]="true"
[value]="onlineResource.url"
[showValidateButton]="false"
></gn-ui-url-input>
</ng-template>
</div>
</ng-template>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,12 @@ export class FormFieldOnlineResourcesComponent {
notLinkResources: OnlineNotLinkResource[] = []
uploadProgress = undefined
uploadSubscription: Subscription = null
newService = {
newService = <DatasetServiceDistribution>{
type: 'service',
accessServiceProtocol: 'ogcFeatures',
identifierInService: '',
} as Omit<DatasetServiceDistribution, 'url'>
url: undefined,
}

protected MAX_UPLOAD_SIZE_MB = MAX_UPLOAD_SIZE_MB

Expand Down
46 changes: 44 additions & 2 deletions libs/ui/inputs/src/lib/url-input/url-input.component.stories.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
import { Meta, StoryObj } from '@storybook/angular'
import {
applicationConfig,
Meta,
moduleMetadata,
StoryObj,
} from '@storybook/angular'
import {
NgIconComponent,
provideIcons,
provideNgIconsConfig,
} from '@ng-icons/core'
import { matStar } from '@ng-icons/material-icons/baseline'
import { UrlInputComponent } from './url-input.component'

export default {
title: 'Inputs/UrlInputComponent',
component: UrlInputComponent,
decorators: [],
decorators: [
moduleMetadata({
imports: [NgIconComponent],
}),
applicationConfig({
providers: [
provideIcons({
matStar,
}),
provideNgIconsConfig({
size: '0.9em',
}),
],
}),
],
argTypes: {
valueChange: {
action: 'valueChange',
Expand Down Expand Up @@ -56,3 +81,20 @@ export const WithoutUploadButton: StoryObj<UrlInputComponent> = {
</gn-ui-url-input>`,
}),
}

export const WithCustomValidateButton: StoryObj<UrlInputComponent> = {
args: {
value: null,
disabled: false,
placeholder: 'https://mysite.org/file',
showValidateButton: true,
},
render: (args) => ({
props: args,
template: `
<gn-ui-url-input [value]='value' [disabled]='disabled' [placeholder]='placeholder' [showValidateButton]='showValidateButton'
(valueChange)='valueChange($event)' (uploadClick)='uploadClick($event)'>
<ng-icon name='matStar'></ng-icon>
</gn-ui-url-input>`,
}),
}
Loading

0 comments on commit 82df975

Please sign in to comment.