cozy-viewer 31.1.7 → 31.2.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,16 @@
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
+ # [31.2.0](https://github.com/cozy/cozy-libs/compare/cozy-viewer@31.1.7...cozy-viewer@31.2.0) (2026-10-13)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **cozy-viewer:** Pass generateWebLink to the View in Drive action ([3dd9b85](https://github.com/cozy/cozy-libs/commit/3dd9b85c767bd9880f3e86ef903ebb6aea2bb436))
11
+
12
+ ### Features
13
+
14
+ - **cozy-viewer:** Let the host app handle a click on the file path ([32346cc](https://github.com/cozy/cozy-libs/commit/32346ccfde79439ff652b566586bf0383e6f0e7d))
15
+
6
16
  ## [31.1.7](https://github.com/cozy/cozy-libs/compare/cozy-viewer@31.1.6...cozy-viewer@31.1.7) (2026-10-13)
7
17
 
8
18
  ### Bug Fixes
@@ -71,7 +71,8 @@ var Informations = function Informations(_ref) {
71
71
  var hasElectronicSafe = (0, _has.default)(file, 'metadata.electronicSafe');
72
72
  var anchorRef = (0, _react.useRef)();
73
73
  var actions = (0, _Actions.makeActions)([_Actions.viewInDrive], {
74
- client: client
74
+ client: client,
75
+ generateWebLink: _cozyClient.generateWebLink
75
76
  });
76
77
  return /*#__PURE__*/_react.default.createElement(_List.default, null, /*#__PURE__*/_react.default.createElement(_ListItem.default, null, /*#__PURE__*/_react.default.createElement(_ListItemIcon.default, null, /*#__PURE__*/_react.default.createElement(_twakeIcons.Icon, {
77
78
  icon: _twakeIcons.FileOutline
package/dist/Viewer.d.ts CHANGED
@@ -31,6 +31,7 @@ declare namespace Viewer {
31
31
  showClose: PropTypes.Requireable<boolean>;
32
32
  toolbarRef: PropTypes.Requireable<object>;
33
33
  showFilePath: PropTypes.Requireable<boolean>;
34
+ onFilePathClick: PropTypes.Requireable<(...args: any[]) => any>;
34
35
  hideSummarizeBtn: PropTypes.Requireable<boolean>;
35
36
  }>>;
36
37
  }>>;
@@ -75,6 +75,7 @@ var Toolbar = function Toolbar(_ref) {
75
75
  isDesktop = _ref.breakpoints.isDesktop,
76
76
  children = _ref.children,
77
77
  showFilePath = _ref.showFilePath,
78
+ onFilePathClick = _ref.onFilePathClick,
78
79
  onPaywallRedirect = _ref.onPaywallRedirect,
79
80
  hideSummarizeBtn = _ref.hideSummarizeBtn;
80
81
  var client = (0, _cozyClient.useClient)();
@@ -129,7 +130,9 @@ var Toolbar = function Toolbar(_ref) {
129
130
  noWrap: true
130
131
  }, /*#__PURE__*/_react.default.createElement(_MidEllipsis.default, {
131
132
  text: file.name
132
- })), showFilePath ? /*#__PURE__*/_react.default.createElement(_ToolbarFilePath.ToolbarFilePath, null) : null), isDesktop && /*#__PURE__*/_react.default.createElement("div", {
133
+ })), showFilePath ? /*#__PURE__*/_react.default.createElement(_ToolbarFilePath.ToolbarFilePath, {
134
+ onClick: onFilePathClick
135
+ }) : null), isDesktop && /*#__PURE__*/_react.default.createElement("div", {
133
136
  className: "u-flex u-flex-items-center"
134
137
  }, !isCozySharing && !isOwner(file._id) && /*#__PURE__*/_react.default.createElement(_cozySharing.ShareButton, {
135
138
  className: "u-white",
@@ -175,6 +178,7 @@ Toolbar.propTypes = {
175
178
  onMouseLeave: _propTypes.default.func.isRequired,
176
179
  onClose: _propTypes.default.func,
177
180
  showFilePath: _propTypes.default.bool,
181
+ onFilePathClick: _propTypes.default.func,
178
182
  onPaywallRedirect: _propTypes.default.func,
179
183
  hideSummarizeBtn: _propTypes.default.bool
180
184
  };
@@ -1 +1,3 @@
1
- export function ToolbarFilePath(): JSX.Element;
1
+ export function ToolbarFilePath({ onClick }: {
2
+ onClick: any;
3
+ }): JSX.Element;
@@ -37,7 +37,8 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
37
37
 
38
38
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
39
39
 
40
- var ToolbarFilePath = function ToolbarFilePath() {
40
+ var ToolbarFilePath = function ToolbarFilePath(_ref) {
41
+ var _onClick = _ref.onClick;
41
42
  var client = (0, _cozyClient.useClient)();
42
43
 
43
44
  var _useBreakpoints = (0, _Breakpoints.default)(),
@@ -65,6 +66,20 @@ var ToolbarFilePath = function ToolbarFilePath() {
65
66
  slug: appSlug
66
67
  });
67
68
 
69
+ if (isDesktop && link && _onClick) {
70
+ return /*#__PURE__*/_react.default.createElement(_Link.default, {
71
+ href: link,
72
+ onClick: function onClick(ev) {
73
+ ev.preventDefault();
74
+
75
+ _onClick(fileWithPath);
76
+ },
77
+ color: "inherit"
78
+ }, /*#__PURE__*/_react.default.createElement(_FilePath.default, {
79
+ className: "u-white"
80
+ }, path));
81
+ }
82
+
68
83
  if (isDesktop && link) {
69
84
  return /*#__PURE__*/_react.default.createElement(_AppLinker.default, {
70
85
  app: {
@@ -72,9 +87,9 @@ var ToolbarFilePath = function ToolbarFilePath() {
72
87
  },
73
88
  nativePath: nativePath,
74
89
  href: link
75
- }, function (_ref) {
76
- var href = _ref.href,
77
- onClick = _ref.onClick;
90
+ }, function (_ref2) {
91
+ var href = _ref2.href,
92
+ onClick = _ref2.onClick;
78
93
  return /*#__PURE__*/_react.default.createElement(_Link.default, {
79
94
  href: href,
80
95
  onClick: onClick,
@@ -0,0 +1 @@
1
+ export {};
@@ -203,6 +203,7 @@ var ViewerControls = /*#__PURE__*/function (_Component) {
203
203
  showClose = toolbarProps.showClose,
204
204
  toolbarRef = toolbarProps.toolbarRef,
205
205
  showFilePath = toolbarProps.showFilePath,
206
+ onFilePathClick = toolbarProps.onFilePathClick,
206
207
  onPaywallRedirect = toolbarProps.onPaywallRedirect,
207
208
  hideSummarizeBtn = toolbarProps.hideSummarizeBtn;
208
209
  var hidden = this.state.hidden;
@@ -214,6 +215,7 @@ var ViewerControls = /*#__PURE__*/function (_Component) {
214
215
  }, showToolbar && /*#__PURE__*/_react.default.createElement(_Toolbar.default, {
215
216
  toolbarRef: toolbarRef,
216
217
  showFilePath: showFilePath,
218
+ onFilePathClick: onFilePathClick,
217
219
  onMouseEnter: this.showControls,
218
220
  onMouseLeave: this.hideControls,
219
221
  onClose: showClose ? onClose : undefined,
@@ -3,6 +3,7 @@ export namespace toolbarPropsPropType {
3
3
  let showClose: PropTypes.Requireable<boolean>;
4
4
  let toolbarRef: PropTypes.Requireable<object>;
5
5
  let showFilePath: PropTypes.Requireable<boolean>;
6
+ let onFilePathClick: PropTypes.Requireable<(...args: any[]) => any>;
6
7
  let hideSummarizeBtn: PropTypes.Requireable<boolean>;
7
8
  }
8
9
  import PropTypes from 'prop-types';
package/dist/proptypes.js CHANGED
@@ -22,6 +22,9 @@ var toolbarPropsPropType = {
22
22
  /** Whether to show file path below his name */
23
23
  showFilePath: _propTypes.default.bool,
24
24
 
25
+ /** Called with the file when its path is clicked, instead of opening the folder in Drive */
26
+ onFilePathClick: _propTypes.default.func,
27
+
25
28
  /** Whether to hide summize button or not */
26
29
  hideSummarizeBtn: _propTypes.default.bool
27
30
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-viewer",
3
- "version": "31.1.7",
3
+ "version": "31.2.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",
@@ -72,5 +72,5 @@
72
72
  "react-router-dom": ">=6.14.2",
73
73
  "twake-i18n": ">=0.3.0"
74
74
  },
75
- "gitHead": "4b518060cd1cd1b19d4100e24f2e3db92242710c"
75
+ "gitHead": "92afbfa840f1a56b17a7cf6adfb1583e03be9ff7"
76
76
  }
@@ -12,7 +12,7 @@ import {
12
12
  Safe,
13
13
  Server
14
14
  } from '@linagora/twake-icons'
15
- import { useClient } from 'cozy-client'
15
+ import { generateWebLink, useClient } from 'cozy-client'
16
16
  import ActionsMenu from 'cozy-ui/transpiled/react/ActionsMenu'
17
17
  import {
18
18
  makeActions,
@@ -43,7 +43,7 @@ const Informations = ({ file, isPublic, t }) => {
43
43
  const hasElectronicSafe = has(file, 'metadata.electronicSafe')
44
44
  const anchorRef = useRef()
45
45
 
46
- const actions = makeActions([viewInDrive], { client })
46
+ const actions = makeActions([viewInDrive], { client, generateWebLink })
47
47
 
48
48
  return (
49
49
  <List>
@@ -37,6 +37,7 @@ const Toolbar = ({
37
37
  breakpoints: { isDesktop },
38
38
  children,
39
39
  showFilePath,
40
+ onFilePathClick,
40
41
  onPaywallRedirect,
41
42
  hideSummarizeBtn
42
43
  }) => {
@@ -86,7 +87,7 @@ const Toolbar = ({
86
87
  >
87
88
  <MidEllipsis text={file.name} />
88
89
  </Typography>
89
- {showFilePath ? <ToolbarFilePath /> : null}
90
+ {showFilePath ? <ToolbarFilePath onClick={onFilePathClick} /> : null}
90
91
  </div>
91
92
 
92
93
  {isDesktop && (
@@ -142,6 +143,7 @@ Toolbar.propTypes = {
142
143
  onMouseLeave: PropTypes.func.isRequired,
143
144
  onClose: PropTypes.func,
144
145
  showFilePath: PropTypes.bool,
146
+ onFilePathClick: PropTypes.func,
145
147
  onPaywallRedirect: PropTypes.func,
146
148
  hideSummarizeBtn: PropTypes.bool
147
149
  }
@@ -15,7 +15,7 @@ import {
15
15
  import { useViewer } from '../providers/ViewerProvider'
16
16
  import { buildFileByIdQuery } from '../queries'
17
17
 
18
- const ToolbarFilePath = () => {
18
+ const ToolbarFilePath = ({ onClick }) => {
19
19
  const client = useClient()
20
20
  const { isDesktop } = useBreakpoints()
21
21
  const { file } = useViewer()
@@ -44,6 +44,21 @@ const ToolbarFilePath = () => {
44
44
  const path = removeFilenameFromPath(fileWithPath.path)
45
45
  const link = makeWebLink({ client, path: nativePath, slug: appSlug })
46
46
 
47
+ if (isDesktop && link && onClick) {
48
+ return (
49
+ <Link
50
+ href={link}
51
+ onClick={ev => {
52
+ ev.preventDefault()
53
+ onClick(fileWithPath)
54
+ }}
55
+ color="inherit"
56
+ >
57
+ <FilePath className="u-white">{path}</FilePath>
58
+ </Link>
59
+ )
60
+ }
61
+
47
62
  if (isDesktop && link) {
48
63
  return (
49
64
  <AppLinker app={{ slug: appSlug }} nativePath={nativePath} href={link}>
@@ -0,0 +1,53 @@
1
+ import '@testing-library/jest-dom'
2
+ import { fireEvent, render, screen } from '@testing-library/react'
3
+ import React from 'react'
4
+
5
+ import { ToolbarFilePath } from './ToolbarFilePath'
6
+
7
+ const file = {
8
+ _id: 'file-id',
9
+ _type: 'io.cozy.files',
10
+ name: 'notes.md',
11
+ dir_id: 'dir-id',
12
+ driveId: 'drive-id'
13
+ }
14
+
15
+ jest.mock('cozy-client', () => ({
16
+ ...jest.requireActual('cozy-client'),
17
+ useClient: () => ({
18
+ getStackClient: () => ({ uri: 'https://alice.cozy.example' }),
19
+ getInstanceOptions: () => ({ subdomain: 'flat' })
20
+ }),
21
+ useQuery: () => ({
22
+ data: { _id: 'dir-id', path: '/Space/Documents' }
23
+ })
24
+ }))
25
+ jest.mock('cozy-ui/transpiled/react/providers/Breakpoints', () => () => ({
26
+ isDesktop: true
27
+ }))
28
+ jest.mock('../providers/ViewerProvider', () => ({
29
+ useViewer: () => ({ file })
30
+ }))
31
+
32
+ describe('ToolbarFilePath', () => {
33
+ it('should link to the folder in Drive by default', () => {
34
+ render(<ToolbarFilePath />)
35
+
36
+ expect(screen.getByRole('link')).toHaveAttribute(
37
+ 'href',
38
+ 'https://alice-drive.cozy.example/#/shareddrive/drive-id/dir-id'
39
+ )
40
+ })
41
+
42
+ it('should hand the click to onClick when given', () => {
43
+ const onClick = jest.fn()
44
+ render(<ToolbarFilePath onClick={onClick} />)
45
+
46
+ const clicked = fireEvent.click(screen.getByRole('link'))
47
+
48
+ expect(clicked).toBe(false)
49
+ expect(onClick).toHaveBeenCalledWith(
50
+ expect.objectContaining({ _id: 'file-id', dir_id: 'dir-id' })
51
+ )
52
+ })
53
+ })
@@ -129,6 +129,7 @@ class ViewerControls extends Component {
129
129
  showClose,
130
130
  toolbarRef,
131
131
  showFilePath,
132
+ onFilePathClick,
132
133
  onPaywallRedirect,
133
134
  hideSummarizeBtn
134
135
  } = toolbarProps
@@ -149,6 +150,7 @@ class ViewerControls extends Component {
149
150
  <Toolbar
150
151
  toolbarRef={toolbarRef}
151
152
  showFilePath={showFilePath}
153
+ onFilePathClick={onFilePathClick}
152
154
  onMouseEnter={this.showControls}
153
155
  onMouseLeave={this.hideControls}
154
156
  onClose={showClose ? onClose : undefined}
package/src/proptypes.js CHANGED
@@ -9,6 +9,8 @@ export const toolbarPropsPropType = {
9
9
  toolbarRef: PropTypes.object,
10
10
  /** Whether to show file path below his name */
11
11
  showFilePath: PropTypes.bool,
12
+ /** Called with the file when its path is clicked, instead of opening the folder in Drive */
13
+ onFilePathClick: PropTypes.func,
12
14
  /** Whether to hide summize button or not */
13
15
  hideSummarizeBtn: PropTypes.bool
14
16
  }