@harvard-lts/mirador-pdf-plugin 0.0.3 → 0.0.5
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.
- package/README.md +5 -3
- package/dist/es/index.js +84 -42
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -57,6 +57,7 @@ Mirador.viewer(
|
|
|
57
57
|
],
|
|
58
58
|
miradorPdfPlugin: {
|
|
59
59
|
pdfAPI: 'https://your-pdf-service.example.com/pdf/download/',
|
|
60
|
+
maxPages: 500,
|
|
60
61
|
},
|
|
61
62
|
},
|
|
62
63
|
[...Plugin]
|
|
@@ -65,9 +66,10 @@ Mirador.viewer(
|
|
|
65
66
|
|
|
66
67
|
### Config options
|
|
67
68
|
|
|
68
|
-
| Option
|
|
69
|
-
|
|
|
70
|
-
| `pdfAPI`
|
|
69
|
+
| Option | Type | Description |
|
|
70
|
+
| ---------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
71
|
+
| `pdfAPI` | String | Base URL of the PDF download service (required). |
|
|
72
|
+
| `maxPages` | Number | Maximum pages allowed in a single request (default: 500). Keep this in sync with the service's `MAX_PAGES_PER_REQUEST` env var so client/server agree. |
|
|
71
73
|
|
|
72
74
|
### URL construction
|
|
73
75
|
|
package/dist/es/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
1
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
2
2
|
import MenuItem from '@material-ui/core/MenuItem';
|
|
3
3
|
import ListItemIcon from '@material-ui/core/ListItemIcon';
|
|
4
4
|
import ListItemText from '@material-ui/core/ListItemText';
|
|
@@ -183,7 +183,7 @@ var miradorPdfMenuItem = {
|
|
|
183
183
|
};
|
|
184
184
|
|
|
185
185
|
var mapStateToProps = function mapStateToProps(state, _ref) {
|
|
186
|
-
var _manifest$getSequence, _state$config;
|
|
186
|
+
var _manifest$getSequence, _state$config, _state$config2;
|
|
187
187
|
var windowId = _ref.windowId;
|
|
188
188
|
var manifest = getManifestoInstance(state, {
|
|
189
189
|
windowId: windowId
|
|
@@ -193,6 +193,7 @@ var mapStateToProps = function mapStateToProps(state, _ref) {
|
|
|
193
193
|
manifestId: (manifest || {}).id,
|
|
194
194
|
totalPages: manifest ? ((_manifest$getSequence = manifest.getSequences()[0]) === null || _manifest$getSequence === void 0 ? void 0 : _manifest$getSequence.getTotalCanvases()) || 0 : 0,
|
|
195
195
|
pdfAPI: (_state$config = state.config) === null || _state$config === void 0 || (_state$config = _state$config.miradorPdfPlugin) === null || _state$config === void 0 ? void 0 : _state$config.pdfAPI,
|
|
196
|
+
maxPages: ((_state$config2 = state.config) === null || _state$config2 === void 0 || (_state$config2 = _state$config2.miradorPdfPlugin) === null || _state$config2 === void 0 ? void 0 : _state$config2.maxPages) || 500,
|
|
196
197
|
containerId: state.config.id
|
|
197
198
|
};
|
|
198
199
|
};
|
|
@@ -212,67 +213,102 @@ var extractUrn = function extractUrn(manifestId) {
|
|
|
212
213
|
var withoutLeadingSlash = pathname.replace(/^\//, '');
|
|
213
214
|
return withoutLeadingSlash.split(':MANIFEST')[0];
|
|
214
215
|
};
|
|
216
|
+
|
|
217
|
+
// Pure validation of the pages input. Returns { valid, message } so it can drive
|
|
218
|
+
// both the inline error text and the disabled state of the Download button
|
|
219
|
+
// without setting React state during render.
|
|
220
|
+
var validatePages = function validatePages(pages, totalPages, maxPages) {
|
|
221
|
+
if (pages === '') {
|
|
222
|
+
// Empty input means "all pages" — only valid if the whole document fits.
|
|
223
|
+
if (totalPages > maxPages) {
|
|
224
|
+
return {
|
|
225
|
+
valid: false,
|
|
226
|
+
message: "This document has ".concat(totalPages, " pages, which exceeds the ").concat(maxPages, "-page limit. Please enter a range of up to ").concat(maxPages, " pages.")
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
return {
|
|
230
|
+
valid: true,
|
|
231
|
+
message: ''
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
var singlePattern = /^\d+$/;
|
|
235
|
+
var rangePattern = /^(\d+)-(\d+)$/;
|
|
236
|
+
if (singlePattern.test(pages)) {
|
|
237
|
+
var num = parseInt(pages, 10);
|
|
238
|
+
if (num < 1 || num > totalPages) {
|
|
239
|
+
return {
|
|
240
|
+
valid: false,
|
|
241
|
+
message: "Page must be between 1 and ".concat(totalPages, ".")
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
valid: true,
|
|
246
|
+
message: ''
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
var rangeMatch = pages.match(rangePattern);
|
|
250
|
+
if (rangeMatch) {
|
|
251
|
+
var start = parseInt(rangeMatch[1], 10);
|
|
252
|
+
var end = parseInt(rangeMatch[2], 10);
|
|
253
|
+
if (start < 1 || end > totalPages) {
|
|
254
|
+
return {
|
|
255
|
+
valid: false,
|
|
256
|
+
message: "Page range must be between 1 and ".concat(totalPages, ".")
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (start >= end) {
|
|
260
|
+
return {
|
|
261
|
+
valid: false,
|
|
262
|
+
message: 'Start page must be less than end page.'
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
if (end - start + 1 > maxPages) {
|
|
266
|
+
return {
|
|
267
|
+
valid: false,
|
|
268
|
+
message: "You can request at most ".concat(maxPages, " pages at once. Please split this into smaller requests.")
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
return {
|
|
272
|
+
valid: true,
|
|
273
|
+
message: ''
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
valid: false,
|
|
278
|
+
message: 'Please enter a page number or range (e.g. 5 or 5-10).'
|
|
279
|
+
};
|
|
280
|
+
};
|
|
215
281
|
var MiradorPdfDialog = function MiradorPdfDialog(_ref3) {
|
|
216
282
|
var open = _ref3.open,
|
|
217
283
|
closeDialog = _ref3.closeDialog,
|
|
218
284
|
manifestId = _ref3.manifestId,
|
|
219
285
|
totalPages = _ref3.totalPages,
|
|
220
286
|
pdfAPI = _ref3.pdfAPI,
|
|
287
|
+
maxPages = _ref3.maxPages,
|
|
221
288
|
containerId = _ref3.containerId,
|
|
222
289
|
classes = _ref3.classes;
|
|
223
290
|
var _useState = useState(''),
|
|
224
291
|
_useState2 = _slicedToArray(_useState, 2),
|
|
225
292
|
pages = _useState2[0],
|
|
226
293
|
setPages = _useState2[1];
|
|
227
|
-
var _useState3 = useState(''),
|
|
228
|
-
_useState4 = _slicedToArray(_useState3, 2),
|
|
229
|
-
error = _useState4[0],
|
|
230
|
-
setError = _useState4[1];
|
|
231
294
|
|
|
232
295
|
// Reset form state whenever the dialog is closed
|
|
233
296
|
useEffect(function () {
|
|
234
297
|
if (!open) {
|
|
235
298
|
setPages('');
|
|
236
|
-
setError('');
|
|
237
299
|
}
|
|
238
300
|
}, [open]);
|
|
239
301
|
var handleClose = function handleClose() {
|
|
240
302
|
closeDialog();
|
|
241
303
|
setPages('');
|
|
242
|
-
setError('');
|
|
243
|
-
};
|
|
244
|
-
var validate = function validate() {
|
|
245
|
-
if (pages === '') return true;
|
|
246
|
-
var singlePattern = /^\d+$/;
|
|
247
|
-
var rangePattern = /^(\d+)-(\d+)$/;
|
|
248
|
-
if (singlePattern.test(pages)) {
|
|
249
|
-
var num = parseInt(pages, 10);
|
|
250
|
-
if (num < 1 || num > totalPages) {
|
|
251
|
-
setError("Page must be between 1 and ".concat(totalPages, "."));
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
var rangeMatch = pages.match(rangePattern);
|
|
257
|
-
if (rangeMatch) {
|
|
258
|
-
var start = parseInt(rangeMatch[1], 10);
|
|
259
|
-
var end = parseInt(rangeMatch[2], 10);
|
|
260
|
-
if (start < 1 || end > totalPages) {
|
|
261
|
-
setError("Page range must be between 1 and ".concat(totalPages, "."));
|
|
262
|
-
return false;
|
|
263
|
-
}
|
|
264
|
-
if (start >= end) {
|
|
265
|
-
setError('Start page must be less than end page.');
|
|
266
|
-
return false;
|
|
267
|
-
}
|
|
268
|
-
return true;
|
|
269
|
-
}
|
|
270
|
-
setError('Please enter a page number or range (e.g. 5 or 5-10).');
|
|
271
|
-
return false;
|
|
272
304
|
};
|
|
305
|
+
|
|
306
|
+
// Live validity drives both the disabled Download button and the helper text.
|
|
307
|
+
var validity = useMemo(function () {
|
|
308
|
+
return validatePages(pages, totalPages, maxPages);
|
|
309
|
+
}, [pages, totalPages, maxPages]);
|
|
273
310
|
var handleDownload = function handleDownload() {
|
|
274
|
-
|
|
275
|
-
if (!validate()) return;
|
|
311
|
+
if (!validity.valid) return;
|
|
276
312
|
var urn = extractUrn(manifestId);
|
|
277
313
|
var baseUrl = "".concat(pdfAPI.replace(/\/$/, ''), "/").concat(urn);
|
|
278
314
|
var url;
|
|
@@ -309,7 +345,11 @@ var MiradorPdfDialog = function MiradorPdfDialog(_ref3) {
|
|
|
309
345
|
children: [/*#__PURE__*/jsx(Typography, {
|
|
310
346
|
variant: "body1",
|
|
311
347
|
gutterBottom: true,
|
|
312
|
-
children: "The document contains ".concat(totalPages, " pages and has an estimated file size of ").concat((totalPages * 0.7862).toFixed(2), " MB. All pages will be included by default. If you wish to download certain portions of it, you may provide a
|
|
348
|
+
children: "The document contains ".concat(totalPages, " pages and has an estimated file size of ").concat((totalPages * 0.7862).toFixed(2), " MB. All pages will be included by default. If you wish to download certain portions of it, you may provide a single page (e.g. 5) or a range (e.g. 5-10).")
|
|
349
|
+
}), /*#__PURE__*/jsx(Typography, {
|
|
350
|
+
variant: "body2",
|
|
351
|
+
gutterBottom: true,
|
|
352
|
+
children: "You can download up to ".concat(maxPages, " pages per request. For larger documents, please request several smaller ranges (e.g. 1-").concat(maxPages, ", then ").concat(maxPages + 1, "-").concat(maxPages * 2, ").")
|
|
313
353
|
}), /*#__PURE__*/jsx(TextField, {
|
|
314
354
|
id: "pdf-pages-input",
|
|
315
355
|
label: "Pages",
|
|
@@ -320,8 +360,8 @@ var MiradorPdfDialog = function MiradorPdfDialog(_ref3) {
|
|
|
320
360
|
onKeyDown: function onKeyDown(e) {
|
|
321
361
|
if (e.key === 'Enter') handleDownload();
|
|
322
362
|
},
|
|
323
|
-
error:
|
|
324
|
-
helperText:
|
|
363
|
+
error: !validity.valid,
|
|
364
|
+
helperText: validity.valid ? "Enter a page number or range (e.g. 5 or 5-10). Max ".concat(maxPages, " pages per request.") : validity.message,
|
|
325
365
|
fullWidth: true,
|
|
326
366
|
margin: "normal",
|
|
327
367
|
variant: "outlined"
|
|
@@ -335,6 +375,7 @@ var MiradorPdfDialog = function MiradorPdfDialog(_ref3) {
|
|
|
335
375
|
onClick: handleDownload,
|
|
336
376
|
color: "primary",
|
|
337
377
|
variant: "contained",
|
|
378
|
+
disabled: !validity.valid,
|
|
338
379
|
children: "Download"
|
|
339
380
|
})]
|
|
340
381
|
})]
|
|
@@ -342,6 +383,7 @@ var MiradorPdfDialog = function MiradorPdfDialog(_ref3) {
|
|
|
342
383
|
};
|
|
343
384
|
MiradorPdfDialog.defaultProps = {
|
|
344
385
|
open: false,
|
|
386
|
+
maxPages: 500,
|
|
345
387
|
containerId: null
|
|
346
388
|
};
|
|
347
389
|
var styles = function styles() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harvard-lts/mirador-pdf-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "A Mirador 3 plugin that interacts with MPS PDF Download Service ",
|
|
5
5
|
"module": "dist/es/index.js",
|
|
6
6
|
"files": [
|
|
@@ -41,17 +41,17 @@
|
|
|
41
41
|
"@rollup/plugin-babel": "^6.0.3",
|
|
42
42
|
"@testing-library/jest-dom": "^6.1.5",
|
|
43
43
|
"@testing-library/react": "^12.0.0",
|
|
44
|
-
"@vitejs/plugin-react": "^4.
|
|
45
|
-
"@vitest/coverage-v8": "^1.
|
|
46
|
-
"@vitest/ui": "^1.
|
|
44
|
+
"@vitejs/plugin-react": "^4.7.0",
|
|
45
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
46
|
+
"@vitest/ui": "^4.1.8",
|
|
47
47
|
"jsdom": "^23.0.0",
|
|
48
48
|
"mirador": "^3.4.3",
|
|
49
49
|
"npm-run-all": "^4.1.5",
|
|
50
50
|
"parcel": "^2.8.3",
|
|
51
51
|
"rollup": "^3.29.5",
|
|
52
52
|
"url": "^0.11.4",
|
|
53
|
-
"vite": "^
|
|
54
|
-
"vitest": "^1.
|
|
53
|
+
"vite": "^7.3.5",
|
|
54
|
+
"vitest": "^4.1.8",
|
|
55
55
|
"whatwg-fetch": "^3.6.20"
|
|
56
56
|
}
|
|
57
57
|
}
|