Skip to content
Snippets Groups Projects
Commit 8dae6b6e authored by Lutz Helm's avatar Lutz Helm Committed by Chris Beer
Browse files

Fix #3522, add selector and UI for related

parent 5bb2cb14
No related branches found
No related tags found
3 merge requests!4Integrate upstream tests into gitlab ci,!3Update mirador code from official project,!2test gitlab ci (dont merge)
{
"@context": "http://iiif.io/api/presentation/2/context.json",
"@id": "http://example.com/iiif/manifest/related-urls.json",
"@type": "sc:Manifest",
"related": [
"http://example.com/related1",
{
"@id": "http://example.com/related2"
},
{
"@id": "http://example.com/related3",
"format": "text/html",
"label": "Something related"
}
]
}
...@@ -21,6 +21,16 @@ describe('ManifestRelatedLinks', () => { ...@@ -21,6 +21,16 @@ describe('ManifestRelatedLinks', () => {
}, },
]} ]}
manifestUrl="http://example.com/" manifestUrl="http://example.com/"
related={[
{
value: 'http://example.com/related',
},
{
format: 'video/ogg',
label: 'Video',
value: 'http://example.com/video',
},
]}
renderings={[ renderings={[
{ {
label: 'PDF Version', label: 'PDF Version',
...@@ -81,16 +91,42 @@ describe('ManifestRelatedLinks', () => { ...@@ -81,16 +91,42 @@ describe('ManifestRelatedLinks', () => {
).toBe(true); ).toBe(true);
}); });
it('renders manifest seeAlso information', () => { it('renders related information', () => {
expect( expect(
wrapper.find(Typography).at(5) wrapper.find(Typography).at(5)
.matchesElement( .matchesElement(
<Typography component="dt">iiif_seeAlso</Typography>, <Typography component="dt">iiif_related</Typography>,
), ),
).toBe(true); ).toBe(true);
expect( expect(
wrapper.find(Typography).at(6) wrapper.find(Typography).at(6)
.matchesElement(
<Typography component="dd"><Link href="http://example.com/related">http://example.com/related</Link></Typography>,
),
).toBe(true);
expect(
wrapper.find(Typography).at(7)
.matchesElement(
<Typography component="dd">
<Link href="http://example.com/video">Video</Link>
<Typography>(video/ogg)</Typography>
</Typography>,
),
).toBe(true);
});
it('renders manifest seeAlso information', () => {
expect(
wrapper.find(Typography).at(9)
.matchesElement(
<Typography component="dt">iiif_seeAlso</Typography>,
),
).toBe(true);
expect(
wrapper.find(Typography).at(10)
.matchesElement( .matchesElement(
<Typography component="dd"> <Typography component="dd">
<Link href="http://example.com/a">A</Link> <Link href="http://example.com/a">A</Link>
...@@ -100,7 +136,7 @@ describe('ManifestRelatedLinks', () => { ...@@ -100,7 +136,7 @@ describe('ManifestRelatedLinks', () => {
).toBe(true); ).toBe(true);
expect( expect(
wrapper.find(Typography).at(8) wrapper.find(Typography).at(12)
.matchesElement( .matchesElement(
<Typography component="dd"><Link href="http://example.com/b">http://example.com/b</Link></Typography>, <Typography component="dd"><Link href="http://example.com/b">http://example.com/b</Link></Typography>,
), ),
...@@ -109,14 +145,14 @@ describe('ManifestRelatedLinks', () => { ...@@ -109,14 +145,14 @@ describe('ManifestRelatedLinks', () => {
it('renders manifest links', () => { it('renders manifest links', () => {
expect( expect(
wrapper.find(Typography).at(9) wrapper.find(Typography).at(13)
.matchesElement( .matchesElement(
<Typography component="dt">iiif_manifest</Typography>, <Typography component="dt">iiif_manifest</Typography>,
), ),
).toBe(true); ).toBe(true);
expect( expect(
wrapper.find(Typography).at(10) wrapper.find(Typography).at(14)
.matchesElement( .matchesElement(
<Typography component="dd"><Link href="http://example.com/">http://example.com/</Link></Typography>, <Typography component="dd"><Link href="http://example.com/">http://example.com/</Link></Typography>,
), ),
......
...@@ -6,6 +6,7 @@ import manifestFixtureSn904cj3429 from '../../fixtures/version-2/sn904cj3429.jso ...@@ -6,6 +6,7 @@ import manifestFixtureSn904cj3429 from '../../fixtures/version-2/sn904cj3429.jso
import manifestFixturev3001 from '../../fixtures/version-3/001.json'; import manifestFixturev3001 from '../../fixtures/version-3/001.json';
import manifestFixtureWithAProvider from '../../fixtures/version-3/with_a_provider.json'; import manifestFixtureWithAProvider from '../../fixtures/version-3/with_a_provider.json';
import manifestFixtureFg165hz3589 from '../../fixtures/version-2/fg165hz3589.json'; import manifestFixtureFg165hz3589 from '../../fixtures/version-2/fg165hz3589.json';
import manifestFixtureRelated from '../../fixtures/version-2/related.json';
import { import {
getManifestoInstance, getManifestoInstance,
getManifestLocale, getManifestLocale,
...@@ -18,8 +19,10 @@ import { ...@@ -18,8 +19,10 @@ import {
getManifestTitle, getManifestTitle,
getManifestThumbnail, getManifestThumbnail,
getManifestMetadata, getManifestMetadata,
getManifestRelated,
getManifestRelatedContent, getManifestRelatedContent,
getManifestRenderings, getManifestRenderings,
getManifestSeeAlso,
getManifestUrl, getManifestUrl,
getMetadataLocales, getMetadataLocales,
getRequiredStatement, getRequiredStatement,
...@@ -210,6 +213,33 @@ describe('getManifestRenderings', () => { ...@@ -210,6 +213,33 @@ describe('getManifestRenderings', () => {
}); });
}); });
describe('getManifestRelated', () => {
it('should return manifest related', () => {
const state = { manifests: { x: { json: manifestFixtureRelated } } };
const received = getManifestRelated(state, { manifestId: 'x' });
expect(received).toEqual([
{
value: 'http://example.com/related1',
},
{
format: undefined,
label: null,
value: 'http://example.com/related2',
},
{
format: 'text/html',
label: 'Something related',
value: 'http://example.com/related3',
},
]);
});
it('should return undefined if manifest undefined', () => {
const received = getManifestRelated({ manifests: {} }, { manifestId: 'x' });
expect(received).toBeUndefined();
});
});
describe('getManifestRelatedContent', () => { describe('getManifestRelatedContent', () => {
it('should return manifest seeAlso content', () => { it('should return manifest seeAlso content', () => {
const state = { manifests: { x: { json: manifestFixtureSn904cj3429 } } }; const state = { manifests: { x: { json: manifestFixtureSn904cj3429 } } };
...@@ -229,6 +259,25 @@ describe('getManifestRelatedContent', () => { ...@@ -229,6 +259,25 @@ describe('getManifestRelatedContent', () => {
}); });
}); });
describe('getManifestSeeAlso', () => {
it('should return manifest seeAlso content', () => {
const state = { manifests: { x: { json: manifestFixtureSn904cj3429 } } };
const received = getManifestSeeAlso(state, { manifestId: 'x' });
expect(received).toEqual([
{
format: 'application/mods+xml',
label: null,
value: 'https://purl.stanford.edu/sn904cj3429.mods',
},
]);
});
it('should return undefined if manifest undefined', () => {
const received = getManifestSeeAlso({ manifests: {} }, { manifestId: 'x' });
expect(received).toBeUndefined();
});
});
describe('getManifestUrl', () => { describe('getManifestUrl', () => {
it('should return manifest url', () => { it('should return manifest url', () => {
const state = { manifests: { x: { json: manifestFixtureWithAProvider } } }; const state = { manifests: { x: { json: manifestFixtureWithAProvider } } };
......
...@@ -20,6 +20,7 @@ export class ManifestRelatedLinks extends Component { ...@@ -20,6 +20,7 @@ export class ManifestRelatedLinks extends Component {
classes, classes,
homepage, homepage,
manifestUrl, manifestUrl,
related,
renderings, renderings,
seeAlso, seeAlso,
id, id,
...@@ -68,17 +69,34 @@ export class ManifestRelatedLinks extends Component { ...@@ -68,17 +69,34 @@ export class ManifestRelatedLinks extends Component {
} }
</> </>
)} )}
{ related && (
<>
<Typography variant="subtitle2" component="dt">{t('iiif_related')}</Typography>
{
related.map(relatedItem => (
<Typography key={relatedItem.value} variant="body1" component="dd">
<Link target="_blank" rel="noopener noreferrer" href={relatedItem.value}>
{relatedItem.label || relatedItem.value}
</Link>
{ relatedItem.format && (
<Typography component="span">{` (${relatedItem.format})`}</Typography>
)}
</Typography>
))
}
</>
)}
{ seeAlso && ( { seeAlso && (
<> <>
<Typography variant="subtitle2" component="dt">{t('iiif_seeAlso')}</Typography> <Typography variant="subtitle2" component="dt">{t('iiif_seeAlso')}</Typography>
{ {
seeAlso.map(related => ( seeAlso.map(seeAlsoItem => (
<Typography key={related.value} variant="body1" component="dd"> <Typography key={seeAlsoItem.value} variant="body1" component="dd">
<Link target="_blank" rel="noopener noreferrer" href={related.value}> <Link target="_blank" rel="noopener noreferrer" href={seeAlsoItem.value}>
{related.label || related.value} {seeAlsoItem.label || seeAlsoItem.value}
</Link> </Link>
{ related.format && ( { seeAlsoItem.format && (
<Typography component="span">{` (${related.format})`}</Typography> <Typography component="span">{` (${seeAlsoItem.format})`}</Typography>
)} )}
</Typography> </Typography>
)) ))
...@@ -110,6 +128,11 @@ ManifestRelatedLinks.propTypes = { ...@@ -110,6 +128,11 @@ ManifestRelatedLinks.propTypes = {
})), })),
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
manifestUrl: PropTypes.string, manifestUrl: PropTypes.string,
related: PropTypes.arrayOf(PropTypes.shape({
format: PropTypes.string,
label: PropTypes.string,
value: PropTypes.string,
})),
renderings: PropTypes.arrayOf(PropTypes.shape({ renderings: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string, label: PropTypes.string,
value: PropTypes.string, value: PropTypes.string,
...@@ -125,6 +148,7 @@ ManifestRelatedLinks.propTypes = { ...@@ -125,6 +148,7 @@ ManifestRelatedLinks.propTypes = {
ManifestRelatedLinks.defaultProps = { ManifestRelatedLinks.defaultProps = {
homepage: null, homepage: null,
manifestUrl: null, manifestUrl: null,
related: null,
renderings: null, renderings: null,
seeAlso: null, seeAlso: null,
t: key => key, t: key => key,
......
...@@ -5,8 +5,9 @@ import { withStyles } from '@material-ui/core/styles'; ...@@ -5,8 +5,9 @@ import { withStyles } from '@material-ui/core/styles';
import { withPlugins } from '../extend/withPlugins'; import { withPlugins } from '../extend/withPlugins';
import { import {
getManifestHomepage, getManifestHomepage,
getManifestRelatedContent, getManifestRelated,
getManifestRenderings, getManifestRenderings,
getManifestSeeAlso,
getManifestUrl, getManifestUrl,
} from '../state/selectors'; } from '../state/selectors';
import { ManifestRelatedLinks } from '../components/ManifestRelatedLinks'; import { ManifestRelatedLinks } from '../components/ManifestRelatedLinks';
...@@ -19,8 +20,9 @@ import { ManifestRelatedLinks } from '../components/ManifestRelatedLinks'; ...@@ -19,8 +20,9 @@ import { ManifestRelatedLinks } from '../components/ManifestRelatedLinks';
const mapStateToProps = (state, { id, windowId }) => ({ const mapStateToProps = (state, { id, windowId }) => ({
homepage: getManifestHomepage(state, { windowId }), homepage: getManifestHomepage(state, { windowId }),
manifestUrl: getManifestUrl(state, { windowId }), manifestUrl: getManifestUrl(state, { windowId }),
related: getManifestRelated(state, { windowId }),
renderings: getManifestRenderings(state, { windowId }), renderings: getManifestRenderings(state, { windowId }),
seeAlso: getManifestRelatedContent(state, { windowId }), seeAlso: getManifestSeeAlso(state, { windowId }),
}); });
const styles = { const styles = {
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
"hideZoomControls": "Zoomsteuerung verbergen", "hideZoomControls": "Zoomsteuerung verbergen",
"iiif_homepage": "Über diese Ressource", "iiif_homepage": "Über diese Ressource",
"iiif_manifest": "IIIF-Manifest", "iiif_manifest": "IIIF-Manifest",
"iiif_related": "Verwandtes",
"iiif_renderings": "Alternative Formate", "iiif_renderings": "Alternative Formate",
"iiif_seeAlso": "Siehe auch", "iiif_seeAlso": "Siehe auch",
"import" : "Importieren", "import" : "Importieren",
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
"hideZoomControls": "Hide zoom controls", "hideZoomControls": "Hide zoom controls",
"iiif_homepage": "About this resource", "iiif_homepage": "About this resource",
"iiif_manifest": "IIIF manifest", "iiif_manifest": "IIIF manifest",
"iiif_related": "Related",
"iiif_renderings": "Alternate formats", "iiif_renderings": "Alternate formats",
"iiif_seeAlso": "See also", "iiif_seeAlso": "See also",
"import" : "Import", "import" : "Import",
......
...@@ -153,13 +153,14 @@ export const getManifestRenderings = createSelector( ...@@ -153,13 +153,14 @@ export const getManifestRenderings = createSelector(
/** /**
* Return the IIIF v2/v3 seeAlso data from a manifest or null * Return the IIIF v2/v3 seeAlso data from a manifest or null
*
* @param {object} state * @param {object} state
* @param {object} props * @param {object} props
* @param {string} props.manifestId * @param {string} props.manifestId
* @param {string} props.windowId * @param {string} props.windowId
* @return {String|null} * @return {String|null}
*/ */
export const getManifestRelatedContent = createSelector( export const getManifestSeeAlso = createSelector(
[ [
getProperty('seeAlso'), getProperty('seeAlso'),
getManifestLocale, getManifestLocale,
...@@ -175,6 +176,48 @@ export const getManifestRelatedContent = createSelector( ...@@ -175,6 +176,48 @@ export const getManifestRelatedContent = createSelector(
)), )),
); );
/**
* Return the IIIF v2/v3 seeAlso data from a manifest or null
*
* @param {object} state
* @param {object} props
* @param {string} props.manifestId
* @param {string} props.windowId
* @return {String|null}
* @deprecated This does not actually return the content of "related" and
* might be removed in a future version.
* @see getManifestSeeAlso
*/
export const getManifestRelatedContent = getManifestSeeAlso;
/**
* Return the IIIF v2 realated links manifest or null
* @param {object} state
* @param {object} props
* @param {string} props.manifestId
* @param {string} props.windowId
* @return {String|null}
*/
export const getManifestRelated = createSelector(
[
getProperty('related'),
getManifestLocale,
],
(relatedLinks, locale) => relatedLinks
&& asArray(relatedLinks).map(related => (
typeof related === 'string'
? {
value: related,
}
: {
format: related.format,
label: PropertyValue.parse(related.label, locale)
.getValue(),
value: related.id || related['@id'],
}
)),
);
/** /**
* Return the IIIF requiredStatement (v3) or attribution (v2) data from a manifest or null * Return the IIIF requiredStatement (v3) or attribution (v2) data from a manifest or null
* @param {object} state * @param {object} state
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment