Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datahub: Propose external viewer button for geojson files #736

Merged
merged 2 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions conf/default.toml
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ background_color = "#fdfbff"

# Optional; URL template enabling to open map layers in an external viewer; if set, displays a button next to the map's layer drop down
# The template must include the following placeholders, which allow the datahub to inject the correct values when adding a layer to a viewer:
# ${service_url}: URL of the OWS
# ${service_type}: Type of the OWS; currently supported WMS, WFS
# ${service_url}: URL of the OWS or geojson file
# ${service_type}: Type of the OWS or geojson file; currently supported WMS, WFS, GEOJSON
# ${layer_name}: Name of the layer
# Be careful to use englobing single quotes, if your template syntax includes JSON (with double quotes)
# Examples:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,61 +43,158 @@ describe('ExternalViewerButtonComponent', () => {
expect(component.externalViewer).toEqual(false)
})
})
describe('with mapConfig and WMS link', () => {
beforeEach(() => {
component.mapConfig = MAP_CONFIG_FIXTURE
component.link = {
url: new URL(
'http://example.com/ows?service=wms&request=getcapabilities'
),
name: 'layername',
type: 'service',
accessServiceProtocol: 'wms',
}
fixture.detectChanges()
})
it('sets externalViewer to display button to true', () => {
expect(component.externalViewer).toEqual(true)
describe('with mapConfig and valid external links', () => {
let buttonComponent: MockButtonComponent
let componentSpy
let windowSpy
const openMock = jest.fn().mockReturnThis()
const focusMock = jest.fn().mockReturnThis()
describe('with mapConfig and WMS link', () => {
beforeEach(() => {
component.mapConfig = MAP_CONFIG_FIXTURE
component.link = {
url: new URL(
'http://example.com/ows?service=wms&request=getcapabilities'
),
name: 'layername',
type: 'service',
accessServiceProtocol: 'wms',
}
fixture.detectChanges()
})
it('sets externalViewer to display button to true', () => {
expect(component.externalViewer).toEqual(true)
})
describe('click button', () => {
beforeEach(() => {
buttonComponent = fixture.debugElement.query(
By.directive(MockButtonComponent)
).componentInstance
componentSpy = jest.spyOn(component, 'openInExternalViewer')
windowSpy = jest
.spyOn(global, 'window', 'get')
.mockImplementation(() => ({
open: openMock,
focus: focusMock,
}))
buttonComponent.buttonClick.emit()
})

afterEach(() => {
componentSpy.mockRestore()
windowSpy.mockRestore()
})
it('calls openInExternalViewer', () => {
expect(component.openInExternalViewer).toHaveBeenCalled()
})
it('opens window in new tab with URL including WMS link params', () => {
expect(openMock).toHaveBeenCalledWith(
'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["layername"],"sources":[{"url":"http%3A%2F%2Fexample.com%2Fows%3Fservice%3Dwms%26request%3Dgetcapabilities","type":"wms"}]}]',
'_blank'
)
})
it('focuses window', () => {
expect(focusMock).toHaveBeenCalled()
})
})
})
describe('click button', () => {
let buttonComponent: MockButtonComponent
let componentSpy
let windowSpy
const openMock = jest.fn().mockReturnThis()
const focusMock = jest.fn().mockReturnThis()
describe('with mapConfig and WFS link', () => {
beforeEach(() => {
buttonComponent = fixture.debugElement.query(
By.directive(MockButtonComponent)
).componentInstance
componentSpy = jest.spyOn(component, 'openInExternalViewer')
windowSpy = jest
.spyOn(global, 'window', 'get')
.mockImplementation(() => ({
open: openMock,
focus: focusMock,
}))
buttonComponent.buttonClick.emit()
component.mapConfig = MAP_CONFIG_FIXTURE
component.link = {
url: new URL(
'http://example.com/ows?service=wfs&request=getcapabilities'
),
name: 'layername',
type: 'service',
accessServiceProtocol: 'wfs',
}
fixture.detectChanges()
})
it('sets externalViewer to display button to true', () => {
expect(component.externalViewer).toEqual(true)
})
describe('click button', () => {
beforeEach(() => {
buttonComponent = fixture.debugElement.query(
By.directive(MockButtonComponent)
).componentInstance
componentSpy = jest.spyOn(component, 'openInExternalViewer')
windowSpy = jest
.spyOn(global, 'window', 'get')
.mockImplementation(() => ({
open: openMock,
focus: focusMock,
}))
buttonComponent.buttonClick.emit()
})

afterEach(() => {
componentSpy.mockRestore()
windowSpy.mockRestore()
afterEach(() => {
componentSpy.mockRestore()
windowSpy.mockRestore()
})
it('calls openInExternalViewer', () => {
expect(component.openInExternalViewer).toHaveBeenCalled()
})
it('opens window in new tab with URL including WFS link params', () => {
expect(openMock).toHaveBeenCalledWith(
'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["layername"],"sources":[{"url":"http%3A%2F%2Fexample.com%2Fows%3Fservice%3Dwfs%26request%3Dgetcapabilities","type":"wfs"}]}]',
'_blank'
)
})
it('focuses window', () => {
expect(focusMock).toHaveBeenCalled()
})
})
it('calls openInExternalViewer', () => {
expect(component.openInExternalViewer).toHaveBeenCalled()
})
describe('with mapConfig and GEOJSON link', () => {
beforeEach(() => {
component.mapConfig = MAP_CONFIG_FIXTURE
component.link = {
url: new URL('http://example.com/somespatialdata.geojson'),
type: 'download',
mimeType: 'application/vnd.geo+json',
}
fixture.detectChanges()
})
it('opens window in new tab with URL including WMS link params', () => {
expect(openMock).toHaveBeenCalledWith(
'https://example.com/myviewer?url=http%3A%2F%2Fexample.com%2Fows%3Fservice%3Dwms%26request%3Dgetcapabilities&name=layername&type=wms',
'_blank'
)
it('sets externalViewer to display button to true', () => {
expect(component.externalViewer).toEqual(true)
})
it('focuses window', () => {
expect(focusMock).toHaveBeenCalled()
describe('click button', () => {
beforeEach(() => {
buttonComponent = fixture.debugElement.query(
By.directive(MockButtonComponent)
).componentInstance
componentSpy = jest.spyOn(component, 'openInExternalViewer')
windowSpy = jest
.spyOn(global, 'window', 'get')
.mockImplementation(() => ({
open: openMock,
focus: focusMock,
}))
buttonComponent.buttonClick.emit()
})

afterEach(() => {
componentSpy.mockRestore()
windowSpy.mockRestore()
})
it('calls openInExternalViewer', () => {
expect(component.openInExternalViewer).toHaveBeenCalled()
})
it('opens window in new tab with URL including link params', () => {
expect(openMock).toHaveBeenCalledWith(
'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["externalviewer.dataset.unnamed"],"sources":[{"url":"http%3A%2F%2Fexample.com%2Fsomespatialdata.geojson","type":"geojson"}]}]',
'_blank'
)
})
it('focuses window', () => {
expect(focusMock).toHaveBeenCalled()
})
})
})
})
describe('with mapConfig and non WMS link', () => {
describe('with mapConfig and invalid external link (non WMS/WFS/GEOJSON)', () => {
beforeEach(() => {
component.mapConfig = MAP_CONFIG_FIXTURE
component.link = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
import { MapConfig } from '@geonetwork-ui/util/app-config'
import { DatasetDistribution } from '@geonetwork-ui/common/domain/model/record'
import { marker } from '@biesbjerg/ngx-translate-extract-marker'
import { TranslateService } from '@ngx-translate/core'
import { getFileFormat } from '@geonetwork-ui/util/shared'

marker('externalviewer.dataset.unnamed')

@Component({
selector: 'gn-ui-external-viewer-button',
Expand Down Expand Up @@ -31,14 +36,24 @@ export class ExternalViewerButtonComponent {
if (this.link.accessServiceProtocol === 'wfs') {
return 'wfs'
}
} else if (
this.link.type === 'download' &&
getFileFormat(this.link) === 'geojson'
) {
return 'geojson'
}
return null
}

constructor(private translateService: TranslateService) {}

openInExternalViewer() {
const templateUrl = this.mapConfig.EXTERNAL_VIEWER_URL_TEMPLATE
const layerName = this.link.name
? this.link.name
: this.translateService.instant('externalviewer.dataset.unnamed')
const url = templateUrl
.replace('${layer_name}', `${this.link.name}`)
.replace('${layer_name}', `${layerName}`)
.replace(
'${service_url}',
`${encodeURIComponent(this.link.url.toString())}`
Expand Down
2 changes: 1 addition & 1 deletion libs/util/app-config/src/lib/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const MAP_CONFIG_FIXTURE: MapConfig = {
MAX_EXTENT: [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855],
DO_NOT_USE_DEFAULT_BASEMAP: false,
EXTERNAL_VIEWER_URL_TEMPLATE:
'https://example.com/myviewer?url=${service_url}&name=${layer_name}&type=${service_type}',
'https://example.com/myviewer/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["${layer_name}"],"sources":[{"url":"${service_url}","type":"${service_type}"}]}]',
EXTERNAL_VIEWER_OPEN_NEW_TAB: true,
MAP_LAYERS: [
{
Expand Down
1 change: 1 addition & 0 deletions translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "unbekannt",
"downloads.wfs.featuretype.not.found": "Die Schicht wurde nicht gefunden",
"dropFile": "Datei ablegen",
"externalviewer.dataset.unnamed": "Datensatz aus dem Datahub",
"facets.block.title.OrgForResource": "Organisation",
"facets.block.title.availableInServices": "Verfügbar für",
"facets.block.title.cl_hierarchyLevel.key": "Ressourcentyp",
Expand Down
1 change: 1 addition & 0 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "unknown",
"downloads.wfs.featuretype.not.found": "The layer was not found",
"dropFile": "drop file",
"externalviewer.dataset.unnamed": "Datahub layer",
"facets.block.title.OrgForResource": "Organisation",
"facets.block.title.availableInServices": "Available for",
"facets.block.title.cl_hierarchyLevel.key": "Resource type",
Expand Down
1 change: 1 addition & 0 deletions translations/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "",
"downloads.wfs.featuretype.not.found": "",
"dropFile": "",
"externalviewer.dataset.unnamed": "",
"facets.block.title.OrgForResource": "",
"facets.block.title.availableInServices": "",
"facets.block.title.cl_hierarchyLevel.key": "",
Expand Down
1 change: 1 addition & 0 deletions translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "inconnu",
"downloads.wfs.featuretype.not.found": "La couche n'a pas été retrouvée",
"dropFile": "Faites glisser votre fichier",
"externalviewer.dataset.unnamed": "Couche du datahub",
"facets.block.title.OrgForResource": "Organisation",
"facets.block.title.availableInServices": "Disponible pour",
"facets.block.title.cl_hierarchyLevel.key": "Type de ressource",
Expand Down
1 change: 1 addition & 0 deletions translations/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "",
"downloads.wfs.featuretype.not.found": "",
"dropFile": "",
"externalviewer.dataset.unnamed": "",
"facets.block.title.OrgForResource": "",
"facets.block.title.availableInServices": "",
"facets.block.title.cl_hierarchyLevel.key": "",
Expand Down
1 change: 1 addition & 0 deletions translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "",
"downloads.wfs.featuretype.not.found": "",
"dropFile": "",
"externalviewer.dataset.unnamed": "",
"facets.block.title.OrgForResource": "",
"facets.block.title.availableInServices": "",
"facets.block.title.cl_hierarchyLevel.key": "",
Expand Down
1 change: 1 addition & 0 deletions translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "",
"downloads.wfs.featuretype.not.found": "",
"dropFile": "",
"externalviewer.dataset.unnamed": "",
"facets.block.title.OrgForResource": "",
"facets.block.title.availableInServices": "",
"facets.block.title.cl_hierarchyLevel.key": "",
Expand Down
1 change: 1 addition & 0 deletions translations/sk.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"downloads.format.unknown": "neznámy",
"downloads.wfs.featuretype.not.found": "Vrstva nebola nájdená",
"dropFile": "nahrať súbor",
"externalviewer.dataset.unnamed": "",
"facets.block.title.OrgForResource": "Organizácia",
"facets.block.title.availableInServices": "Dostupné pre",
"facets.block.title.cl_hierarchyLevel.key": "Typ zdroja",
Expand Down
Loading