diff --git a/src/common/components/layouts/pages/inspect/Inspect.js b/src/common/components/layouts/pages/inspect/Inspect.js index 4190a16f..3170e3ba 100644 --- a/src/common/components/layouts/pages/inspect/Inspect.js +++ b/src/common/components/layouts/pages/inspect/Inspect.js @@ -8,6 +8,7 @@ import _ from 'lodash'; import AppPages from '../../../AppPages'; import { JOB_STATUS, TASK_STATUS } from '../../../../store/constants'; import { WARNING_MESSAGES } from '../../../../services/constants'; +import { scaleOptions } from './constants'; import { getTreeIds, setRulesTreeIds, getAvailableGroups } from '../../../../services/treeService'; import { lockApp, resetOnFileUpload, unlockApp } from '../../../../store/application/actions'; import { getJobStatus, getTaskStatus } from '../../../../store/job/selectors'; @@ -37,18 +38,11 @@ function Inspect({ tagsNames, jobStatus, taskStatus, ruleSummaries, lockApp, unl const [ruleSummariesFiltered, setRuleSummariesFiltered] = useState(ruleSummaries); const [errorsMap, setErrorsMap] = useState({}); const [scale, setScale] = useState('1'); + const [scaleMode, setScaleMode] = useState(''); const [isTreeShow, setIsTreeShow] = useState(false); const [treeData, setTreeData] = useState({}); const [roleMap, setRoleMap] = useState(false); - const scaleOptions = [ - { label: '50%', value: '0.5' }, - { label: '75%', value: '0.75' }, - { label: '100%', value: '1' }, - { label: '150%', value: '1.5' }, - { label: '200%', value: '2' }, - { label: '250%', value: '2.5' }, - { label: '300%', value: '3' }, - ]; + const onDocumentReady = useCallback( eMap => { setErrorsMap(eMap); @@ -133,7 +127,14 @@ function Inspect({ tagsNames, jobStatus, taskStatus, ruleSummaries, lockApp, unl showStructure: isTreeShow, })} > - + name); + +export const scaleOptions = { + advanced: [ + { label: 'Page fit', value: 'page-fit' }, + { label: 'Page width', value: 'page-width' }, + ], + basic: [ + { label: '50%', value: '0.5' }, + { label: '75%', value: '0.75' }, + { label: '100%', value: '1' }, + { label: '150%', value: '1.5' }, + { label: '200%', value: '2' }, + { label: '250%', value: '2.5' }, + { label: '300%', value: '3' }, + ], +}; +export const scaleBasicValues = scaleOptions.basic.map(({ value }) => value); +export const scaleAdvancedValues = scaleOptions.advanced.map(({ value }) => value); +export const scaleAutoValues = getRange(+scaleBasicValues[0], +scaleBasicValues.at(-1), 0.025, 3); diff --git a/src/common/components/layouts/pages/inspect/pdfDocument/PdfDocument.js b/src/common/components/layouts/pages/inspect/pdfDocument/PdfDocument.js index 308c7ccf..d07b5455 100644 --- a/src/common/components/layouts/pages/inspect/pdfDocument/PdfDocument.js +++ b/src/common/components/layouts/pages/inspect/pdfDocument/PdfDocument.js @@ -4,13 +4,16 @@ import PropTypes from 'prop-types'; import PdfViewer from 'verapdf-js-viewer'; import _ from 'lodash'; +import { useDebouncedResizeObserver } from '../../../../../hooks/useDebouncedResizeObserver'; import { getFileName, getPdfFiles } from '../../../../../store/pdfFiles/selectors'; import { getRuleSummaries } from '../../../../../store/job/result/selectors'; import { convertContextToPath, findAllMcid, getCheckId } from '../../../../../services/pdfService'; +import { findNearToOneIndexInSortArray } from '../../../../../services/treeService'; import { getPage, isFileUploadMode } from '../../../../../store/application/selectors'; import { setNumPages, setPage } from '../../../../../store/application/actions'; import { getItem } from '../../../../../services/localStorageService'; import { LS_ERROR_MESSAGES_LANGUAGE } from '../../../../../store/constants'; +import { scaleAdvancedValues, scaleAutoValues } from '../constants'; import { getProfile } from '../../../../../store/job/settings/selectors'; import { getFileNameLink } from '../../../../../store/pdfLink/selectors'; import { errorMessagesMap, errorProfiles, languageEnum } from '../tree/Tree'; @@ -39,10 +42,12 @@ PdfDocument.propTypes = { isTreeShow: PropTypes.bool.isRequired, expandedRules: PropTypes.arrayOf(PropTypes.number).isRequired, scale: PropTypes.string.isRequired, + scaleMode: PropTypes.string.isRequired, page: PropTypes.number.isRequired, initTree: PropTypes.func.isRequired, setSelectedCheck: PropTypes.func.isRequired, setSelectedNodeId: PropTypes.func.isRequired, + setScale: PropTypes.func.isRequired, setPdfName: PropTypes.func.isRequired, onPageChange: PropTypes.func.isRequired, setNumPages: PropTypes.func.isRequired, @@ -109,6 +114,7 @@ function getTitleDescription({ specification, clause, testNumber }, errorMessage } function PdfDocument(props) { + const { ref, width: wrapperWidth, height: wrapperHeight } = useDebouncedResizeObserver(500); const [structureTree, setStructureTree] = useState({}); const [mapOfErrors, setMapOfErrors] = useState({}); const [indicesOfVisibleErrors, setIndicesOfVisibleErrors] = useState(null); @@ -255,9 +261,42 @@ function PdfDocument(props) { }); setIndicesOfVisibleErrors(indicesOfVisibleBboxes); }, [createMapOfErrors, props.ruleSummariesFiltered, structureTree, mapOfErrors]); + useEffect(() => { + if (!scaleAdvancedValues.includes(props.scaleMode)) { + return; + } + + const pdfPage = document.querySelector('.pdf-page'); + + if (!_.isNil(wrapperWidth) && !_.isNil(wrapperHeight) && !_.isNil(pdfPage)) { + const { width: pageWidth, height: pageHeight } = pdfPage.getBoundingClientRect(); + let ratio; + + switch (props.scaleMode) { + case scaleAdvancedValues[0]: { + ratio = Math.max(pageWidth / wrapperWidth, pageHeight / wrapperHeight); + break; + } + case scaleAdvancedValues[1]: { + ratio = pageWidth / wrapperWidth; + break; + } + default: { + ratio = 1; + break; + } + } + + props.setScale(prev => { + const index = findNearToOneIndexInSortArray(scaleAutoValues.map(value => (ratio * value) / prev)); + return scaleAutoValues[index] ?? prev; + }); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.scaleMode, wrapperWidth, wrapperHeight]); return ( -
+
{props.warningMessage && ( {props.warningMessage} diff --git a/src/common/components/layouts/pages/inspect/structure/Structure.js b/src/common/components/layouts/pages/inspect/structure/Structure.js index f82f383b..981d4308 100644 --- a/src/common/components/layouts/pages/inspect/structure/Structure.js +++ b/src/common/components/layouts/pages/inspect/structure/Structure.js @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; +import useResizeObserver from 'use-resize-observer'; import _ from 'lodash'; -import useResizeObserver from 'use-resize-observer'; import { makeStyles } from '@material-ui/core/styles'; import List from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; diff --git a/src/common/components/layouts/pages/inspect/toolbar/Toolbar.js b/src/common/components/layouts/pages/inspect/toolbar/Toolbar.js index ca0bcd4a..457e20f2 100644 --- a/src/common/components/layouts/pages/inspect/toolbar/Toolbar.js +++ b/src/common/components/layouts/pages/inspect/toolbar/Toolbar.js @@ -2,12 +2,13 @@ import React, { useCallback, useMemo } from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { useHistory } from 'react-router-dom'; +import _ from 'lodash'; + import ArrowBack from '@material-ui/icons/ArrowBack'; import AddIcon from '@material-ui/icons/Add'; import RemoveIcon from '@material-ui/icons/Remove'; import IconButton from '@material-ui/core/IconButton'; import Typography from '@material-ui/core/Typography'; -import _ from 'lodash'; import AppPages from '../../../../AppPages'; import { getJobId } from '../../../../../store/job/selectors'; @@ -16,23 +17,26 @@ import Select from '../../../../shared/select/Select'; import Pagination from '../../../../shared/pagination/Pagination'; import { getNumPages, getPage } from '../../../../../store/application/selectors'; import { setPage } from '../../../../../store/application/actions'; +import { scaleAdvancedValues } from '../constants'; import './Toolbar.scss'; const BACK = 'Back to summary'; -function Toolbar({ jobId, name, scale, scaleOptions, page, numPages, onScaleChanged, setPage }) { +function Toolbar({ jobId, name, scale, mode, scaleOptions, page, numPages, onScaleChanged, onModeChanged, setPage }) { const history = useHistory(); + const isAutozoom = useMemo(() => scaleAdvancedValues.includes(mode), [mode]); const onBackClick = useMemo(() => () => history.push(AppPages.RESULTS.url(jobId)), [history, jobId]); - const currentScaleIndex = useMemo(() => _.findIndex(scaleOptions, { value: scale }), [scaleOptions, scale]); + const currentScaleIndex = useMemo(() => _.findIndex(scaleOptions.basic, { value: scale }), [scaleOptions, scale]); + const onZoomIn = useCallback(() => { - if (currentScaleIndex < scaleOptions.length - 1) { - onScaleChanged(scaleOptions[currentScaleIndex + 1].value); + if (currentScaleIndex < scaleOptions.basic.length - 1) { + onScaleChanged(scaleOptions.basic[currentScaleIndex + 1].value); } }, [scaleOptions, currentScaleIndex, onScaleChanged]); const onZoomOut = useCallback(() => { if (currentScaleIndex > 0) { - onScaleChanged(scaleOptions[currentScaleIndex - 1].value); + onScaleChanged(scaleOptions.basic[currentScaleIndex - 1].value); } }, [scaleOptions, currentScaleIndex, onScaleChanged]); @@ -51,19 +55,25 @@ function Toolbar({ jobId, name, scale, scaleOptions, page, numPages, onScaleChan
- + - +