@cu-mkp/editioncrafter 1.1.0-beta.1 → 1.2.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/editioncrafter.js +20709 -18672
  2. package/dist/es/src/{action → EditionCrafter/action}/DocumentActions.js +8 -0
  3. package/dist/es/src/{action → EditionCrafter/action}/initialState/documentInitialState.js +7 -0
  4. package/dist/es/src/{component → EditionCrafter/component}/DiploMatic.js +17 -14
  5. package/dist/es/src/{component → EditionCrafter/component}/DocumentView.js +16 -6
  6. package/dist/es/src/EditionCrafter/component/Navigation.js +446 -0
  7. package/dist/es/src/{component → EditionCrafter/component}/RouteListener.js +3 -3
  8. package/dist/es/src/EditionCrafter/component/TagToolbar.jsx +57 -0
  9. package/dist/es/src/{component → EditionCrafter/component}/TranscriptionView.js +27 -7
  10. package/dist/es/src/EditionCrafter/context/TagFilter.jsx +61 -0
  11. package/dist/es/src/EditionCrafter/context/TagFilterContext.js +8 -0
  12. package/dist/es/src/EditionCrafter/icons/DocumentPagesIcon.jsx +18 -0
  13. package/dist/es/src/{model → EditionCrafter/model}/Folio.js +27 -1
  14. package/dist/es/src/{model → EditionCrafter/model}/folioLayout.js +6 -5
  15. package/dist/es/src/{saga → EditionCrafter/saga}/RouteListenerSaga.js +44 -3
  16. package/dist/es/src/{scss → EditionCrafter/scss}/_base.scss +11 -1
  17. package/dist/es/src/{scss → EditionCrafter/scss}/_diplomatic.scss +15 -24
  18. package/dist/es/src/EditionCrafter/scss/_navigation.scss +468 -0
  19. package/dist/es/src/{scss → EditionCrafter/scss}/_transcriptView.scss +50 -41
  20. package/dist/es/src/{scss → EditionCrafter/scss}/editioncrafter.scss +2 -1
  21. package/dist/es/src/RecordList/component/CollapsibleMenu.jsx +22 -0
  22. package/dist/es/src/RecordList/component/Loading.jsx +12 -0
  23. package/dist/es/src/RecordList/component/Pill.jsx +10 -0
  24. package/dist/es/src/RecordList/component/Record.jsx +82 -0
  25. package/dist/es/src/RecordList/component/RecordListView.jsx +109 -0
  26. package/dist/es/src/RecordList/component/Sidebar.jsx +83 -0
  27. package/dist/es/src/RecordList/component/SidebarTagList.jsx +38 -0
  28. package/dist/es/src/RecordList/context/FilterContext.jsx +8 -0
  29. package/dist/es/src/RecordList/index.jsx +92 -0
  30. package/dist/es/src/RecordList/lib/sql.js +9 -0
  31. package/dist/es/src/RecordList/styles/base.css +78 -0
  32. package/dist/es/src/RecordList/styles/record.css +84 -0
  33. package/dist/es/src/RecordList/styles/sidebar.css +39 -0
  34. package/dist/es/src/{index.js → index.jsx} +6 -3
  35. package/package.json +6 -3
  36. package/dist/es/src/component/Navigation.js +0 -402
  37. package/dist/es/src/hooks/useIsWidthUp.js +0 -9
  38. package/dist/es/src/lib/registerServiceWorker.js +0 -111
  39. package/dist/es/src/scss/_navigation.scss +0 -209
  40. /package/dist/es/src/{action → EditionCrafter/action}/DiplomaticActions.js +0 -0
  41. /package/dist/es/src/{action → EditionCrafter/action}/GlossaryActions.js +0 -0
  42. /package/dist/es/src/{action → EditionCrafter/action}/initialState/diplomaticInitialState.js +0 -0
  43. /package/dist/es/src/{action → EditionCrafter/action}/initialState/glossaryInitialState.js +0 -0
  44. /package/dist/es/src/{action → EditionCrafter/action}/rootReducer.js +0 -0
  45. /package/dist/es/src/{component → EditionCrafter/component}/AlphabetLinks.js +0 -0
  46. /package/dist/es/src/{component → EditionCrafter/component}/CustomizedTooltops.js +0 -0
  47. /package/dist/es/src/{component → EditionCrafter/component}/EditorComment.js +0 -0
  48. /package/dist/es/src/{component → EditionCrafter/component}/ErrorBoundary.js +0 -0
  49. /package/dist/es/src/{component → EditionCrafter/component}/FigureImage.js +0 -0
  50. /package/dist/es/src/{component → EditionCrafter/component}/GlossaryView.js +0 -0
  51. /package/dist/es/src/{component → EditionCrafter/component}/HelpPopper.js +0 -0
  52. /package/dist/es/src/{component → EditionCrafter/component}/ImageGridView.js +0 -0
  53. /package/dist/es/src/{component → EditionCrafter/component}/ImageView.js +0 -0
  54. /package/dist/es/src/{component → EditionCrafter/component}/ImageZoomControl.js +0 -0
  55. /package/dist/es/src/{component → EditionCrafter/component}/JumpToFolio.js +0 -0
  56. /package/dist/es/src/{component → EditionCrafter/component}/Pagination.js +0 -0
  57. /package/dist/es/src/{component → EditionCrafter/component}/Parser.js +0 -0
  58. /package/dist/es/src/{component → EditionCrafter/component}/RingSpinner.js +0 -0
  59. /package/dist/es/src/{component → EditionCrafter/component}/SeaDragonComponent.js +0 -0
  60. /package/dist/es/src/{component → EditionCrafter/component}/SinglePaneView.js +0 -0
  61. /package/dist/es/src/{component → EditionCrafter/component}/SplitPaneView.js +0 -0
  62. /package/dist/es/src/{component → EditionCrafter/component}/Watermark.js +0 -0
  63. /package/dist/es/src/{component → EditionCrafter/component}/XMLView.js +0 -0
  64. /package/dist/es/src/{icons → EditionCrafter/icons}/ByIcon.js +0 -0
  65. /package/dist/es/src/{icons → EditionCrafter/icons}/CcIcon.js +0 -0
  66. /package/dist/es/src/{icons → EditionCrafter/icons}/NcIcon.js +0 -0
  67. /package/dist/es/src/{icons → EditionCrafter/icons}/SaIcon.js +0 -0
  68. /package/dist/es/src/{icons → EditionCrafter/icons}/SideMenuIconLeft.js +0 -0
  69. /package/dist/es/src/{icons → EditionCrafter/icons}/SideMenuIconRight.js +0 -0
  70. /package/dist/es/src/{icons → EditionCrafter/icons}/howtouse-asterisk.png +0 -0
  71. /package/dist/es/src/{icons → EditionCrafter/icons}/howtouse-curly.png +0 -0
  72. /package/dist/es/src/{icons → EditionCrafter/icons}/howtouse-square.png +0 -0
  73. /package/dist/es/src/{icons → EditionCrafter/icons}/howtouse-ups.png +0 -0
  74. /package/dist/es/src/{img → EditionCrafter/img}/banner-about.png +0 -0
  75. /package/dist/es/src/{img → EditionCrafter/img}/banner-essays.jpg +0 -0
  76. /package/dist/es/src/{img → EditionCrafter/img}/banner-essays.png +0 -0
  77. /package/dist/es/src/{img → EditionCrafter/img}/banner-how-to.png +0 -0
  78. /package/dist/es/src/{img → EditionCrafter/img}/banner-resources.png +0 -0
  79. /package/dist/es/src/{img → EditionCrafter/img}/book-open-cropped.png +0 -0
  80. /package/dist/es/src/{img → EditionCrafter/img}/book-open.png +0 -0
  81. /package/dist/es/src/{img → EditionCrafter/img}/book-spine.png +0 -0
  82. /package/dist/es/src/{img → EditionCrafter/img}/bookcover-cropped.png +0 -0
  83. /package/dist/es/src/{img → EditionCrafter/img}/cropped-MKLizardFilled-32x32.jpg +0 -0
  84. /package/dist/es/src/{img → EditionCrafter/img}/editioncrafterlogo.png +0 -0
  85. /package/dist/es/src/{img → EditionCrafter/img}/folio48r-drawing.png +0 -0
  86. /package/dist/es/src/{img → EditionCrafter/img}/howtouse-asterisk.png +0 -0
  87. /package/dist/es/src/{img → EditionCrafter/img}/howtouse-beaker.png +0 -0
  88. /package/dist/es/src/{img → EditionCrafter/img}/howtouse-curly.png +0 -0
  89. /package/dist/es/src/{img → EditionCrafter/img}/howtouse-square.png +0 -0
  90. /package/dist/es/src/{img → EditionCrafter/img}/howtouse-ups.png +0 -0
  91. /package/dist/es/src/{img → EditionCrafter/img}/lizard-no-bg.png +0 -0
  92. /package/dist/es/src/{img → EditionCrafter/img}/logo_center_multi_line.png +0 -0
  93. /package/dist/es/src/{img → EditionCrafter/img}/logo_center_single_line.png +0 -0
  94. /package/dist/es/src/{img → EditionCrafter/img}/logo_columbia.png +0 -0
  95. /package/dist/es/src/{img → EditionCrafter/img}/mk-banner-logo.png +0 -0
  96. /package/dist/es/src/{img → EditionCrafter/img}/mk-homepage-logo.png +0 -0
  97. /package/dist/es/src/{img → EditionCrafter/img}/spinner.gif +0 -0
  98. /package/dist/es/src/{img → EditionCrafter/img}/text-bg.png +0 -0
  99. /package/dist/es/src/{img → EditionCrafter/img}/watermark.png +0 -0
  100. /package/dist/es/src/{lib → EditionCrafter/lib}/copyObject.js +0 -0
  101. /package/dist/es/src/{model → EditionCrafter/model}/DocumentHelper.js +0 -0
  102. /package/dist/es/src/{model → EditionCrafter/model}/ReduxStore.js +0 -0
  103. /package/dist/es/src/{saga → EditionCrafter/saga}/rootSaga.js +0 -0
  104. /package/dist/es/src/{scss → EditionCrafter/scss}/_CETEIcean.scss +0 -0
  105. /package/dist/es/src/{scss → EditionCrafter/scss}/_globalNavigation.scss +0 -0
  106. /package/dist/es/src/{scss → EditionCrafter/scss}/_glossary.scss +0 -0
  107. /package/dist/es/src/{scss → EditionCrafter/scss}/_imageGridView.scss +0 -0
  108. /package/dist/es/src/{scss → EditionCrafter/scss}/_imageView.scss +0 -0
  109. /package/dist/es/src/{scss → EditionCrafter/scss}/_imageZoomControl.scss +0 -0
  110. /package/dist/es/src/{scss → EditionCrafter/scss}/_jumpbox.scss +0 -0
  111. /package/dist/es/src/{scss → EditionCrafter/scss}/_pagination.scss +0 -0
  112. /package/dist/es/src/{scss → EditionCrafter/scss}/_ringSpinner.scss +0 -0
  113. /package/dist/es/src/{scss → EditionCrafter/scss}/_singlePaneView.scss +0 -0
  114. /package/dist/es/src/{scss → EditionCrafter/scss}/_spinner.scss +0 -0
  115. /package/dist/es/src/{scss → EditionCrafter/scss}/_splitPaneView.scss +0 -0
  116. /package/dist/es/src/{scss → EditionCrafter/scss}/_thumbnails.scss +0 -0
  117. /package/dist/es/src/{scss → EditionCrafter/scss}/_watermark.scss +0 -0
  118. /package/dist/es/src/{scss → EditionCrafter/scss}/_xmlView.scss +0 -0
@@ -16,12 +16,20 @@ DocumentActions.loadDocument = function loadDocument(state, manifestData) {
16
16
  }
17
17
  }
18
18
 
19
+ DocumentActions.loadTags = function loadTags(state, tags) {
20
+ return {
21
+ ...state,
22
+ tags,
23
+ }
24
+ }
25
+
19
26
  DocumentActions.loadFolio = function loadFolio(state, folio) {
20
27
  const oldFolio = state.folioIndex[folio.id]
21
28
  const folioIdx = state.folios.indexOf(oldFolio)
22
29
  state.folios[folioIdx] = folio
23
30
  state.folioIndex[folio.id] = folio
24
31
  state.folioByName[folio.name] = folio
32
+
25
33
  return {
26
34
  ...state,
27
35
  }
@@ -1,8 +1,14 @@
1
+ function getHeaderUrlFromManifestUrl(manifestUrl) {
2
+ const truncated = manifestUrl.replace('/iiif/manifest.json', '')
3
+ return `${truncated}/html/index.html`
4
+ }
5
+
1
6
  export default function documentInitalState(iiifManifest, documentName, transcriptionTypes, variorum = false, derivativeNames = null, threePanel = false) {
2
7
  return {
3
8
  documentName,
4
9
  derivativeNames,
5
10
  manifestURL: iiifManifest,
11
+ headerUrl: getHeaderUrlFromManifestUrl(iiifManifest),
6
12
  transcriptionTypes,
7
13
  variorum,
8
14
  threePanel,
@@ -10,5 +16,6 @@ export default function documentInitalState(iiifManifest, documentName, transcri
10
16
  loaded: false,
11
17
  folioIndex: {},
12
18
  folioByName: {},
19
+ tags: null,
13
20
  }
14
21
  }
@@ -9,6 +9,7 @@ import {
9
9
  Route,
10
10
  Routes,
11
11
  } from 'react-router-dom'
12
+ import TagFilterProvider from '../context/TagFilter'
12
13
  import DocumentView from './DocumentView'
13
14
  import RouteListener from './RouteListener'
14
15
 
@@ -38,27 +39,29 @@ function DiploMatic(props) {
38
39
  return (
39
40
  <Provider store={props.store}>
40
41
  <HashRouter>
41
- <div id="diplomatic" className={fixedFrameModeClass} ref={containerRef} style={{ height: containerHeight }}>
42
- <RouteListener />
43
- <div id="content" style={{ height: '100%' }}>
44
- <Routes>
45
- <Route path="/ec/:folioID/:transcriptionType/:folioID2/:transcriptionType2/:folioID3/:transcriptionType3" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
46
- <Route path="/ec/:folioID/:transcriptionType/:folioID2/:transcriptionType2" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
47
- <Route path="/ec/:folioID/:transcriptionType" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
48
- <Route path="/ec/:folioID" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
49
- <Route path="/ec" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
50
- <Route path="/" element={<Navigate to="/ec" />} exact />
51
- </Routes>
42
+ <TagFilterProvider>
43
+ <div id="diplomatic" className={fixedFrameModeClass} ref={containerRef} style={{ height: containerHeight }}>
44
+ <RouteListener />
45
+ <div id="content" style={{ height: '100%' }}>
46
+ <Routes>
47
+ <Route path="/ec/:folioID/:transcriptionType/:folioID2/:transcriptionType2/:folioID3/:transcriptionType3" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
48
+ <Route path="/ec/:folioID/:transcriptionType/:folioID2/:transcriptionType2" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
49
+ <Route path="/ec/:folioID/:transcriptionType" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
50
+ <Route path="/ec/:folioID" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
51
+ <Route path="/ec" element={<DocumentView {...props} containerWidth={containerWidth} />} exact />
52
+ <Route path="/" element={<Navigate to="/ec" />} exact />
53
+ </Routes>
54
+ </div>
52
55
  </div>
53
- </div>
56
+ </TagFilterProvider>
54
57
  </HashRouter>
55
58
  </Provider>
56
59
  )
57
60
  }
58
61
 
59
62
  DiploMatic.propTypes = {
60
- store: PropTypes.isRequired,
61
- config: PropTypes.isRequired,
63
+ store: PropTypes.object.isRequired,
64
+ config: PropTypes.object.isRequired,
62
65
  }
63
66
 
64
67
  function mapStateToProps(state) {
@@ -34,7 +34,7 @@ function DocumentView(props) {
34
34
 
35
35
  // "reload" the page if the config props change
36
36
  useEffect(() => {
37
- dispatchAction(props, 'RouteListenerSaga.userNavigatation', location)
37
+ dispatchAction(props, 'RouteListenerSaga.userNavigation', location.pathname)
38
38
  }, [props.config])
39
39
 
40
40
  useEffect(() => {
@@ -429,7 +429,9 @@ function DocumentView(props) {
429
429
  side={side}
430
430
  />
431
431
  )
432
- } if (viewType === 'TranscriptionView') {
432
+ }
433
+
434
+ if (viewType === 'TranscriptionView') {
433
435
  return (
434
436
  <TranscriptionView
435
437
  key={key}
@@ -440,7 +442,9 @@ function DocumentView(props) {
440
442
  transcriptionType={transcriptionType}
441
443
  />
442
444
  )
443
- } if (viewType === 'XMLView') {
445
+ }
446
+
447
+ if (viewType === 'XMLView') {
444
448
  return (
445
449
  <XMLView
446
450
  key={key}
@@ -451,7 +455,9 @@ function DocumentView(props) {
451
455
  side={side}
452
456
  />
453
457
  )
454
- } if (viewType === 'ImageGridView') {
458
+ }
459
+
460
+ if (viewType === 'ImageGridView') {
455
461
  return (
456
462
  <ImageGridView
457
463
  key={key}
@@ -461,7 +467,9 @@ function DocumentView(props) {
461
467
  selectedDoc={document || props.document.variorum && Object.keys(props.document.derivativeNames)[side === 'left' ? 0 : side === 'right' ? 1 : Object.keys(props.document.derivativeNames).length > 2 ? 2 : 1]}
462
468
  />
463
469
  )
464
- } if (viewType === 'GlossaryView') {
470
+ }
471
+
472
+ if (viewType === 'GlossaryView') {
465
473
  return (
466
474
  <GlossaryView
467
475
  key={key}
@@ -492,7 +500,9 @@ function DocumentView(props) {
492
500
  return `${side}-${pane.viewType}`
493
501
  }
494
502
 
495
- if (!props.document.loaded) { return null }
503
+ if (!props.document.loaded) {
504
+ return null
505
+ }
496
506
 
497
507
  // combine component state with state from props
498
508
  const docView = {
@@ -0,0 +1,446 @@
1
+ import MenuItem from '@material-ui/core/MenuItem'
2
+ import Select from '@material-ui/core/Select'
3
+ import React, { useMemo, useRef, useState } from 'react'
4
+ import { BsFillGrid3X3GapFill } from 'react-icons/bs'
5
+ import {
6
+ FaCode,
7
+ FaQuestionCircle,
8
+ } from 'react-icons/fa'
9
+ import { GoTag } from 'react-icons/go'
10
+ import { HiOutlineBookOpen } from 'react-icons/hi'
11
+ import { IoArrowBackCircleOutline, IoArrowForwardCircleOutline, IoLockOpenOutline } from 'react-icons/io5'
12
+ import { connect } from 'react-redux'
13
+ import DocumentPagesIcon from '../icons/DocumentPagesIcon'
14
+ import DocumentHelper from '../model/DocumentHelper'
15
+ import AlphabetLinks from './AlphabetLinks'
16
+ import HelpPopper from './HelpPopper'
17
+ import JumpToFolio from './JumpToFolio'
18
+ import TagToolbar from './TagToolbar'
19
+
20
+ const initialPopoverObj = {
21
+ anchorEl: null,
22
+ }
23
+
24
+ function NavArrows(props) {
25
+ return (
26
+ <>
27
+ <span
28
+ title="Go back"
29
+ onClick={props.changeCurrentFolio}
30
+ data-id={props.documentView[props.side].previousFolioShortID}
31
+ className={(!props.documentView[props.side].hasPrevious) ? 'disabled nav-arrow' : 'nav-arrow'}
32
+ >
33
+ <IoArrowBackCircleOutline />
34
+ </span>
35
+
36
+ <span
37
+ title="Go forward"
38
+ onClick={props.changeCurrentFolio}
39
+ data-id={props.documentView[props.side].nextFolioShortID}
40
+ className={(!props.documentView[props.side].hasNext) ? 'disabled nav-arrow' : 'nav-arrow'}
41
+ >
42
+ <IoArrowForwardCircleOutline />
43
+ </span>
44
+ </>
45
+ )
46
+ }
47
+
48
+ function GridViewButton(props) {
49
+ return (
50
+ <button
51
+ className="grid-view-button"
52
+ style={{ cursor: props.documentView[props.side].transcriptionType !== 'g' ? 'pointer' : 'default', padding: '0 15px' }}
53
+ title={props.documentView[props.side].transcriptionType !== 'g' && 'Return to Grid View'}
54
+ onClick={props.documentView[props.side].transcriptionType !== 'g' && props.onGoToGrid}
55
+ type="button"
56
+ >
57
+ <BsFillGrid3X3GapFill />
58
+ </button>
59
+ )
60
+ }
61
+
62
+ function ToggleButton(props) {
63
+ return (
64
+ <button
65
+ className={`toggle-button ${props.active ? 'active' : ''}`}
66
+ onClick={props.onClick}
67
+ title="Toggle XML Mode"
68
+ type="button"
69
+ >
70
+ <props.icon />
71
+ </button>
72
+ )
73
+ }
74
+
75
+ function Navigation(props) {
76
+ const [popover, setPopover] = useState({ ...initialPopoverObj })
77
+ const [openHelp, setOpenHelp] = useState(false)
78
+ const [openHelpNarrow, setOpenHelpNarrow] = useState(false)
79
+ const [openTags, setOpenTags] = useState(false)
80
+
81
+ const helpRef = useRef(null)
82
+ const helpRefNarrow = useRef(null)
83
+
84
+ const onJumpBoxBlur = () => {
85
+ setPopover({ anchorEl: null })
86
+ }
87
+
88
+ const changeType = (event) => {
89
+ if (event.target.value === undefined || event.target.value === 0)
90
+ return
91
+ props.documentViewActions.changeTranscriptionType(
92
+ props.side,
93
+ event.target.value,
94
+ )
95
+ }
96
+
97
+ const onGoToGrid = () => {
98
+ props.documentViewActions.changeTranscriptionType(props.side, 'g')
99
+ }
100
+
101
+ const toggleHelp = () => {
102
+ setOpenHelp(!openHelp)
103
+ }
104
+
105
+ const toggleHelpNarrow = () => {
106
+ setOpenHelpNarrow(!openHelpNarrow)
107
+ }
108
+
109
+ const toggleTags = () => setOpenTags(!openTags)
110
+
111
+ const toggleBookmode = () => {
112
+ if (!props.documentView.bookMode) {
113
+ props.documentViewActions.changeCurrentFolio(
114
+ props.documentView.left.iiifShortID,
115
+ 'left',
116
+ props.documentView.left.transcriptionType,
117
+ )
118
+
119
+ props.documentViewActions.changeCurrentFolio(
120
+ props.documentView.left.nextFolioShortID,
121
+ 'right',
122
+ props.documentView.left.transcriptionType,
123
+ )
124
+ }
125
+
126
+ props.documentViewActions.setBookMode(
127
+ props.documentView.left.iiifShortID,
128
+ !props.documentView.bookMode,
129
+ )
130
+ }
131
+
132
+ const toggleXMLMode = () => {
133
+ props.documentViewActions.setXMLMode(
134
+ props.side,
135
+ !props.documentView[props.side].isXMLMode,
136
+ )
137
+ }
138
+
139
+ const toggleLockmode = () => {
140
+ if (props.documentView.bookMode) {
141
+ toggleBookmode()
142
+ return
143
+ }
144
+
145
+ // If we are transitioning from unlocked to locked, sync up the panes
146
+ if (props.documentView.linkedMode === false) {
147
+ if (props.side === 'left') {
148
+ props.documentViewActions.changeCurrentFolio(
149
+ props.documentView.left.iiifShortID,
150
+ 'right',
151
+ props.documentView.right.transcriptionType,
152
+ )
153
+ }
154
+ else {
155
+ props.documentViewActions.changeCurrentFolio(
156
+ props.documentView.right.iiifShortID,
157
+ 'left',
158
+ props.documentView.left.transcriptionType,
159
+ )
160
+ }
161
+ }
162
+
163
+ // Set lock
164
+ props.documentViewActions.setLinkedMode(
165
+ !props.documentView.linkedMode,
166
+ )
167
+ }
168
+
169
+ const changeCurrentFolio = (event) => {
170
+ const {
171
+ documentViewActions,
172
+ documentView,
173
+ side,
174
+ } = props
175
+
176
+ if (typeof event.currentTarget.dataset.id === 'undefined' || event.currentTarget.dataset.id.length === 0) {
177
+ return
178
+ }
179
+ const folioID = event.currentTarget.dataset.id
180
+ documentViewActions.changeCurrentFolio(
181
+ folioID,
182
+ side,
183
+ documentView[side].transcriptionType,
184
+ )
185
+ }
186
+
187
+ const revealJumpBox = (event) => {
188
+ setPopover({
189
+ anchorEl: event.currentTarget,
190
+ })
191
+ }
192
+
193
+ const {
194
+ side,
195
+ document,
196
+ documentView,
197
+ documentViewActions,
198
+ onFilterChange,
199
+ } = props
200
+
201
+ const selectColorStyle = documentView[side].transcriptionType === 'f' ? { color: 'white' } : { color: 'black' }
202
+ const selectClass = documentView[side].transcriptionType === 'f' ? 'dark' : 'light'
203
+ const showButtonsStyle = documentView[side].transcriptionType === 'glossary' ? { visibility: 'hidden' } : { visibility: 'visible' }
204
+ const selectContainerStyle = { display: 'flex' } // what's the reason we want this to be hidden sometimes?
205
+ const imageViewActive = documentView[side].transcriptionType === 'f'
206
+ const folioName = document.folioIndex[documentView[side].iiifShortID]?.name
207
+ // this is messy but faster for the moment then figuring out why the sides dont behave the same
208
+ const helpMarginStyle = side === 'left' ? { marginRight: '55px' } : { marginRight: '15px' }
209
+
210
+ const folio = folioName
211
+ ? document.folioByName[folioName]
212
+ : null
213
+
214
+ const docHasTags = useMemo(
215
+ () => folio?.tagIds && folio.tagIds.length > 0 && document.tags && Object.keys(document.tags).length > 0,
216
+ [folio, document],
217
+ )
218
+
219
+ if (!documentView) {
220
+ return (
221
+ <div>
222
+ Unknown Transcription Type
223
+ </div>
224
+ )
225
+ }
226
+
227
+ return (
228
+ <div>
229
+ <div className="navigationComponent">
230
+
231
+ { documentView[side].transcriptionType !== 'glossary'
232
+ ? (
233
+
234
+ <div id="tool-bar-buttons" className="breadcrumbs" style={showButtonsStyle}>
235
+
236
+ <div className="toolbar-side toolbar-left">
237
+ <GridViewButton
238
+ documentView={documentView}
239
+ onGoToGrid={onGoToGrid}
240
+ side={side}
241
+ />
242
+ <div className="folio-path" style={{ display: 'flex', overflowX: 'hidden', justifyContent: 'flex-end' }}>
243
+ <span
244
+ className="document-title"
245
+ title={props.documentName || document.documentName}
246
+ >
247
+ {props.documentName || document.documentName}
248
+ </span>
249
+ <span>/</span>
250
+ <div
251
+ onClick={revealJumpBox}
252
+ className="folioName"
253
+ style={{ flexShrink: '0', minWidth: '40px' }}
254
+ title={folioName}
255
+ >
256
+ {folioName}
257
+ </div>
258
+ </div>
259
+
260
+ <NavArrows
261
+ changeCurrentFolio={changeCurrentFolio}
262
+ side={side}
263
+ documentView={documentView}
264
+ />
265
+ </div>
266
+
267
+ <div className="toolbar-side toolbar-right">
268
+ <div
269
+ className="book-mode-toggles"
270
+ title="Toggle book mode"
271
+ onClick={toggleBookmode}
272
+ >
273
+ <button className={props.documentView.bookMode ? 'selected' : ''} type="button">
274
+ <HiOutlineBookOpen />
275
+ </button>
276
+ <button className={props.documentView.bookMode ? '' : 'selected'} type="button">
277
+ <DocumentPagesIcon />
278
+ </button>
279
+ </div>
280
+
281
+ <label className="lockmode-container">
282
+ <input
283
+ onChange={toggleLockmode}
284
+ title="Toggle coordination of views"
285
+ type="checkbox"
286
+ value={props.documentView.linkedMode}
287
+ />
288
+ <span className="switch">
289
+ <span className="slider">
290
+ <IoLockOpenOutline />
291
+ </span>
292
+ </span>
293
+ </label>
294
+
295
+ <div className="vertical-separator" />
296
+
297
+ <Select
298
+ className={selectClass}
299
+ style={{ ...selectColorStyle, marginRight: 15, fontSize: 'max(16px, 1rem)' }}
300
+ value={documentView[side].transcriptionType}
301
+ id="doc-type"
302
+ onClick={changeType}
303
+ >
304
+ {Object.keys(props.document.folios.find(fol => (fol.id === props.documentView[props.side].iiifShortID)).annotationURLs).map(ttKey => (
305
+ <MenuItem value={ttKey} key={ttKey}>{props.document.variorum ? props.document.transcriptionTypes[props.document.folios.find(fol => (fol.id === props.documentView[props.side].iiifShortID)).doc_id][ttKey] : props.document.transcriptionTypes[ttKey]}</MenuItem>
306
+ ))}
307
+ <MenuItem value="f" key="f">
308
+ {DocumentHelper.transcriptionTypeLabels.f}
309
+ </MenuItem>
310
+ { props.glossary && (
311
+ <MenuItem value="glossary" key="glossary">
312
+ {DocumentHelper.transcriptionTypeLabels.glossary}
313
+ </MenuItem>
314
+ ) }
315
+ </Select>
316
+ {!imageViewActive && (
317
+ <ToggleButton
318
+ onClick={toggleXMLMode}
319
+ active={props.documentView[props.side].isXMLMode}
320
+ icon={FaCode}
321
+ />
322
+ )}
323
+ <div className="vertical-separator" />
324
+ {docHasTags && (
325
+ <ToggleButton
326
+ active={openTags}
327
+ onClick={toggleTags}
328
+ icon={GoTag}
329
+ />
330
+ )}
331
+ <button
332
+ title="Toggle folio help"
333
+ className={`toggle-button ${openHelp ? 'active' : ''}`}
334
+ onClick={toggleHelp}
335
+ ref={helpRef}
336
+ type="button"
337
+ >
338
+ <FaQuestionCircle />
339
+ <HelpPopper
340
+ marginStyle={helpMarginStyle}
341
+ anchorEl={helpRef.current}
342
+ open={openHelp}
343
+ onClose={toggleHelp}
344
+ />
345
+ </button>
346
+ </div>
347
+
348
+ <JumpToFolio
349
+ side={side}
350
+ anchorEl={popover.anchorEl}
351
+ submitHandler={documentViewActions.jumpToFolio}
352
+ blurHandler={onJumpBoxBlur}
353
+ />
354
+
355
+ </div>
356
+ )
357
+ : (<AlphabetLinks onFilterChange={onFilterChange} value={props.value} />)}
358
+
359
+ </div>
360
+ {openTags && (
361
+ <TagToolbar
362
+ document={props.document}
363
+ folio={folio}
364
+ toggleTags={toggleTags}
365
+ />
366
+ )}
367
+ <div className="navigationComponentNarrow">
368
+ { documentView[side].transcriptionType !== 'glossary'
369
+ ? (
370
+
371
+ <div id="tool-bar-buttons" className="breadcrumbsNarrow" style={showButtonsStyle}>
372
+
373
+ <GridViewButton
374
+ documentView={documentView}
375
+ onGoToGrid={onGoToGrid}
376
+ side={side}
377
+ />
378
+ &nbsp;
379
+
380
+ {!imageViewActive && (
381
+ <ToggleButton
382
+ onClick={toggleXMLMode}
383
+ active={props.documentView[props.side].isXMLMode}
384
+ icon={FaCode}
385
+ />
386
+ )}
387
+
388
+ { imageViewActive && (
389
+ <NavArrows
390
+ changeCurrentFolio={changeCurrentFolio}
391
+ side={side}
392
+ documentView={documentView}
393
+ />
394
+ )}
395
+
396
+ </div>
397
+ )
398
+ : (<AlphabetLinks onFilterChange={onFilterChange} value={props.value} />)}
399
+
400
+ <div id="doc-type-help" style={selectContainerStyle} ref={helpRefNarrow}>
401
+ <Select
402
+ className={selectClass}
403
+ style={{ ...selectColorStyle, marginRight: 15, fontSize: 'max(16px, 1rem)' }}
404
+ value={documentView[side].transcriptionType}
405
+ id="doc-type"
406
+ onClick={changeType}
407
+ >
408
+ {Object.keys(props.document.folios.find(fol => (fol.id === props.documentView[props.side].iiifShortID)).annotationURLs).map(ttKey => (
409
+ <MenuItem value={ttKey} key={ttKey} title={ttKey}>{props.document.variorum ? props.document.transcriptionTypes[props.document.folios.find(fol => (fol.id === props.documentView[props.side].iiifShortID)).doc_id][ttKey] : props.document.transcriptionTypes[ttKey]}</MenuItem>
410
+ ))}
411
+ <MenuItem value="f" key="f">
412
+ {DocumentHelper.transcriptionTypeLabels.f}
413
+ </MenuItem>
414
+ { props.glossary && (
415
+ <MenuItem value="glossary" key="glossary">
416
+ {DocumentHelper.transcriptionTypeLabels.glossary}
417
+ </MenuItem>
418
+ ) }
419
+ </Select>
420
+ <span
421
+ title="Toggle folio help"
422
+ onClick={toggleHelpNarrow}
423
+ className="helpIcon"
424
+ >
425
+ <FaQuestionCircle />
426
+ </span>
427
+ <HelpPopper
428
+ marginStyle={helpMarginStyle}
429
+ anchorEl={helpRefNarrow.current}
430
+ open={openHelpNarrow}
431
+ onClose={toggleHelpNarrow}
432
+ />
433
+ </div>
434
+ </div>
435
+ </div>
436
+ )
437
+ }
438
+
439
+ function mapStateToProps(state) {
440
+ return {
441
+ document: state.document,
442
+ glossary: !!state.glossary.URL,
443
+ }
444
+ }
445
+
446
+ export default (connect(mapStateToProps)(Navigation))
@@ -7,10 +7,10 @@ import { dispatchAction } from '../model/ReduxStore'
7
7
  function RouteListener(props) {
8
8
  const listening = useRef(false)
9
9
 
10
- const location = useLocation()
10
+ const { pathname } = useLocation()
11
11
 
12
12
  const userNavigated = () => {
13
- dispatchAction(props, 'RouteListenerSaga.userNavigatation', location)
13
+ dispatchAction(props, 'RouteListenerSaga.userNavigation', pathname)
14
14
  }
15
15
 
16
16
  useEffect(() => {
@@ -22,7 +22,7 @@ function RouteListener(props) {
22
22
 
23
23
  useEffect(() => {
24
24
  userNavigated()
25
- }, [location])
25
+ }, [pathname])
26
26
 
27
27
  return null
28
28
  }
@@ -0,0 +1,57 @@
1
+ import { useContext } from 'react'
2
+ import { BsCheck, BsX } from 'react-icons/bs'
3
+ import { GoTag } from 'react-icons/go'
4
+ import TagFilterContext from '../context/TagFilterContext'
5
+
6
+ function TagPill(props) {
7
+ return (
8
+ <button
9
+ className={props.isActive ? 'active' : ''}
10
+ onClick={props.onClick}
11
+ type="button"
12
+ >
13
+ {props.isActive && <BsCheck />}
14
+ {props.name}
15
+ </button>
16
+ )
17
+ }
18
+
19
+ function TagToolbar(props) {
20
+ const { tags, toggleTag } = useContext(TagFilterContext)
21
+
22
+ return (
23
+ <div className="tag-bar">
24
+ <div className="tag-list">
25
+ <span className="tag-label">
26
+ <GoTag />
27
+ Tags
28
+ </span>
29
+ {props.folio.tagIds.map((xmlId) => {
30
+ const name = props.document.tags[xmlId]
31
+
32
+ if (name) {
33
+ return (
34
+ <TagPill
35
+ isActive={tags.includes(xmlId)}
36
+ key={xmlId}
37
+ name={name}
38
+ onClick={() => toggleTag(xmlId)}
39
+ />
40
+ )
41
+ }
42
+
43
+ return null
44
+ })}
45
+ </div>
46
+ <button
47
+ className="tag-bar-close"
48
+ onClick={props.toggleTags}
49
+ type="button"
50
+ >
51
+ <BsX />
52
+ </button>
53
+ </div>
54
+ )
55
+ }
56
+
57
+ export default TagToolbar