Skip to content
Snippets Groups Projects
Select Git revision
  • 7f582b6643f5798bf9f0d8959057efe41ce51a08
  • master default protected
  • dev
3 results

functions.php

Blame
  • CollectionDialog.js 8.72 KiB
    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import {
      Button,
      Chip,
      Dialog,
      DialogActions,
      DialogTitle,
      Link,
      MenuList,
      MenuItem,
      Typography,
    } from '@mui/material';
    import ArrowBackIcon from '@mui/icons-material/ArrowBackSharp';
    import Skeleton from '@mui/material/Skeleton';
    import asArray from '../lib/asArray';
    import { LabelValueMetadata } from './LabelValueMetadata';
    import CollapsibleSection from '../containers/CollapsibleSection';
    import ScrollIndicatedDialogContent from '../containers/ScrollIndicatedDialogContent';
    import ManifestInfo from '../containers/ManifestInfo';
    
    /**
     * a dialog providing the possibility to select the collection
     */
    export class CollectionDialog extends Component {
      /** */
      static getUseableLabel(resource, index) {
        return (resource
          && resource.getLabel
          && resource.getLabel().length > 0)
          ? resource.getLabel().getValue()
          : String(index + 1);
      }
    
      /** */
      constructor(props) {
        super(props);
    
        this.state = { filter: null };
        this.hideDialog = this.hideDialog.bind(this);
      }
    
      /** */
      setFilter(filter) {
        this.setState({ filter });
      }
    
      /** */
      hideDialog() {
        const {
          hideCollectionDialog, windowId,
        } = this.props;
    
        hideCollectionDialog(windowId);
      }
    
      /** */
      selectCollection(c) {
        const {
          collectionPath,
          manifestId,
          showCollectionDialog,
          windowId,
        } = this.props;
    
        showCollectionDialog(c.id, [...collectionPath, manifestId], windowId);
      }
    
      /** */
      goToPreviousCollection() {
        const { collectionPath, showCollectionDialog, windowId } = this.props;
    
        showCollectionDialog(
          collectionPath[collectionPath.length - 1],
          collectionPath.slice(0, -1),
          windowId,
        );
      }
    
      /** */
      selectManifest(m) {
        const {
          addWindow,
          collectionPath,
          manifestId,
          setWorkspaceAddVisibility,
          updateWindow,
          windowId,
        } = this.props;
    
        if (windowId) {
          updateWindow(windowId, {
            canvasId: null, collectionPath: [...collectionPath, manifestId], manifestId: m.id,
          });
        } else {
          addWindow({ collectionPath: [...collectionPath, manifestId], manifestId: m.id });
        }
    
        this.hideDialog();
        setWorkspaceAddVisibility(false);
      }
    
      /** */
      dialogContainer() {
        const { containerId, windowId } = this.props;
        return document.querySelector(`#${containerId} #${windowId}`);
      }
    
      /** */
      placeholder() {
        const { classes } = this.props;
    
        return (
          <Dialog
            className={classes.dialog}
            onClose={this.hideDialog}
            open
            container={this.dialogContainer()}
            BackdropProps={this.backdropProps()}
          >
            <DialogTitle id="select-collection">
              <Skeleton className={classes.placeholder} variant="text" />
            </DialogTitle>
            <ScrollIndicatedDialogContent>
              <Skeleton className={classes.placeholder} variant="text" />
              <Skeleton className={classes.placeholder} variant="text" />
            </ScrollIndicatedDialogContent>
          </Dialog>
        );
      }
    
      /** */
      backdropProps() {
        const { classes } = this.props;
        return { classes: { root: classes.dialog } };
      }
    
      /** */
      render() {
        const {
          classes,
          collection,
          error,
          isMultipart,
          manifest,
          ready,
          t,
        } = this.props;
    
        const { filter } = this.state;
    
        if (error) return null;
        // If this component is optimistically rendering ahead of the window its in
        // force a re-render so that it is placed correctly. The right thing here is
        // to maybe pass a ref.
        if (!this.dialogContainer()) {
          this.forceUpdate();
          return null;
        }
        if (!ready) return this.placeholder();
    
        const rights = manifest && (asArray(manifest.getProperty('rights') || manifest.getProperty('license')));
    
        const requiredStatement = manifest
          && asArray(manifest.getRequiredStatement()).filter(l => l.getValue()).map(labelValuePair => ({
            label: null,
            values: labelValuePair.getValues(),
          }));
    
        const collections = manifest.getCollections();
    
        const currentFilter = filter || (collections.length > 0 ? 'collections' : 'manifests');
    
        return (
          <Dialog
            className={classes.dialog}
            onClose={this.hideDialog}
            container={this.dialogContainer()}
            BackdropProps={this.backdropProps()}
            open
          >
            <DialogTitle id="select-collection">
              <Typography component="div" variant="overline">
                { t(isMultipart ? 'multipartCollection' : 'collection') }
              </Typography>
              <Typography variant="h3">
                {CollectionDialog.getUseableLabel(manifest)}
              </Typography>
            </DialogTitle>
            <ScrollIndicatedDialogContent className={classes.dialogContent}>
              { collection && (
                <Button
                  startIcon={<ArrowBackIcon />}
                  onClick={() => this.goToPreviousCollection()}
                >
                  {CollectionDialog.getUseableLabel(collection)}
                </Button>
              )}
    
              <div className={classes.collectionMetadata}>
                <ManifestInfo manifestId={manifest.id} />
                <CollapsibleSection
                  id="select-collection-rights"
                  label={t('attributionTitle')}
                >
                  { requiredStatement && (
                    <LabelValueMetadata labelValuePairs={requiredStatement} defaultLabel={t('attribution')} />
                  )}
                  {
                    rights && rights.length > 0 && (
                      <>
                        <Typography variant="subtitle2" component="dt">{t('rights')}</Typography>
                        { rights.map(v => (
                          <Typography variant="body1" component="dd" key={v}>
                            <Link target="_blank" rel="noopener noreferrer" href={v} underline="hover">
                              {v}
                            </Link>
                          </Typography>
                        )) }
                      </>
                    )
                  }
                </CollapsibleSection>
              </div>
              <div className={classes.collectionFilter}>
                {manifest.getTotalCollections() > 0 && (
                  <Chip clickable color={currentFilter === 'collections' ? 'primary' : 'default'} onClick={() => this.setFilter('collections')} label={t('totalCollections', { count: manifest.getTotalCollections() })} />
                )}
                {manifest.getTotalManifests() > 0 && (
                  <Chip clickable color={currentFilter === 'manifests' ? 'primary' : 'default'} onClick={() => this.setFilter('manifests')} label={t('totalManifests', { count: manifest.getTotalManifests() })} />
                )}
              </div>
              { currentFilter === 'collections' && (
                <MenuList>
                  {
                    collections.map(c => (
                      <MenuItem
                        key={c.id}
                        onClick={() => { this.selectCollection(c); }}
                        className={classes.collectionItem}
                      >
                        {CollectionDialog.getUseableLabel(c)}
                      </MenuItem>
                    ))
                  }
                </MenuList>
              )}
              { currentFilter === 'manifests' && (
                <MenuList>
                  {
                    manifest.getManifests().map(m => (
                      <MenuItem
                        key={m.id}
                        onClick={() => { this.selectManifest(m); }}
                        className={classes.collectionItem}
                      >
                        {CollectionDialog.getUseableLabel(m)}
                      </MenuItem>
                    ))
                  }
                </MenuList>
              )}
            </ScrollIndicatedDialogContent>
            <DialogActions>
              <Button onClick={this.hideDialog}>
                {t('close')}
              </Button>
            </DialogActions>
          </Dialog>
        );
      }
    }
    
    CollectionDialog.propTypes = {
      addWindow: PropTypes.func.isRequired,
      classes: PropTypes.objectOf(PropTypes.string).isRequired,
      collection: PropTypes.object, // eslint-disable-line react/forbid-prop-types
      collectionPath: PropTypes.arrayOf(PropTypes.string),
      containerId: PropTypes.string,
      error: PropTypes.string,
      hideCollectionDialog: PropTypes.func.isRequired,
      isMultipart: PropTypes.bool,
      manifest: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
      manifestId: PropTypes.string.isRequired,
      ready: PropTypes.bool,
      setWorkspaceAddVisibility: PropTypes.func.isRequired,
      showCollectionDialog: PropTypes.func.isRequired,
      t: PropTypes.func.isRequired,
      updateWindow: PropTypes.func.isRequired,
      windowId: PropTypes.string,
    };
    
    CollectionDialog.defaultProps = {
      collection: null,
      collectionPath: [],
      containerId: null,
      error: null,
      isMultipart: false,
      ready: false,
      windowId: null,
    };