cozy-viewer 28.0.32 → 28.1.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [28.1.0](https://github.com/cozy/cozy-libs/compare/cozy-viewer@28.0.32...cozy-viewer@28.1.0) (2026-06-08)
7
+
8
+ ### Features
9
+
10
+ - **viewer:** Add an Edit button to the PDF viewer ([e6bc365](https://github.com/cozy/cozy-libs/commit/e6bc36506d7eb3d728028b4e81191e991653b672))
11
+
6
12
  ## [28.0.32](https://github.com/cozy/cozy-libs/compare/cozy-viewer@28.0.31...cozy-viewer@28.0.32) (2026-06-04)
7
13
 
8
14
  **Note:** Version bump only for package cozy-viewer
package/dist/Viewer.d.ts CHANGED
@@ -18,6 +18,14 @@ declare namespace Viewer {
18
18
  /** To open the Only Office file */
19
19
  opener: PropTypes.Requireable<(...args: any[]) => any>;
20
20
  }>>;
21
+ /** Used to open a PDF in an external editor */
22
+ PdfViewer: PropTypes.Requireable<PropTypes.InferProps<{
23
+ /** Whether PDF editing is enabled by the host app */
24
+ isPdfEditorEnabled: PropTypes.Requireable<boolean>;
25
+ /** Opens the PDF in the editor; an "Edit" button is shown when editing is
26
+ * enabled, this is set and the user has write access */
27
+ opener: PropTypes.Requireable<(...args: any[]) => any>;
28
+ }>>;
21
29
  toolbarProps: PropTypes.Requireable<PropTypes.InferProps<{
22
30
  showToolbar: PropTypes.Requireable<boolean>;
23
31
  showClose: PropTypes.Requireable<boolean>;
package/dist/Viewer.js CHANGED
@@ -188,6 +188,16 @@ Viewer.propTypes = {
188
188
  /** To open the Only Office file */
189
189
  opener: _propTypes.default.func
190
190
  }),
191
+
192
+ /** Used to open a PDF in an external editor */
193
+ PdfViewer: _propTypes.default.shape({
194
+ /** Whether PDF editing is enabled by the host app */
195
+ isPdfEditorEnabled: _propTypes.default.bool,
196
+
197
+ /** Opens the PDF in the editor; an "Edit" button is shown when editing is
198
+ * enabled, this is set and the user has write access */
199
+ opener: _propTypes.default.func
200
+ }),
191
201
  toolbarProps: _propTypes.default.shape(_proptypes.toolbarPropsPropType)
192
202
  })
193
203
  };
@@ -234,6 +234,16 @@ ViewerContainer.propTypes = {
234
234
  opener: _propTypes.default.func
235
235
  }),
236
236
 
237
+ /** Used to open a PDF in an external editor */
238
+ PdfViewer: _propTypes.default.shape({
239
+ /** Whether PDF editing is enabled by the host app */
240
+ isPdfEditorEnabled: _propTypes.default.bool,
241
+
242
+ /** Opens the PDF in the editor; an "Edit" button is shown when editing is
243
+ * enabled, this is set and the user has write access */
244
+ opener: _propTypes.default.func
245
+ }),
246
+
237
247
  /** Used to spread props to Panel components */
238
248
  panel: _propTypes.default.shape({
239
249
  qualifications: _propTypes.default.shape({
@@ -45,8 +45,12 @@ export class PdfJsViewer extends React.Component<any, any, any> {
45
45
  export namespace PdfJsViewer {
46
46
  namespace propTypes {
47
47
  let url: PropTypes.Validator<string>;
48
+ let file: PropTypes.Requireable<object>;
48
49
  let gestures: PropTypes.Requireable<object>;
49
50
  let renderFallbackExtraContent: PropTypes.Requireable<(...args: any[]) => any>;
51
+ let isReadOnly: PropTypes.Requireable<boolean>;
52
+ let isPdfEditorEnabled: PropTypes.Requireable<boolean>;
53
+ let editPdfOpener: PropTypes.Requireable<(...args: any[]) => any>;
50
54
  }
51
55
  }
52
56
  declare const _default: any;
@@ -35,6 +35,12 @@ var _react = _interopRequireWildcard(require("react"));
35
35
 
36
36
  var _reactPdf = require("react-pdf");
37
37
 
38
+ var _Buttons = _interopRequireDefault(require("cozy-ui/transpiled/react/Buttons"));
39
+
40
+ var _Icon = _interopRequireDefault(require("cozy-ui/transpiled/react/Icon"));
41
+
42
+ var _Pen = _interopRequireDefault(require("cozy-ui/transpiled/react/Icons/Pen"));
43
+
38
44
  var _NoViewer = _interopRequireDefault(require("../NoViewer"));
39
45
 
40
46
  var _PdfToolbarButton = _interopRequireDefault(require("../components/PdfToolbarButton"));
@@ -281,7 +287,10 @@ var PdfJsViewer = /*#__PURE__*/function (_Component) {
281
287
  url = _this$props.url,
282
288
  file = _this$props.file,
283
289
  renderFallbackExtraContent = _this$props.renderFallbackExtraContent,
284
- t = _this$props.t;
290
+ t = _this$props.t,
291
+ isReadOnly = _this$props.isReadOnly,
292
+ isPdfEditorEnabled = _this$props.isPdfEditorEnabled,
293
+ editPdfOpener = _this$props.editPdfOpener;
285
294
  var _this$state = this.state,
286
295
  loaded = _this$state.loaded,
287
296
  errored = _this$state.errored,
@@ -340,7 +349,20 @@ var PdfJsViewer = /*#__PURE__*/function (_Component) {
340
349
  keepToolbarDisplayed: false
341
350
  });
342
351
  }
343
- }, !renderAllPages && /*#__PURE__*/_react.default.createElement("span", {
352
+ }, isPdfEditorEnabled && editPdfOpener && !isReadOnly && /*#__PURE__*/_react.default.createElement(_Buttons.default, {
353
+ variant: "text",
354
+ color: "secondary",
355
+ className: "u-p-half u-m-half",
356
+ startIcon: /*#__PURE__*/_react.default.createElement(_Icon.default, {
357
+ icon: _Pen.default,
358
+ size: 16
359
+ }),
360
+ label: t('Viewer.editPdf'),
361
+ onClick: function onClick() {
362
+ return editPdfOpener(file);
363
+ },
364
+ "data-testid": "pdf-edit-button"
365
+ }), !renderAllPages && /*#__PURE__*/_react.default.createElement("span", {
344
366
  className: "u-mh-half"
345
367
  }, /*#__PURE__*/_react.default.createElement(_PdfToolbarButton.default, {
346
368
  icon: "top",
@@ -388,8 +410,20 @@ exports.PdfJsViewer = PdfJsViewer;
388
410
  (0, _defineProperty2.default)(PdfJsViewer, "contextType", _ViewerProvider.ViewerContext);
389
411
  PdfJsViewer.propTypes = {
390
412
  url: _propTypes.default.string.isRequired,
413
+ file: _propTypes.default.object,
391
414
  gestures: _propTypes.default.object,
392
- renderFallbackExtraContent: _propTypes.default.func
415
+ renderFallbackExtraContent: _propTypes.default.func,
416
+
417
+ /** Whether the user only has read access; hides the "Edit" button. */
418
+ isReadOnly: _propTypes.default.bool,
419
+
420
+ /** Whether PDF editing is enabled by the host app. The "Edit" button is only
421
+ * shown when this is true, an opener is provided and the user has write
422
+ * access. */
423
+ isPdfEditorEnabled: _propTypes.default.bool,
424
+
425
+ /** Opens the file in an external PDF editor. */
426
+ editPdfOpener: _propTypes.default.func
393
427
  };
394
428
 
395
429
  var _default = (0, _flow.default)(_withFileUrl.default, _withViewerLocales.withViewerLocales)(PdfJsViewer);
@@ -88,7 +88,7 @@ var getViewerComponentName = function getViewerComponentName(_ref) {
88
88
 
89
89
  exports.getViewerComponentName = getViewerComponentName;
90
90
  var ViewerByFile = (0, _withBreakpoints.default)()(function (_ref2) {
91
- var _componentsProps$Only, _componentsProps$Only2;
91
+ var _componentsProps$Only, _componentsProps$Only2, _componentsProps$PdfV, _componentsProps$PdfV2;
92
92
 
93
93
  var onClose = _ref2.onClose,
94
94
  renderFallbackExtraContent = _ref2.renderFallbackExtraContent,
@@ -99,10 +99,13 @@ var ViewerByFile = (0, _withBreakpoints.default)()(function (_ref2) {
99
99
  componentsProps = _ref2.componentsProps;
100
100
 
101
101
  var _useViewer = (0, _ViewerProvider.useViewer)(),
102
- file = _useViewer.file;
102
+ file = _useViewer.file,
103
+ isReadOnly = _useViewer.isReadOnly;
103
104
 
104
105
  var isOnlyOfficeEnabled = componentsProps === null || componentsProps === void 0 ? void 0 : (_componentsProps$Only = componentsProps.OnlyOfficeViewer) === null || _componentsProps$Only === void 0 ? void 0 : _componentsProps$Only.isEnabled;
105
106
  var onlyOfficeOpener = componentsProps === null || componentsProps === void 0 ? void 0 : (_componentsProps$Only2 = componentsProps.OnlyOfficeViewer) === null || _componentsProps$Only2 === void 0 ? void 0 : _componentsProps$Only2.opener;
107
+ var isPdfEditorEnabled = componentsProps === null || componentsProps === void 0 ? void 0 : (_componentsProps$PdfV = componentsProps.PdfViewer) === null || _componentsProps$PdfV === void 0 ? void 0 : _componentsProps$PdfV.isPdfEditorEnabled;
108
+ var editPdfOpener = componentsProps === null || componentsProps === void 0 ? void 0 : (_componentsProps$PdfV2 = componentsProps.PdfViewer) === null || _componentsProps$PdfV2 === void 0 ? void 0 : _componentsProps$PdfV2.opener;
106
109
 
107
110
  var _useEncrypted = (0, _Encrypted.useEncrypted)(),
108
111
  url = _useEncrypted.url;
@@ -121,6 +124,9 @@ var ViewerByFile = (0, _withBreakpoints.default)()(function (_ref2) {
121
124
  gestures: gestures,
122
125
  gesturesRef: gesturesRef,
123
126
  onlyOfficeOpener: onlyOfficeOpener,
127
+ isReadOnly: isReadOnly,
128
+ isPdfEditorEnabled: isPdfEditorEnabled,
129
+ editPdfOpener: editPdfOpener,
124
130
  onSwipe: onSwipe,
125
131
  onClose: onClose
126
132
  });
@@ -35,6 +35,7 @@ var en = {
35
35
  next: "Next",
36
36
  openWith: "Open with...",
37
37
  openInOnlyOffice: "Open with Only Office",
38
+ editPdf: "Edit",
38
39
  panel: {
39
40
  collapse: "Collapse",
40
41
  header: "Details",
@@ -151,6 +152,7 @@ var fr = {
151
152
  next: "Suivante",
152
153
  openWith: "Ouvrir avec...",
153
154
  openInOnlyOffice: "Ouvrir avec Only Office",
155
+ editPdf: "\xC9diter",
154
156
  panel: {
155
157
  collapse: "R\xE9duire",
156
158
  header: "D\xE9tails",
@@ -267,6 +269,7 @@ var ru = {
267
269
  next: "\u0421\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439",
268
270
  openWith: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E...",
269
271
  openInOnlyOffice: "\u041E\u0442\u043A\u0440\u044B\u0442\u044C \u0432 Only Office",
272
+ editPdf: "\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
270
273
  panel: {
271
274
  collapse: "\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C",
272
275
  header: "\u0421\u0432\u0435\u0434\u0435\u043D\u0438\u044F",
@@ -383,6 +386,7 @@ var vi = {
383
386
  next: "Ti\u1EBFp theo",
384
387
  openWith: "M\u1EDF b\u1EB1ng...",
385
388
  openInOnlyOffice: "M\u1EDF b\u1EB1ng Only Office",
389
+ editPdf: "Ch\u1EC9nh s\u1EEDa",
386
390
  panel: {
387
391
  collapse: "Thu g\u1ECDn",
388
392
  header: "Chi ti\u1EBFt",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-viewer",
3
- "version": "28.0.32",
3
+ "version": "28.1.0",
4
4
  "description": "Cozy-Viewer provides a component to show files in a viewer.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",
@@ -31,10 +31,10 @@
31
31
  "babel-preset-cozy-app": "^2.8.4",
32
32
  "cozy-client": "^60.20.0",
33
33
  "cozy-device-helper": "2.0.0",
34
- "cozy-harvest-lib": "^37.0.31",
34
+ "cozy-harvest-lib": "^37.0.32",
35
35
  "cozy-intent": "^2.31.1",
36
36
  "cozy-logger": "^1.18.1",
37
- "cozy-sharing": "^33.1.1",
37
+ "cozy-sharing": "^33.1.2",
38
38
  "cozy-ui": "^138.1.0",
39
39
  "cozy-ui-plus": "^8.0.1",
40
40
  "identity-obj-proxy": "3.0.0",
@@ -71,5 +71,5 @@
71
71
  "react-router-dom": ">=6.14.2",
72
72
  "twake-i18n": ">=0.3.0"
73
73
  },
74
- "gitHead": "a6e1d756c4f41496383878fd9ce59afbb443f5b7"
74
+ "gitHead": "4f63c28ae3cd8cac22487e6640006de4f5c31cfc"
75
75
  }
package/src/Viewer.jsx CHANGED
@@ -126,6 +126,14 @@ Viewer.propTypes = {
126
126
  /** To open the Only Office file */
127
127
  opener: PropTypes.func
128
128
  }),
129
+ /** Used to open a PDF in an external editor */
130
+ PdfViewer: PropTypes.shape({
131
+ /** Whether PDF editing is enabled by the host app */
132
+ isPdfEditorEnabled: PropTypes.bool,
133
+ /** Opens the PDF in the editor; an "Edit" button is shown when editing is
134
+ * enabled, this is set and the user has write access */
135
+ opener: PropTypes.func
136
+ }),
129
137
  toolbarProps: PropTypes.shape(toolbarPropsPropType)
130
138
  })
131
139
  }
@@ -165,6 +165,14 @@ ViewerContainer.propTypes = {
165
165
  /** To open the Only Office file */
166
166
  opener: PropTypes.func
167
167
  }),
168
+ /** Used to open a PDF in an external editor */
169
+ PdfViewer: PropTypes.shape({
170
+ /** Whether PDF editing is enabled by the host app */
171
+ isPdfEditorEnabled: PropTypes.bool,
172
+ /** Opens the PDF in the editor; an "Edit" button is shown when editing is
173
+ * enabled, this is set and the user has write access */
174
+ opener: PropTypes.func
175
+ }),
168
176
  /** Used to spread props to Panel components */
169
177
  panel: PropTypes.shape({
170
178
  qualifications: PropTypes.shape({
@@ -5,6 +5,10 @@ import PropTypes from 'prop-types'
5
5
  import React, { Component } from 'react'
6
6
  import { Document, Page } from 'react-pdf'
7
7
 
8
+ import Button from 'cozy-ui/transpiled/react/Buttons'
9
+ import Icon from 'cozy-ui/transpiled/react/Icon'
10
+ import PenIcon from 'cozy-ui/transpiled/react/Icons/Pen'
11
+
8
12
  import styles from './styles.styl'
9
13
  import NoViewer from '../NoViewer'
10
14
  import ToolbarButton from '../components/PdfToolbarButton'
@@ -195,7 +199,15 @@ export class PdfJsViewer extends Component {
195
199
  }
196
200
 
197
201
  render() {
198
- const { url, file, renderFallbackExtraContent, t } = this.props
202
+ const {
203
+ url,
204
+ file,
205
+ renderFallbackExtraContent,
206
+ t,
207
+ isReadOnly,
208
+ isPdfEditorEnabled,
209
+ editPdfOpener
210
+ } = this.props
199
211
  const {
200
212
  loaded,
201
213
  errored,
@@ -273,6 +285,17 @@ export class PdfJsViewer extends Component {
273
285
  this.setState({ keepToolbarDisplayed: false })
274
286
  }
275
287
  >
288
+ {isPdfEditorEnabled && editPdfOpener && !isReadOnly && (
289
+ <Button
290
+ variant="text"
291
+ color="secondary"
292
+ className="u-p-half u-m-half"
293
+ startIcon={<Icon icon={PenIcon} size={16} />}
294
+ label={t('Viewer.editPdf')}
295
+ onClick={() => editPdfOpener(file)}
296
+ data-testid="pdf-edit-button"
297
+ />
298
+ )}
276
299
  {!renderAllPages && (
277
300
  <span className="u-mh-half">
278
301
  <ToolbarButton
@@ -329,8 +352,17 @@ export class PdfJsViewer extends Component {
329
352
 
330
353
  PdfJsViewer.propTypes = {
331
354
  url: PropTypes.string.isRequired,
355
+ file: PropTypes.object,
332
356
  gestures: PropTypes.object,
333
- renderFallbackExtraContent: PropTypes.func
357
+ renderFallbackExtraContent: PropTypes.func,
358
+ /** Whether the user only has read access; hides the "Edit" button. */
359
+ isReadOnly: PropTypes.bool,
360
+ /** Whether PDF editing is enabled by the host app. The "Edit" button is only
361
+ * shown when this is true, an opener is provided and the user has write
362
+ * access. */
363
+ isPdfEditorEnabled: PropTypes.bool,
364
+ /** Opens the file in an external PDF editor. */
365
+ editPdfOpener: PropTypes.func
334
366
  }
335
367
 
336
368
  export default flow(withFileUrl, withViewerLocales)(PdfJsViewer)
@@ -64,9 +64,11 @@ const ViewerByFile = withBreakpoints()(({
64
64
  breakpoints: { isDesktop },
65
65
  componentsProps
66
66
  }) => {
67
- const { file } = useViewer()
67
+ const { file, isReadOnly } = useViewer()
68
68
  const isOnlyOfficeEnabled = componentsProps?.OnlyOfficeViewer?.isEnabled
69
69
  const onlyOfficeOpener = componentsProps?.OnlyOfficeViewer?.opener
70
+ const isPdfEditorEnabled = componentsProps?.PdfViewer?.isPdfEditorEnabled
71
+ const editPdfOpener = componentsProps?.PdfViewer?.opener
70
72
 
71
73
  const { url } = useEncrypted()
72
74
 
@@ -88,6 +90,9 @@ const ViewerByFile = withBreakpoints()(({
88
90
  gestures={gestures}
89
91
  gesturesRef={gesturesRef}
90
92
  onlyOfficeOpener={onlyOfficeOpener}
93
+ isReadOnly={isReadOnly}
94
+ isPdfEditorEnabled={isPdfEditorEnabled}
95
+ editPdfOpener={editPdfOpener}
91
96
  onSwipe={onSwipe}
92
97
  onClose={onClose}
93
98
  />
@@ -26,6 +26,7 @@
26
26
  "next": "Next",
27
27
  "openWith": "Open with...",
28
28
  "openInOnlyOffice": "Open with Only Office",
29
+ "editPdf": "Edit",
29
30
  "panel": {
30
31
  "collapse": "Collapse",
31
32
  "header": "Details",
@@ -26,6 +26,7 @@
26
26
  "next": "Suivante",
27
27
  "openWith": "Ouvrir avec...",
28
28
  "openInOnlyOffice": "Ouvrir avec Only Office",
29
+ "editPdf": "Éditer",
29
30
  "panel": {
30
31
  "collapse": "Réduire",
31
32
  "header": "Détails",
@@ -26,6 +26,7 @@
26
26
  "next": "Следующий",
27
27
  "openWith": "Открыть с помощью...",
28
28
  "openInOnlyOffice": "Открыть в Only Office",
29
+ "editPdf": "Редактировать",
29
30
  "panel": {
30
31
  "collapse": "Свернуть",
31
32
  "header": "Сведения",
@@ -113,4 +114,4 @@
113
114
  "loadingText": "Создание резюме"
114
115
  }
115
116
  }
116
- }
117
+ }
@@ -26,6 +26,7 @@
26
26
  "next": "Tiếp theo",
27
27
  "openWith": "Mở bằng...",
28
28
  "openInOnlyOffice": "Mở bằng Only Office",
29
+ "editPdf": "Chỉnh sửa",
29
30
  "panel": {
30
31
  "collapse": "Thu gọn",
31
32
  "header": "Chi tiết",
@@ -113,4 +114,4 @@
113
114
  "loadingText": "Đang tóm tắt nội dung"
114
115
  }
115
116
  }
116
- }
117
+ }