diff --git a/gateway/gateway.yaml b/gateway/gateway.yaml index 1fe34a05..f8d4fadd 100644 --- a/gateway/gateway.yaml +++ b/gateway/gateway.yaml @@ -34,26 +34,6 @@ georchestra: - "/proxy/?url=*" anonymous: true services: - header: - target: ${georchestra.gateway.services.header.target} - access-rules: - - intercept-url: /header/** - anonymous: true - datafeeder: - target: ${georchestra.gateway.services.datafeeder.target} - headers: - json-user: true - json-organization: true - access-rules: - - intercept-url: /datafeeder/** - anonymous: false - allowed-roles: SUPERUSER,IMPORT - import: - target: ${georchestra.gateway.services.import.target} - access-rules: - - intercept-url: /import/** - anonymous: false - allowed-roles: SUPERUSER,IMPORT console: target: ${georchestra.gateway.services.console.target} access-rules: diff --git a/gateway/routes.yaml b/gateway/routes.yaml index 7f12903c..cee6be10 100644 --- a/gateway/routes.yaml +++ b/gateway/routes.yaml @@ -13,10 +13,6 @@ spring: - Path=/ filters: - RedirectTo=308, /datahub/ - - id: header - uri: ${georchestra.gateway.services.header.target} - predicates: - - Path=/header,/header/** - id: console uri: ${georchestra.gateway.services.console.target} predicates: @@ -63,6 +59,10 @@ spring: uri: ${georchestra.gateway.services.datahub.target} predicates: - Path=/datahub/** + - id: metadata-editor + uri: ${georchestra.gateway.services.metadata-editor.target} + predicates: + - Path=/metadata-editor/** - id: ogc-api-records uri: ${georchestra.gateway.services.ogc-api-records.target} predicates: @@ -71,6 +71,7 @@ spring: georchestra.gateway.services: console.target: http://${CONSOLE_HOST:console}:8080/console/ datahub.target: http://${DATAHUB_HOST:datahub}:80/datahub/ + metadata-editor.target: http://{METADATA_EDITOR_HOST:metadata-editor}:80/metadata-editor/ geonetwork.target: http://${GEONETWORK_HOST:geonetwork}:8080/geonetwork/ geoserver.target: http://${GEOSERVER_HOST:geoserver}:8080/geoserver/ geowebcache.target: http://${GEOWEBCACHE_HOST:geowebcache}:8080/geowebcache/ diff --git a/metadata-editor/README.md b/metadata-editor/README.md new file mode 100644 index 00000000..d47f60cf --- /dev/null +++ b/metadata-editor/README.md @@ -0,0 +1,44 @@ +This folder contains a few customizations specific to geOrchestra for the Datahub: + +* `conf`: geOrchestra-specific Datahub configuration +* `assets`: custom geOrchestra assets overriding the default ones +* `scripts/add-header.sh`: a script meant for injecting the geOrchestra header in the datahub application +* `scripts/add-header-webcomponent.sh`: same as above, but using the new header Web Component from https://github.com/georchestra/header/ + +## How to apply customizations + +### Using docker + +Three things are necessary: +* let the Datahub image know where to find custom assets... +* ...as well as where to find custom configuration +* inject the geOrchestra header in the main HTML file + +For the header injection, the `add-header.sh` should be run at startup time. In order to do this, we need +to override the entrypoint of the docker image. + +The default entrypoint of the Datahub can be seen here: https://github.com/geonetwork/geonetwork-ui/blob/a624c073ff2fdd86c2b2b649799d260463d84374/tools/docker/Dockerfile.apps#L22 + +Taking all this into account, this is how to start the Datahub docker image with customizations: + +```bash +$ docker run -d \ + -p 8080:80 \ + -v georchestra_datadir:/etc/georchestra \ + --env ASSETS_DIRECTORY_OVERRIDE=/etc/georchestra/datahub/assets \ + --env CONFIG_DIRECTORY_OVERRIDE=/etc/georchestra/datahub/conf \ + --entrypoint sh \ + geonetwork/geonetwork-ui-datahub:latest \ + -c "sh /docker-entrypoint.sh; sh /etc/georchestra/datahub/scripts/add-header.sh; nginx -g 'daemon off;'" +``` + +### Not using docker + +1. Copy the files in the `assets` folder to the folder of the same name in the Datahub files + > Example: `assets/favicon.ico` goes to `/var/www/html/datahub/assets/favicon.ico` + +2. Copy the configuration file in the `conf` folder to `assets/configuration` in the Datahub files + > Example: `conf/default.toml` goes to `/var/www/html/datahub/assets/configuration/default.toml` + +3. Run `add-header.sh` by specifying as argument the path to the Datahub files + > Example: run `$ ./add-header.sh /var/www/html/datahub` diff --git a/metadata-editor/assets/favicon.ico b/metadata-editor/assets/favicon.ico new file mode 100644 index 00000000..69fa00c8 Binary files /dev/null and b/metadata-editor/assets/favicon.ico differ diff --git a/metadata-editor/assets/img/header_bg.webp b/metadata-editor/assets/img/header_bg.webp new file mode 100644 index 00000000..f45a1664 Binary files /dev/null and b/metadata-editor/assets/img/header_bg.webp differ diff --git a/metadata-editor/conf/default.toml b/metadata-editor/conf/default.toml new file mode 100644 index 00000000..90e305be --- /dev/null +++ b/metadata-editor/conf/default.toml @@ -0,0 +1,240 @@ +# GeoNetwork-UI configuration +# Note: this file's syntax is TOML (https://toml.io/) + +### GLOBAL SETTINGS + +[global] +# This URL (relative or absolute) must point to the API endpoint of a GeoNetwork4 instance +geonetwork4_api_url = "/geonetwork/srv/api" + +# deprecated - not used currently +datahub_url = "/datahub" + +# Optional; URL template allowing opening datasets in an editor; if set, applications such as the Datahub will offer a button in the header to open the currently-viewed dataset in an editor. +# The template must include the following placeholders, which allow applications to inject the correct values when generating the final URL: +# ${record_id}: identifier of the record +# Example for an integration with the Metadata-Editor: +# edit_url_template = "/metadata-editor/edit/${record_id}" + +# This should point to a proxy to avoid CORS errors on some requests (data preview, OGC capabilities etc.) +# The actual URL will be appended after this path, e.g. : https://my.proxy/?url=http%3A%2F%2Fencoded.url%2Fows` +# This is an optional parameter: leave empty to disable proxy usage +proxy_path = "/mapstore/proxy/?url=" + +# This optional parameter defines, in which language metadata should be queried in elasticsearch. +# Use ISO 639-1 (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format in 2 characters to indicate the language of the metadata. +# Setting to "current" will use the current language of the User Interface. +# If not indicated, a wildcard is used and no language preference is applied for the search. +# metadata_language = "current" + +# This optional URL should point to the login page that allows authentication to the datahub. +# If not indicated, the default geonetwork login page is used. +# The following three placeholders can be part of this URL: +# - ${current_url}: indicates where the current location should be injected in the constructed login URL (eg. start, end) +# - ${lang2}, ${lang3}: indicates if and where the current language should be part of the login URL in language 2 or 3 letter code +# Example to use the georchestra login page: +login_url = "${current_url}?login" +logout_url = "/logout" +# settings_url = "/geonetwork/srv/\${lang3}/admin.console#/organization/users?userOrGroup=" + +# This optional URL should point to the static html page wc-embedder.html which allows to display a web component (like chart and table) via a permalink. +# URLs can be indicated from the root of the same server starting with a "/" or as an external URL. Be conscious of potential CORS issues when using an external URL. +# The default location in the dockerized datahub app for example is "/datahub/wc-embedder.html". +# If the URL is not indicated, no permalinks will show up in the UI. +web_component_embedder_url = "/datahub/wc-embedder.html" + +# This optional parameter defines the languages that will be provided in a dropdown for the user to translate the UI. +# Available languages are listed here: (https://github.com/geonetwork/geonetwork-ui/blob/main/libs/util/i18n/src/lib/i18n.constants.ts). +# More information about the translation can be found in the docs (https://geonetwork.github.io/geonetwork-ui/main/docs/reference/i18n.html) +# languages = ['en', 'fr', 'de'] + +# Enables displaying a "contact block" wherever relevant in applications +# contact_email = "opendata@mycompany.com" + +# Enable declare a specific reuse configuration in datahub +# reuse_form_url = "http://path.to.reuseform.fr" + +### VISUAL THEME + +# All parameters are expressed in CSS format, see: +# - for color: https://developer.mozilla.org/en-US/docs/Web/CSS/color +# - for font families: https://developer.mozilla.org/en-US/docs/Web/CSS/font-family +# - for background: https://developer.mozilla.org/en-US/docs/Web/CSS/background +[theme] +primary_color = "#85127e" +secondary_color = "#1b1f3b" +main_color = "#495057" # All-purpose text color +background_color = "#fdfbff" + +# These optional parameters indicate which background should be used for the main header and the text color used +# on top of the background. The color should be chosen to contrast well with the background (defaults to white). +# Note: The search header does not use the header_foreground_color as it allows futher customisation via HTML. +# header_background = "center /cover url('assets/img/header_bg.webp')" or "var(--color-gray-500)" +# header_foreground_color = 'white' + +# This optional parameter allows to override the fallback image that should be used for thumbnails, +# if the metadata record has no thumbnail image url or it is broken. +# thumbnail_placeholder = 'assets/img/my_custom_placeholder.png' + +# These optional parameters allow changing fonts used in the app +main_font = "'Inter', sans-serif" +title_font = "'Inter', sans-serif" +fonts_stylesheet_url = "https://fonts.googleapis.com/css2?family=Display&family=Inter:wght@200;300;400;500;600;700&display=swap" + +# Use it to set custom location for the favicon; by default, the path `/favicon.ico` will be used +# favicon = "assets/favicon.ico" + +### SEARCH SETTINGS + +# This section contains settings used for fine-tuning the search experience +[search] + +# Optional; Indicates whether the quick filter (by record kind dataset, service or reuse) below the search filters is displayed or not. Defaults to `true`. +# record_kind_quick_filter = true + +# Optional; Indicates the number of elements per page ( datahub news, search, organization pages) +# limit = 5 + +# Optional; specify a GeoJSON object to be used as filter: all records contained inside the geometry will be boosted on top, +# all records which do not intersect with the geometry will be shown with lower priority; can be specified as URL or inline +# Note: if the GeoJSON object contains multiple features, only the geometry of the first one will be kept! +# filter_geometry_url = "/console/account/areaofcompetence" +# filter_geometry_data = '{ "coordinates": [...], "type": "Polygon" }' + +# The advanced search filters available to the user can be customized with this setting. +# The following fields can be used for filtering: 'organization', 'format', 'publicationYear', 'standard', 'inspireKeyword', 'keyword', 'topic', 'isSpatial', 'license', 'resourceType', 'representationType', 'producerOrg', 'publisherOrg' +# If not configured, the default values are 'organization', 'format', 'publicationYear', 'topic', 'isSpatial', 'license' +# Note that some links in the datahub app set an 'organization' filter. So this field is needed to allow unsetting such filters. +# WARNING: 'resourceType' filter has been deprecated, please use 'recordKind' instead. Breaking change: 'resourceType' filter won't retrieve featureCatalog anymore. +# advanced_filters = ['organization', 'format', 'publicationYear', 'topic', 'isSpatial', 'license'] + +# Optional; if true, the default pre-configured searches ("The latest" and "The most popular") +# will not be shown under the main search bar. Defaults to false. +# do_not_use_default_search_preset = false + +# One or several search presets visible in form of badges can be defined here; every search preset is composed of: +# - a name (which can be a translation key) +# - a sort criteria (prepend the field name with - to do a descending sort): +# - `-revisionDateForResource,-publicationDateForResource,-creationDateForResource` (resource dates) +# - `-userSavedcount` +# - `-qualityScore` +# - `-_score` +# Note: Other fields of the records can be used as a sort criteria, but the sort drop-down will not display their entries. +# - filters which can be expressed like so: +# [[search_preset]] +# name = 'filterByName' +# filters.q = 'Full text search' +# filters.organization = ['Org 1', 'Org 2'] +# filters.format = ['format 1', 'format 2'] +# filters.documentStandard = ['iso19115-3.2018'] +# filters.keyword = ['keyword 1', 'keyword 2'] +# filters.inspireKeyword = ['http://inspire.ec.europa.eu/theme/er'] +# filters.topic = ['boundaries'] +# filters.publicationYear = ['2023', '2022'] +# filters.isSpatial = ['yes'] +# filters.license = ['unknown'] +# sort = '-revisionDateForResource,-publicationDateForResource,-creationDateForResource' +# [[search_preset]] +# name = 'otherFilterName' +# filters.q = 'Other Full text search' +# ... +# Note: Values for the same filter are treated with an OR logic, value for different filters are treated with an AND logic + +# Search presets will be advertised to the user along the main search field. + + +### 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 + +### MAP SETTINGS + +# The map section allows to customize how maps are configured. +[map] +# Optional; Will limit the possibility to zoom in past a certain zoom level +max_zoom = 14 + +# Optional; will limit the possibility to pan or zoom out outside of an extent +# Expressed in the map view projection (EPSG:3857) +# max_extent = [-418263.418776, 5251529.591305, 961272.067714, 6706890.609855] + +# Optional; Will remove WFS from map layers if its features exceed the indicated number. +# Data preview chart and table will be hidden in this case. +# max_feature_count = 5000 + +# 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 or geojson file +# ${service_type}: Type of the OWS or geojson file; currently supported WMS, WFS, GEOJSON +# ${layer_name}: Name of the layer +# ${mime_type}: Preferred image format for WMS layers; resolves to image/png for WMS layers backed by vector data (WFS), image/jpeg otherwise; empty for non-WMS layers +# Be careful to use englobing single quotes, if your template syntax includes JSON (with double quotes) +# Examples: +# mapfishapp template: +# external_viewer_url_template = '/mapfishapp/?owsurl=${service_url}&layername=${layer_name}&owstype=${service_type}Layer' +# mapstore template +external_viewer_url_template = '/mapstore/#/?actions=[{"type":"CATALOG:ADD_LAYERS_FROM_CATALOGS","layers":["${layer_name}"],"sources":[{"url":"${service_url}","type":"${service_type}"}],"options":[{"format":"${mime_type}"}]}]' + +# Optional; if true, opens external viewer in new tab (default false) +external_viewer_open_new_tab = true + +# Optional; Will not tile WMS. False by default. +# do_not_tile_wms = false + +# Optional; if true, the default basemap will not be added to the map. +# Use [[map_layer]] sections to define your own custom layers (see below) +# do_not_use_default_basemap = false + +# One or several layers (as background or overlay) can be added to the map with the following properties: +# - type (mandatory): Indicates the layer type. Possible values are 'xyz', 'wms', 'wfs', 'geojson'. +# - url (mandatory for 'xyz', 'wms' and 'wfs' types): Layer endpoint URL. +# - name (mandatory for 'wms' and 'wfs' types): indicates the layer name or feature type. +# - data (for 'geojson' type only): inline GeoJSON data as string +# Layer order in the config is the same as in the map, the first one being the bottom one. +# Each layer is defined in its own [[map_layer]] section. +# Example: +# [[map_layer]] +# type = "maplibre-style" +# styleUrl = "https://data.geopf.fr/annexes/ressources/vectorTiles/styles/PLAN.IGN/gris.json" +# [[map_layer]] +# type = "xyz" +# url = "https://{a-c}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png" +# [[map_layer]] +# type = "wfs" +# url = "https://www.geo2france.fr/geoserver/cr_hdf/ows" +# name = "masque_hdf_ign_carto_latin1" +# [[map_layer]] +# type = "geojson" +# data = """ +# { +# "type": "FeatureCollection", +# "features": [{"type": "Feature", "geometry": {"type": "Point", "coordinates": [125.6, 10.1]}}] +# } +# """ + +### TRANSLATIONS + +# To override translations in a specific language, use a 'translations.xx' section where 'xx' is a language code. +# Language codes are expressed in ISO 639-1 codes, see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes +# Example: +# +# [translations.en] +# results.sortBy.dateStamp = "Last time someone changed something" +# [translations.fr] +# results.sortBy.dateStamp = "Dernière fois que quelqu'un a modifié quelque chose" +# +# Note: +# translation keys ending with ".html" _can_ contain HTML markup, including inline CSS: +# catalog.welcome.html = """ +# Welcome to Organization's
+# wonderful data catalogue +# """ +#[translations.en] +#datahub.header.title.html = '
Discover all the data
of your platform
' + +#[translations.fr] +#datahub.header.title.html = '
Toutes les données
de votre plateforme
' diff --git a/metadata-editor/scripts/add-header-webcomponent.sh b/metadata-editor/scripts/add-header-webcomponent.sh new file mode 100755 index 00000000..c16d69fe --- /dev/null +++ b/metadata-editor/scripts/add-header-webcomponent.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# To be properl executed by datahub initialization need the +x flag +# so you need to add it with chmod and commit/push it +# To be properl executed by datahub initialization need the +x flag +# so you need to add it with chmod and commit/push it +function prop { + variable=$(grep "^${1}" /etc/georchestra/default.properties) + if [[ -z $variable ]] || [[ $variable == \#* ]] ; + then + echo ${2} + else + echo $variable | cut -d'=' -f2 + fi + #one-line version [[ -z $variable ]] || [[ $variable == \#* ]] && echo ${2} || echo $variable | cut -d'=' -f2 +} + +STYLESHEET=$(prop "georchestraStylesheet" "") +SCRIPT=$(prop "headerScript" "https://cdn.jsdelivr.net/gh/georchestra/header@dist/header.js") +HEIGHT=$(prop "headerHeight" "80") +LEGACY=$(prop "useLegacyHeader" "false") +LEGACY_URL=$(prop "headerUrl" "/header") +LOGO=$(prop "logoUrl" "https://www.georchestra.org/public/georchestra-logo.svg") +CONFIG_FILE=$(prop "headerConfigFile" "") + +DATAHUB_DIR=${1:-/usr/share/nginx/html/datahub} +SNIPPET="" + +if grep -q "${SNIPPET}" "${DATAHUB_DIR}/index.html"; then + echo "[INFO] geOrchestra: header already present." + exit 0 +fi + +echo "[INFO] geOrchestra: adding header in the main page..." +sed -i "s##${SNIPPET}#" ${DATAHUB_DIR}/index.html