cozy-harvest-lib 18.1.2 → 18.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,28 @@
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
+ # [18.2.0](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@18.1.3...cozy-harvest-lib@18.2.0) (2023-10-12)
7
+
8
+
9
+ ### Features
10
+
11
+ * Add information link redirecting to the store ([e058415](https://github.com/cozy/cozy-libs/commit/e058415ae9ad5e330e106e2e629cff6096355e5b))
12
+
13
+
14
+
15
+
16
+
17
+ ## [18.1.3](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@18.1.2...cozy-harvest-lib@18.1.3) (2023-10-12)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * Optimize the request ([b948b48](https://github.com/cozy/cozy-libs/commit/b948b487c560db1e208612d7d5496e595bc94f21))
23
+
24
+
25
+
26
+
27
+
6
28
  ## [18.1.2](https://github.com/cozy/cozy-libs/compare/cozy-harvest-lib@18.1.1...cozy-harvest-lib@18.1.2) (2023-10-11)
7
29
 
8
30
 
@@ -90,8 +90,8 @@ export var DataTab = function DataTab(_ref) {
90
90
  account: account,
91
91
  trigger: trigger,
92
92
  konnector: konnector
93
- }), konnector.vendor_link && /*#__PURE__*/React.createElement(InformationsCard, {
94
- link: konnector.vendor_link
93
+ }), /*#__PURE__*/React.createElement(InformationsCard, {
94
+ konnector: konnector
95
95
  }))));
96
96
  };
97
97
  DataTab.propTypes = {
@@ -100,7 +100,7 @@ var NewAccountModal = function NewAccountModal(_ref) {
100
100
  onClose: onDismiss
101
101
  }), !serverSideKonnector && /*#__PURE__*/React.createElement(InformationsCard, {
102
102
  className: "u-mt-1",
103
- link: konnector.vendor_link
103
+ konnector: konnector
104
104
  }), /*#__PURE__*/React.createElement("div", {
105
105
  className: "u-mb-2"
106
106
  })));
@@ -1,19 +1,24 @@
1
- import { ListItemText } from '@material-ui/core';
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
4
  import cx from 'classnames';
3
5
  import React from 'react';
6
+ import { useClient, generateWebLink } from 'cozy-client';
4
7
  import Card from 'cozy-ui/transpiled/react/Card';
5
8
  import Divider from 'cozy-ui/transpiled/react/Divider';
6
- import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
7
9
  import Icon from 'cozy-ui/transpiled/react/Icon';
8
10
  import GlobeIcon from 'cozy-ui/transpiled/react/Icons/Globe';
11
+ import StoreIcon from 'cozy-ui/transpiled/react/Icons/Store';
9
12
  import List from 'cozy-ui/transpiled/react/List';
10
13
  import ListItem from 'cozy-ui/transpiled/react/ListItem';
11
14
  import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon';
15
+ import ListItemText from 'cozy-ui/transpiled/react/ListItemText';
12
16
  import Typography from 'cozy-ui/transpiled/react/Typography';
17
+ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
13
18
  import { getErrorMessage } from '../../helpers/getErrorMessage';
14
19
  import logger from '../../logger';
15
20
 
16
- var getLabel = function getLabel(link) {
21
+ var getHost = function getHost(link) {
17
22
  if (!link) return null;
18
23
 
19
24
  try {
@@ -25,15 +30,92 @@ var getLabel = function getLabel(link) {
25
30
  }
26
31
  };
27
32
 
28
- export var InformationsCard = function InformationsCard(_ref) {
29
- var className = _ref.className,
30
- link = _ref.link;
33
+ var ExternalLinkButton = function ExternalLinkButton(_ref) {
34
+ var url = _ref.url,
35
+ primaryText = _ref.primaryText,
36
+ secondaryText = _ref.secondaryText,
37
+ icon = _ref.icon;
38
+ return /*#__PURE__*/React.createElement(ListItem, {
39
+ button: true,
40
+ className: "u-mb-half",
41
+ component: "a",
42
+ href: url,
43
+ target: "_blank"
44
+ }, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
45
+ icon: icon,
46
+ size: 16,
47
+ color: "textPrimary"
48
+ })), /*#__PURE__*/React.createElement(ListItemText, {
49
+ primary: primaryText,
50
+ secondary: secondaryText
51
+ }));
52
+ };
53
+
54
+ var StoreButton = function StoreButton(_ref2) {
55
+ var appSlug = _ref2.appSlug;
56
+ var client = useClient();
31
57
 
32
58
  var _useI18n = useI18n(),
33
59
  t = _useI18n.t;
34
60
 
35
- var label = getLabel(link);
36
- if (!label) return null;
61
+ if (!client) {
62
+ return null;
63
+ }
64
+
65
+ if (!appSlug) {
66
+ return null;
67
+ }
68
+
69
+ var _client$getInstanceOp = client.getInstanceOptions(),
70
+ subDomainType = _client$getInstanceOp.cozySubdomainType;
71
+
72
+ var storeAppName = 'store'; // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
73
+
74
+ var cozyURL = new URL(client.getStackClient().uri);
75
+ var nativePath = "/myapps/".concat(appSlug);
76
+ var url = generateWebLink({
77
+ cozyUrl: cozyURL.origin,
78
+ searchParams: [],
79
+ pathname: '/',
80
+ hash: nativePath,
81
+ slug: storeAppName,
82
+ subDomainType: subDomainType
83
+ });
84
+ return /*#__PURE__*/React.createElement(ExternalLinkButton, {
85
+ url: url,
86
+ primaryText: t('card.information.store'),
87
+ secondaryText: t('card.information.storeDescription'),
88
+ icon: StoreIcon
89
+ });
90
+ };
91
+
92
+ var VendorLinkButton = function VendorLinkButton(_ref3) {
93
+ var vendorLink = _ref3.vendorLink;
94
+
95
+ var _useI18n2 = useI18n(),
96
+ t = _useI18n2.t;
97
+
98
+ var host = getHost(vendorLink);
99
+
100
+ if (!host) {
101
+ return null;
102
+ }
103
+
104
+ return /*#__PURE__*/React.createElement(ExternalLinkButton, {
105
+ url: vendorLink,
106
+ primaryText: t('card.information.websiteLink'),
107
+ secondaryText: host,
108
+ icon: GlobeIcon
109
+ });
110
+ };
111
+
112
+ export var InformationsCard = function InformationsCard(_ref4) {
113
+ var className = _ref4.className,
114
+ konnector = _ref4.konnector;
115
+
116
+ var _useI18n3 = useI18n(),
117
+ t = _useI18n3.t;
118
+
37
119
  return /*#__PURE__*/React.createElement(Card, {
38
120
  className: cx('u-p-0', className)
39
121
  }, /*#__PURE__*/React.createElement("div", {
@@ -43,22 +125,13 @@ export var InformationsCard = function InformationsCard(_ref) {
43
125
  }
44
126
  }, /*#__PURE__*/React.createElement(Typography, {
45
127
  variant: "h5"
46
- }, t('card.websiteLink.title'))), /*#__PURE__*/React.createElement(Divider, {
128
+ }, t('card.information.title'))), /*#__PURE__*/React.createElement(Divider, {
47
129
  className: "u-ml-0 u-maw-100 u-mb-half"
48
130
  }), /*#__PURE__*/React.createElement(List, {
49
131
  className: "u-p-0"
50
- }, /*#__PURE__*/React.createElement(ListItem, {
51
- button: true,
52
- className: "u-mb-half",
53
- component: "a",
54
- href: link,
55
- target: "_blank"
56
- }, /*#__PURE__*/React.createElement(ListItemIcon, null, /*#__PURE__*/React.createElement(Icon, {
57
- icon: GlobeIcon,
58
- size: 16,
59
- color: "textPrimary"
60
- })), /*#__PURE__*/React.createElement(ListItemText, {
61
- primary: t('card.websiteLink.description'),
62
- secondary: label
63
- }))));
132
+ }, /*#__PURE__*/React.createElement(StoreButton, {
133
+ appSlug: konnector.slug
134
+ }), /*#__PURE__*/React.createElement(VendorLinkButton, {
135
+ vendorLink: konnector.vendor_link
136
+ })));
64
137
  };
@@ -4,9 +4,9 @@ import { isFlagshipApp } from 'cozy-device-helper';
4
4
  import Alert from 'cozy-ui/transpiled/react/Alert';
5
5
  import AlertTitle from 'cozy-ui/transpiled/react/AlertTitle';
6
6
  import Button from 'cozy-ui/transpiled/react/Buttons';
7
- import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
8
7
  import Icon from 'cozy-ui/transpiled/react/Icon';
9
8
  import ArrowUp from 'cozy-ui/transpiled/react/Icons/ArrowUp';
9
+ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n';
10
10
  export var RunningAlert = function RunningAlert() {
11
11
  var _useI18n = useI18n(),
12
12
  t = _useI18n.t;
@@ -481,28 +481,34 @@ export var fetchAccountsWithoutTriggers = /*#__PURE__*/function () {
481
481
 
482
482
  export var fetchReusableAccount = /*#__PURE__*/function () {
483
483
  var _ref9 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8(client, konnector) {
484
- var _yield$client$collect, triggers, accountsWithoutTrigger;
485
-
484
+ var triggers, accountsWithoutTrigger;
486
485
  return _regeneratorRuntime.wrap(function _callee8$(_context8) {
487
486
  while (1) {
488
487
  switch (_context8.prev = _context8.next) {
489
488
  case 0:
490
489
  _context8.next = 2;
491
- return client.collection('io.cozy.triggers').all();
490
+ return client.queryAll(Q('io.cozy.triggers').where({
491
+ _id: {
492
+ $gt: null
493
+ }
494
+ }).partialIndex({
495
+ worker: {
496
+ $in: ['konnector', 'client']
497
+ }
498
+ }).indexFields(['_id']));
492
499
 
493
500
  case 2:
494
- _yield$client$collect = _context8.sent;
495
- triggers = _yield$client$collect.data;
496
- _context8.next = 6;
501
+ triggers = _context8.sent;
502
+ _context8.next = 5;
497
503
  return fetchAccountsWithoutTriggers(client, triggers);
498
504
 
499
- case 6:
505
+ case 5:
500
506
  accountsWithoutTrigger = _context8.sent;
501
507
  return _context8.abrupt("return", accountsWithoutTrigger.find(function (account) {
502
508
  return account.account_type === konnector.slug;
503
509
  }));
504
510
 
505
- case 8:
511
+ case 7:
506
512
  case "end":
507
513
  return _context8.stop();
508
514
  }
@@ -564,22 +564,14 @@ describe('fetchReusableAccount', function () {
564
564
  var accounts = _ref22.accounts,
565
565
  triggers = _ref22.triggers;
566
566
  var client = new CozyClient({});
567
- client.collection = jest.fn(function (doctype) {
568
- if (doctype === 'io.cozy.triggers') {
569
- return {
570
- all: jest.fn().mockResolvedValue({
571
- data: triggers
572
- })
573
- };
574
- } else {
575
- throw new Error("client.collection for ".concat(doctype, " is not mocked"));
576
- }
577
- });
578
567
  client.query = jest.fn().mockImplementation(function () {
579
568
  return {
580
569
  data: accounts
581
570
  };
582
571
  });
572
+ client.queryAll = jest.fn().mockImplementation(function () {
573
+ return triggers;
574
+ });
583
575
  return {
584
576
  client: client
585
577
  };
@@ -136,9 +136,11 @@
136
136
  "install": "Discover CoachCO2"
137
137
  }
138
138
  },
139
- "websiteLink": {
139
+ "information": {
140
140
  "title": "Useful information",
141
- "description": "Service website"
141
+ "websiteLink": "Open the website",
142
+ "store": "See in Cozy Cloud Store",
143
+ "storeDescription": "Access the description of this konnector app"
142
144
  }
143
145
  },
144
146
  "default": {
@@ -136,9 +136,11 @@
136
136
  "install": "Découvrir Coach CO2"
137
137
  }
138
138
  },
139
- "websiteLink": {
139
+ "information": {
140
140
  "title": "Informations utiles",
141
- "description": "Site du service"
141
+ "websiteLink": "Ouvrir le site",
142
+ "store": "Voir dans le Store Cozy Cloud",
143
+ "storeDescription": "Accès la fiche descriptive de cette application connecteur"
142
144
  }
143
145
  },
144
146
  "default": {
@@ -136,9 +136,11 @@
136
136
  "install": "Ontdek CoachCO2"
137
137
  }
138
138
  },
139
- "websiteLink": {
139
+ "information": {
140
140
  "title": "Nuttige informatie",
141
- "description": "Website van dienst"
141
+ "websiteLink": "De website openen",
142
+ "store": "Zie in de Cozy Cloud Store",
143
+ "storeDescription": "Ga naar de beschrijving van deze konnector app"
142
144
  }
143
145
  },
144
146
  "default": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cozy-harvest-lib",
3
- "version": "18.1.2",
3
+ "version": "18.2.0",
4
4
  "description": "Provides logic, modules and components for Cozy's harvest applications.",
5
5
  "main": "dist/index.js",
6
6
  "author": "Cozy",
@@ -112,5 +112,5 @@
112
112
  "react-router-dom": ">=4.3.1"
113
113
  },
114
114
  "sideEffects": false,
115
- "gitHead": "db4a954385db84b920e714ae87bda1fb96010c80"
115
+ "gitHead": "263e7855ca380bce6202f0ef242483b8f77d6469"
116
116
  }
@@ -94,9 +94,7 @@ export const DataTab = ({
94
94
  trigger={trigger}
95
95
  konnector={konnector}
96
96
  />
97
- {konnector.vendor_link && (
98
- <InformationsCard link={konnector.vendor_link} />
99
- )}
97
+ <InformationsCard konnector={konnector} />
100
98
  </Stack>
101
99
  </div>
102
100
  </div>
@@ -102,7 +102,7 @@ const NewAccountModal = ({ konnector, onSuccess, onDismiss }) => {
102
102
  />
103
103
 
104
104
  {!serverSideKonnector && (
105
- <InformationsCard className="u-mt-1" link={konnector.vendor_link} />
105
+ <InformationsCard className="u-mt-1" konnector={konnector} />
106
106
  )}
107
107
 
108
108
  {/*
@@ -1,26 +1,48 @@
1
- import { ListItemText } from '@material-ui/core'
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
3
  import cx from 'classnames'
3
4
  import React from 'react'
4
5
 
6
+ import { useClient, generateWebLink } from 'cozy-client'
5
7
  import Card from 'cozy-ui/transpiled/react/Card'
6
8
  import Divider from 'cozy-ui/transpiled/react/Divider'
7
- import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
8
9
  import Icon from 'cozy-ui/transpiled/react/Icon'
9
10
  import GlobeIcon from 'cozy-ui/transpiled/react/Icons/Globe'
11
+ import StoreIcon from 'cozy-ui/transpiled/react/Icons/Store'
10
12
  import List from 'cozy-ui/transpiled/react/List'
11
13
  import ListItem from 'cozy-ui/transpiled/react/ListItem'
12
14
  import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon'
15
+ import ListItemText from 'cozy-ui/transpiled/react/ListItemText'
13
16
  import Typography from 'cozy-ui/transpiled/react/Typography'
17
+ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
14
18
 
15
19
  import { getErrorMessage } from '../../helpers/getErrorMessage'
16
20
  import logger from '../../logger'
17
21
 
22
+ interface Konnector {
23
+ vendor_link: string
24
+ slug: string
25
+ }
18
26
  interface InformationsCardProps {
19
27
  className?: string
20
- link: string
28
+ konnector: Konnector
29
+ }
30
+
31
+ interface StoreButtonProps {
32
+ appSlug: string
33
+ }
34
+ interface VendorLinkButtonProps {
35
+ vendorLink: string
36
+ }
37
+ interface ExternalLinkButtonProps {
38
+ url: string
39
+ primaryText: string
40
+ secondaryText: string
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ icon: any
21
43
  }
22
44
 
23
- const getLabel = (link?: string): string | null => {
45
+ const getHost = (link?: string): string | null => {
24
46
  if (!link) return null
25
47
 
26
48
  try {
@@ -32,14 +54,87 @@ const getLabel = (link?: string): string | null => {
32
54
  }
33
55
  }
34
56
 
57
+ const ExternalLinkButton = ({
58
+ url,
59
+ primaryText,
60
+ secondaryText,
61
+ icon
62
+ }: ExternalLinkButtonProps): JSX.Element | null => {
63
+ return (
64
+ <ListItem
65
+ button
66
+ className="u-mb-half"
67
+ component="a"
68
+ href={url}
69
+ target="_blank"
70
+ >
71
+ <ListItemIcon>
72
+ <Icon icon={icon} size={16} color="textPrimary" />
73
+ </ListItemIcon>
74
+
75
+ <ListItemText primary={primaryText} secondary={secondaryText} />
76
+ </ListItem>
77
+ )
78
+ }
79
+
80
+ const StoreButton = ({ appSlug }: StoreButtonProps): JSX.Element | null => {
81
+ const client = useClient()
82
+ const { t } = useI18n()
83
+ if (!client) {
84
+ return null
85
+ }
86
+ if (!appSlug) {
87
+ return null
88
+ }
89
+ const { cozySubdomainType: subDomainType }: any = client.getInstanceOptions()
90
+
91
+ const storeAppName = 'store'
92
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
93
+ const cozyURL = new URL(client.getStackClient().uri)
94
+ const nativePath = `/myapps/${appSlug}`
95
+ const url = generateWebLink({
96
+ cozyUrl: cozyURL.origin,
97
+ searchParams: [],
98
+ pathname: '/',
99
+ hash: nativePath,
100
+ slug: storeAppName,
101
+ subDomainType
102
+ })
103
+ return (
104
+ <ExternalLinkButton
105
+ url={url}
106
+ primaryText={t('card.information.store')}
107
+ secondaryText={t('card.information.storeDescription')}
108
+ icon={StoreIcon}
109
+ />
110
+ )
111
+ }
112
+
113
+ const VendorLinkButton = ({
114
+ vendorLink
115
+ }: VendorLinkButtonProps): JSX.Element | null => {
116
+ const { t } = useI18n()
117
+ const host = getHost(vendorLink)
118
+
119
+ if (!host) {
120
+ return null
121
+ }
122
+
123
+ return (
124
+ <ExternalLinkButton
125
+ url={vendorLink}
126
+ primaryText={t('card.information.websiteLink')}
127
+ secondaryText={host}
128
+ icon={GlobeIcon}
129
+ />
130
+ )
131
+ }
132
+
35
133
  export const InformationsCard = ({
36
134
  className,
37
- link
135
+ konnector
38
136
  }: InformationsCardProps): JSX.Element | null => {
39
137
  const { t } = useI18n()
40
- const label = getLabel(link)
41
-
42
- if (!label) return null
43
138
 
44
139
  return (
45
140
  <Card className={cx('u-p-0', className)}>
@@ -47,28 +142,14 @@ export const InformationsCard = ({
47
142
  className="u-ph-1 u-flex u-flex-items-center"
48
143
  style={{ minHeight: '64px' }}
49
144
  >
50
- <Typography variant="h5">{t('card.websiteLink.title')}</Typography>
145
+ <Typography variant="h5">{t('card.information.title')}</Typography>
51
146
  </div>
52
147
 
53
148
  <Divider className="u-ml-0 u-maw-100 u-mb-half" />
54
149
 
55
150
  <List className="u-p-0">
56
- <ListItem
57
- button
58
- className="u-mb-half"
59
- component="a"
60
- href={link}
61
- target="_blank"
62
- >
63
- <ListItemIcon>
64
- <Icon icon={GlobeIcon} size={16} color="textPrimary" />
65
- </ListItemIcon>
66
-
67
- <ListItemText
68
- primary={t('card.websiteLink.description')}
69
- secondary={label}
70
- />
71
- </ListItem>
151
+ <StoreButton appSlug={konnector.slug} />
152
+ <VendorLinkButton vendorLink={konnector.vendor_link} />
72
153
  </List>
73
154
  </Card>
74
155
  )
@@ -4,9 +4,9 @@ import { isFlagshipApp } from 'cozy-device-helper'
4
4
  import Alert from 'cozy-ui/transpiled/react/Alert'
5
5
  import AlertTitle from 'cozy-ui/transpiled/react/AlertTitle'
6
6
  import Button from 'cozy-ui/transpiled/react/Buttons'
7
- import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
8
7
  import Icon from 'cozy-ui/transpiled/react/Icon'
9
8
  import ArrowUp from 'cozy-ui/transpiled/react/Icons/ArrowUp'
9
+ import { useI18n } from 'cozy-ui/transpiled/react/providers/I18n'
10
10
 
11
11
  export const RunningAlert = (): JSX.Element | null => {
12
12
  const { t } = useI18n()
@@ -237,7 +237,22 @@ export const fetchAccountsWithoutTriggers = async (client, triggers) => {
237
237
  * @return {Account} An account without trigger for the given konnector
238
238
  */
239
239
  export const fetchReusableAccount = async (client, konnector) => {
240
- const { data: triggers } = await client.collection('io.cozy.triggers').all()
240
+ // the where is there because ATM TriggerCollection check if there is
241
+ // a selector to know if it should call /jobs/triggers or
242
+ // /data/io.cozy.triggers.
243
+ // In our case, we only want the triggers without the job, so we want
244
+ // to use /data/io.cozy.triggers
245
+ const triggers = await client.queryAll(
246
+ Q('io.cozy.triggers')
247
+ .where({
248
+ _id: { $gt: null }
249
+ })
250
+ .partialIndex({
251
+ worker: { $in: ['konnector', 'client'] }
252
+ })
253
+ .indexFields(['_id'])
254
+ )
255
+
241
256
  const accountsWithoutTrigger = await fetchAccountsWithoutTriggers(
242
257
  client,
243
258
  triggers
@@ -417,20 +417,15 @@ describe('Account mutations', () => {
417
417
  describe('fetchReusableAccount', () => {
418
418
  const setup = ({ accounts, triggers }) => {
419
419
  const client = new CozyClient({})
420
- client.collection = jest.fn(doctype => {
421
- if (doctype === 'io.cozy.triggers') {
422
- return {
423
- all: jest.fn().mockResolvedValue({ data: triggers })
424
- }
425
- } else {
426
- throw new Error(`client.collection for ${doctype} is not mocked`)
427
- }
428
- })
429
420
  client.query = jest.fn().mockImplementation(() => {
430
421
  return {
431
422
  data: accounts
432
423
  }
433
424
  })
425
+
426
+ client.queryAll = jest.fn().mockImplementation(() => {
427
+ return triggers
428
+ })
434
429
  return { client }
435
430
  }
436
431
  it('should return the right account when possible', async () => {
@@ -136,9 +136,11 @@
136
136
  "install": "Discover CoachCO2"
137
137
  }
138
138
  },
139
- "websiteLink": {
139
+ "information": {
140
140
  "title": "Useful information",
141
- "description": "Service website"
141
+ "websiteLink": "Open the website",
142
+ "store": "See in Cozy Cloud Store",
143
+ "storeDescription": "Access the description of this konnector app"
142
144
  }
143
145
  },
144
146
  "default": {
@@ -136,9 +136,11 @@
136
136
  "install": "Découvrir Coach CO2"
137
137
  }
138
138
  },
139
- "websiteLink": {
139
+ "information": {
140
140
  "title": "Informations utiles",
141
- "description": "Site du service"
141
+ "websiteLink": "Ouvrir le site",
142
+ "store": "Voir dans le Store Cozy Cloud",
143
+ "storeDescription": "Accès la fiche descriptive de cette application connecteur"
142
144
  }
143
145
  },
144
146
  "default": {
@@ -136,9 +136,11 @@
136
136
  "install": "Ontdek CoachCO2"
137
137
  }
138
138
  },
139
- "websiteLink": {
139
+ "information": {
140
140
  "title": "Nuttige informatie",
141
- "description": "Website van dienst"
141
+ "websiteLink": "De website openen",
142
+ "store": "Zie in de Cozy Cloud Store",
143
+ "storeDescription": "Ga naar de beschrijving van deze konnector app"
142
144
  }
143
145
  },
144
146
  "default": {