Skip to content
Snippets Groups Projects
Commit 92c0cb06 authored by Anthony's avatar Anthony
Browse files

Merge branch '18-upgrade-pour-coeso' into 'annotation-on-video'

Add research field and undo research manifest in annotation content

Closes #18

See merge request iiif/mirador-video-annotation!15
parents 735afa7d 885df11b
Branches
Tags
1 merge request!15Add research field and undo research manifest in annotation content
Pipeline #1393 failed
......@@ -24,16 +24,6 @@ export class AnnotationManifestsAccordion extends Component {
this.handleOpenManifestSideToSide = this.handleOpenManifestSideToSide.bind(this);
this.handleOpenAccordion = this.handleOpenAccordion.bind(this);
/** Search manifest directly in content. We consider all the links with #manifest at the end are manifest */
function searchManifestInContent(text) {
if (text == null) {
return null;
}
return text.match(
/((http|https)\:\/\/[a-z0-9\/:%_+.,#?!@&=-]+)#manifest/gi,
);
}
/** Search if the annotation is a manifest. URL must be resolvable for the annotation. So the manifest url is added at the end of the id */
function searchManifestInID(id) {
const match = id.match(
......@@ -45,17 +35,13 @@ export class AnnotationManifestsAccordion extends Component {
const { annotation } = this.props;
/** Merge array even if some are null) */
const concat = (...arrays) => [].concat(...arrays.filter(Array.isArray));
annotation.manifests = concat(searchManifestInContent(annotation.content), searchManifestInID(annotation.id));
annotation.manifests = searchManifestInID(annotation.id);
if (annotation.manifests) {
annotation.manifests = annotation.manifests.map(id => ({ id }));
} else {
annotation.manifests = [];
}
annotation.manifests = removeDuplicates(annotation.manifests);
this.state = { annotation };
}
......
......@@ -6,9 +6,15 @@ import MenuList from '@material-ui/core/MenuList';
import MenuItem from '@material-ui/core/MenuItem';
import ListItemText from '@material-ui/core/ListItemText';
import Typography from '@material-ui/core/Typography';
import SearchIcon from '@material-ui/icons/SearchSharp';
import InputBase from '@material-ui/core/InputBase';
import CircularProgress from '@material-ui/core/CircularProgress';
import TextField from '@material-ui/core/TextField';
import SanitizedHtml from '../containers/SanitizedHtml';
import { ScrollTo } from './ScrollTo';
import AnnotationManifestsAccordion from '../containers/AnnotationManifestsAccordion';
import { filterAnnotation } from '../helper/utils';
import { MiradorMenuButton } from './MiradorMenuButton';
/**
* CanvasAnnotations ~
......@@ -23,6 +29,9 @@ export class CanvasAnnotations extends Component {
this.handleClick = this.handleClick.bind(this);
this.handleAnnotationHover = this.handleAnnotationHover.bind(this);
this.handleAnnotationBlur = this.handleAnnotationBlur.bind(this);
this.handleAnnotationSearch = this.handleAnnotationSearch.bind(this);
this.state = { };
}
/**
......@@ -54,21 +63,51 @@ export class CanvasAnnotations extends Component {
hoverAnnotation(windowId, []);
}
/** */
handleAnnotationSearch(event) {
this.setState({ inputSearch: event.target.value });
}
/**
* Returns the rendered component
*/
render() {
const {
annotations, autoScroll, classes, index, label, selectedAnnotationId, t, totalSize,
autoScroll, classes, index, label, selectedAnnotationId, t, totalSize,
listContainerComponent, htmlSanitizationRuleSet, hoveredAnnotationIds,
containerRef,
} = this.props;
let { annotations } = this.props;
if (annotations.length === 0) return null;
const { inputSearch } = this.state;
if (inputSearch != undefined && inputSearch !== '') {
annotations = filterAnnotation(annotations, inputSearch);
}
const annotationCount = annotations.length;
return (
<>
<Typography className={classes.sectionHeading} variant="overline">
{t('annotationCanvasLabel', { context: `${index + 1}/${totalSize}`, label })}
</Typography>
<div className={classes.headerAnnotationPanel}>
<TextField
label={t('searchPlaceholderAnnotation')}
onChange={this.handleAnnotationSearch}
className={classes.searchAnnotationsTextfield}
InputProps={{
endAdornment: (
<div className={classes.endAdornment}>
<MiradorMenuButton aria-label={t('searchAnnotationTooltip')} type="submit">
<SearchIcon />
</MiradorMenuButton>
</div>
),
}}
/>
</div>
<MenuList autoFocusItem variant="selectedMenu">
{
annotations.map(annotation => (
......@@ -117,7 +156,18 @@ export class CanvasAnnotations extends Component {
</ScrollTo>
))
}
{annotations.length == 0
&& (
<MenuItem>
<Typography>
{t('noAnnotationFound')}
</Typography>
</MenuItem>
)}
</MenuList>
<div className={classes.footerAnnotationPanel}>
<Typography component="p" variant="subtitle2">{t('showingNumAnnotations', { count: annotationCount, number: annotationCount })}</Typography>
</div>
</>
);
}
......
import { createRef, Component } from 'react';
import PropTypes from 'prop-types';
import Typography from '@material-ui/core/Typography';
import AnnotationSettings from '../containers/AnnotationSettings';
import CanvasAnnotations from '../containers/CanvasAnnotations';
import CompanionWindow from '../containers/CompanionWindow';
......@@ -34,10 +33,6 @@ export class WindowSideBarAnnotationsPanel extends Component {
otherRef={this.containerRef}
titleControls={<AnnotationSettings windowId={windowId} />}
>
<div className={classes.section}>
<Typography component="p" variant="subtitle2">{t('showingNumAnnotations', { count: annotationCount, number: annotationCount })}</Typography>
</div>
{canvasIds.map((canvasId, index) => (
<CanvasAnnotations
canvasId={canvasId}
......
import { compose } from 'redux';
import { connect } from 'react-redux';
import { withTranslation } from 'react-i18next';
import { withStyles } from '@material-ui/core/styles';
import { alpha, withStyles } from '@material-ui/core/styles';
import { withPlugins } from '../extend/withPlugins';
import * as actions from '../state/actions';
import {
......@@ -69,16 +69,39 @@ const styles = theme => ({
marginRight: theme.spacing(0.5),
marginTop: theme.spacing(1),
},
hovered: {},
manifestLabel: {
fontSize: '10px',
endAdornment: {
position: 'absolute',
right: 0,
},
sectionHeading: {
footerAnnotationPanel: {
background: theme.palette.background.paper,
borderTop: `.5px solid ${theme.palette.section_divider}`,
bottom: 0,
paddingBottom: theme.spacing(1),
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(1),
paddingTop: theme.spacing(2),
position: 'sticky',
},
grow: {
flexGrow: 1,
},
headerAnnotationPanel: {
background: theme.palette.background.paper,
borderBottom: `.5px solid ${theme.palette.section_divider}`,
marginBottom: theme.spacing(1),
padding: theme.spacing(0, 1, 1, 1),
position: 'sticky',
top: 0,
zIndex: 10,
},
hovered: {},
manifestLabel: {
fontSize: '10px',
},
searchAnnotationsTextfield: {
width: '100%',
},
});
const enhance = compose(
......
/**
* Remove duplicate elements in array
*
* Filter annotation with a query string. Search in ID and value
* */
export const removeDuplicates = (arr) => [...new Map(arr.map(v => [v.id, v])).values()];
export const filterAnnotation = (annotations, query) => annotations.filter((annotation) => {
// eslint-disable-next-line max-len
const queryLowered = query.toLowerCase();
return annotation.id.toLowerCase().includes(queryLowered) || annotation.content.toLowerCase().includes(queryLowered);
});
......@@ -96,6 +96,7 @@
"multipartCollection": "Multipart Collection",
"nextCanvas": "Next item",
"noItemSelected": "No item selected",
"noAnnotationFound": "No annotation found",
"numItems_one": "{{number}} item",
"numItems_other": "{{number}} items",
"off": "Off",
......@@ -118,6 +119,7 @@
"right": "Right",
"rights": "License",
"scroll": "Scroll",
"searchAnnotationTooltip": "Filter annotations",
"searchInputLabel": "search terms",
"searchNextResult": "Next result",
"searchNoResults": "No results found",
......@@ -125,6 +127,7 @@
"searchResultsRemaining": "{{numLeft}} remaining",
"searchSubmitAria": "Submit search",
"searchTitle": "Search",
"searchPlaceholderAnnotation" : "Filter...",
"selectWorkspaceMenu": "Select workspace type",
"showingNumAnnotations_one": "Showing {{number}} annotation",
"showingNumAnnotations_other": "Showing {{number}} annotations",
......
......@@ -92,6 +92,7 @@
"moveCompanionWindowToRight": "Déplacer à droite",
"nextCanvas": "Suivant",
"noItemSelected": "Aucun élément sélectionné",
"noAnnotationFound": "Aucune annotation trouvé",
"numItems_one": "{{number}} image",
"numItems_other": "{{number}} images",
"off": "aucun",
......@@ -114,9 +115,11 @@
"right": "Droite",
"rights": "Licence",
"scroll": "Défilement horizontal",
"searchAnnotationTooltip": "Filtrer les annotations",
"searchInputLabel": "Chercher un mot",
"searchNextResult": "Résultat suivant",
"searchNoResults": "Aucun résultat trouvé",
"searchPlaceholderAnnotation" : "Filtrer...",
"searchPreviousResult": "Résultat précédent",
"searchSubmitAria": "Lancer la recherche",
"searchTitle": "Rechercher",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment