Commit 48389b68 authored by Matija Obreza's avatar Matija Obreza
Browse files

Merge branch '16-documentation' into 'main'

Resolve "Documentation"

Closes #16

See merge request !34
parents e880f166 a9b51a5a
# Enhance your website with data from Genesys
This package allows for embedding [Genesys](https://www.genesys-pgr.org) into your website.
Genesys is an openly accessible database on **plant genetic resources** maintained in **genebanks** around the world. This package allows for embedding data from [Genesys](https://www.genesys-pgr.org) into your website.
Instead of hosting and maintaining a separate database, web server and domain name, use **Embedded Genesys** to integrate your genebank collection data directly into the institutional website!
Explore the demo at https://genesys-pgr.p.gitlab.croptrust.org/ui-embedded/
......@@ -25,13 +27,16 @@ Add a container `<div>` to your HTML page and initialize the Genesys UI with the
<div class="container-fluid mb-5" id="genesys-container"></div>
<script type="text/javascript">
// Detect language from query string
const queryLang = document.location.search && document.location.search.substr(1) || undefined;
// Embedded Genesys configuration
const genesysConfig = {
apiUrl: 'https://api.sandbox.genesys-pgr.org', // Genesys API server
clientId: 'clientid@genesys', // Client ID
clientKey: 'changeme', // Client key
title: 'Genesys:', // HTML title prefix
language: 'en', // Display Embedded Genesys in: en, es, zh-TW
language: queryLang, // Use URL query string to use the "detected" language (see above), or specify a constant: 'en', 'es', 'zh-TW'
filter: {
institute: { code: [ 'ETH013' ] }, // Genesys data filter
},
......@@ -43,7 +48,7 @@ Add a container `<div>` to your HTML page and initialize the Genesys UI with the
shoppingCart: {
enabled: true, // Enable shopping cart
},
captchaSiteKey: '<public key for your site>', // Your hCaptcha site key
captchaSiteKey: '<public key for your site>', // Your hCaptcha site key from https://dashboard.hcaptcha.com
map: {
enabled: true, // Enable map
baseMap: {
......@@ -61,9 +66,12 @@ Add a container `<div>` to your HTML page and initialize the Genesys UI with the
</script>
```
**Note:** Please contact helpdesk@genesys-pgr.org to obtain API keys for use in your environment.
**Note:** Please see available configuration options in the *Configuration options* section below.
**Note:** Any website that uses the Genesys API must be registered. Please contact helpdesk@genesys-pgr.org to obtain API keys for use in your environment.
## Configuration options
# Configuration options
The `genesysConfig` argument to `showGenesysUI()` is a simple map of various settings you can pass
to *@geneesys-pgr/ui-embedded*:
......@@ -94,26 +102,31 @@ Features can be toggled by setting corresponding property **on** (set to `true`)
|`pdci`|`true`| Display passport data completeness index (PDCI) information on accession details page |
### Shopping cart options
## Shopping cart and captcha options
The shopping cart is **disabled by default**. To allow users to add accessions to the cart, access the cart and submit requests for material you must explicity enable it in your configuration:
The shopping cart is **disabled by default**.
```
To allow users to add accessions to the cart, access the cart and submit requests for material you must explicity enable the shopping cart and specify the captcha site key in your configuration:
```js
const genesysConfig = {
// Shopping cart enabled
captchaSiteKey: '<public key for your site>', // Your hCaptcha site key from https://dashboard.hcaptcha.com
shoppingCart: {
enabled: true,
enabled: true, // Enable shopping cart
},
};
```
**Note:** The form to request for material includes a **reCaptcha** check. Valid public and private reCaptcha keys must be registered with Genesys.
|Property|Default|Description|
|---|---|---|
|`enabled`|`false`| Toggle Shopping cart functionality |
### Map configuration
**Note:** The request for material form includes an **hCaptcha** check. Valid public and private keys for your **hCaptcha** account must be registered with Genesys. Please contact helpdesk@genesys-pgr.org for support.
When `captchaSiteKey` is missing, the **Shopping cart** functionality is automatically disabled.
## Map configuration
The map is **disabled by default**. To allow users to see map of accession collecting site on accession details page and access the map page you must explicity enable it in your configuration and provide a tile server URL and an attribution data for the base map layer:
......@@ -122,8 +135,8 @@ The map is **disabled by default**. To allow users to see map of accession colle
|`enabled`|`false`| Toggle map functionality |
|`height`|`'400px'`| Height of the map of accessions (use a CSS expression) |
|`baseMap`|`{ url: ..., attribution: ... }`| See `url` and `attribution` below. |
|`baseMap.url`|[World_Light_Gray_Base](https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}/)| Tile server url for the map base layer. |
|`baseMap.attribution`|Tiles &copy; ...| Base layer attribution. |
|`baseMap.url`|[World_Light_Gray_Base](https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}/)| Tile server template URL for the base map layer. |
|`baseMap.attribution`|Tiles &copy; ...| Map base layer attribution. |
# Translating Embedded Genesys
......
import React from 'react';
import { Link } from 'react-router-dom';
import { parse } from 'query-string';
import { connect } from 'react-redux';
import { AccessionService } from '@genesys-pgr/client/service';
......@@ -15,10 +14,12 @@ import { WithConfig } from 'config/config';
import Loading from 'ui/common/Loading';
import PageTitle from 'ui/common/PageTitle';
import { CountryName } from 'ui/common/CountryName';
// util
import {parseLocationSearch} from "utilities/filterUtil";
interface AccessionListPageState {
filter: AccessionFilter;
accessions: FilteredPage<Accession>;
accessions: FilteredPage<Accession, AccessionFilter>;
selected: string[];
cartItems: string[];
isAllSelected: boolean;
......@@ -42,7 +43,7 @@ class AccessionListPage extends React.Component<AccessionListPageProps & WithTra
}
public componentDidMount() {
const { current, filterCode } = this.parseLocationSearch(this.props.location);
const { current, filterCode } = parseLocationSearch(this.props.location);
this.loadData(filterCode || this.state.filter, current ? { page: current } : {});
if (typeof window !== 'undefined') {
window.addEventListener('storage', this.handleLocalStorageUpdate);
......@@ -67,8 +68,8 @@ class AccessionListPage extends React.Component<AccessionListPageProps & WithTra
};
public componentDidUpdate(prevProps) {
const { current: currentPage, filterCode } = this.parseLocationSearch(this.props.location);
const { current: prevPage, filterCode: prevFilterCode } = this.parseLocationSearch(prevProps.location);
const { current: currentPage, filterCode } = parseLocationSearch(this.props.location);
const { current: prevPage, filterCode: prevFilterCode } = parseLocationSearch(prevProps.location);
if (prevPage !== undefined && currentPage === 0 && prevFilterCode !== undefined && filterCode === undefined) {
// console.log('did update, reset filter);
......@@ -76,16 +77,6 @@ class AccessionListPage extends React.Component<AccessionListPageProps & WithTra
}
}
private parseLocationSearch = (location) => {
const current = +parse(location.search).p || 0;
const filterCode = parse(location.search).filter && parse(location.search).filter.toString();
// const size = +parse(location.search).l || 20;
// const sort = parse(location.search).s;
// const dir = parse(location.search).d;
return { current, filterCode /* , size, sort, dir, */ };
};
private loadData = (filter: string | AccessionFilter, pageR: IPageRequest): Promise<any> => {
return AccessionService
.list(filter, pageR)
......
......@@ -28,6 +28,10 @@ export class Config {
// Merge feature config
this.accession = { ...defaultConfig.accession, ...config.accession };
this.shoppingCart = { ...defaultConfig.shoppingCart, ...config.shoppingCart };
if (! this.captchaSiteKey) {
// Force disable shopping cart if captchaSiteKey is missing
this.shoppingCart.enabled = false;
}
this.map = { ...defaultConfig.map, ...config.map };
// console.log('Source and merged configuration', config, this);
}
......
......@@ -4,9 +4,10 @@ import { history } from 'ui/core/App';
import { withTranslation, WithTranslation } from 'react-i18next';
interface PaginationProps {
loadData: (filter: Record<string, any>, pageR: IPageRequest) => Promise<any>;
paged: FilteredPage<any>;
loadData: (filter: Record<string, any> | string, pageR: IPageRequest) => Promise<any>;
paged: FilteredPage<any, any>;
children: React.ReactNode;
prefix?: string;
}
class Pagination extends React.Component<PaginationProps & WithTranslation> {
......@@ -30,14 +31,15 @@ class Pagination extends React.Component<PaginationProps & WithTranslation> {
const page = +(e.currentTarget as HTMLElement).dataset.page;
loadData(paged.filter, this.makePageRequest(page))
.then((data: FilteredPage<any>) => {
.then((data: FilteredPage<any, any>) => {
this.updateRoute(data);
});
};
private updateRoute = (page: FilteredPage<any>) => {
private updateRoute = (page: FilteredPage<any, any>) => {
// console.log('updateRoute', page);
history.push(`/?filter=${page.filterCode}&p=${page.number}`);
const {prefix} = this.props;
history.push(`${prefix || ''}/?${page.filterCode ? 'filter=' + page.filterCode + '&': ''}p=${page.number}`);
};
private makePageRequest = (page: number): IPageRequest => {
......
import { parse } from 'query-string';
export const parseLocationSearch = (location) => {
const current = +parse(location.search).p || 0;
const filterCode = parse(location.search).filter && parse(location.search).filter.toString();
const size = +parse(location.search).l || 20;
const sort = parse(location.search).s;
const dir = parse(location.search).d;
return {current, filterCode, size, sort, dir};
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment