cozy-bar 0.0.0-development

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/dist/cozy-bar.min.js +77 -0
  4. package/dist/cozy-bar.min.js.map +1 -0
  5. package/package.json +165 -0
  6. package/src/assets/icons/16/icon-storage-16.svg +3 -0
  7. package/src/assets/icons/24/icon-arrow-left.svg +3 -0
  8. package/src/assets/icons/32/icon-claudy.svg +1 -0
  9. package/src/assets/icons/apps/icon-collect.svg +25 -0
  10. package/src/assets/icons/apps/icon-drive.svg +17 -0
  11. package/src/assets/icons/apps/icon-market-soon.svg +25 -0
  12. package/src/assets/icons/apps/icon-photos.svg +19 -0
  13. package/src/assets/icons/apps/icon-soon.svg +21 -0
  14. package/src/assets/icons/apps/icon-store.svg +19 -0
  15. package/src/assets/icons/claudyActions/icon-bills.svg +6 -0
  16. package/src/assets/icons/claudyActions/icon-laptop.svg +7 -0
  17. package/src/assets/icons/claudyActions/icon-phone.svg +8 -0
  18. package/src/assets/icons/claudyActions/icon-question-mark.svg +6 -0
  19. package/src/assets/icons/comingsoon/icon-bank.svg +12 -0
  20. package/src/assets/icons/comingsoon/icon-sante.svg +12 -0
  21. package/src/assets/icons/comingsoon/icon-store.svg +6 -0
  22. package/src/assets/icons/icon-cozy.svg +3 -0
  23. package/src/assets/icons/icon-shield.svg +3 -0
  24. package/src/assets/icons/spinner.svg +4 -0
  25. package/src/assets/sprites/icon-apps.svg +1 -0
  26. package/src/assets/sprites/icon-cozy-home.svg +16 -0
  27. package/src/components/Apps/AppItem.jsx +117 -0
  28. package/src/components/Apps/AppItemPlaceholder.jsx +12 -0
  29. package/src/components/Apps/AppNavButtons.jsx +94 -0
  30. package/src/components/Apps/AppsContent.jsx +91 -0
  31. package/src/components/Apps/ButtonCozyHome.jsx +30 -0
  32. package/src/components/Apps/ButtonCozyHome.spec.jsx +53 -0
  33. package/src/components/Apps/IconCozyHome.jsx +38 -0
  34. package/src/components/Apps/index.jsx +72 -0
  35. package/src/components/Banner.jsx +41 -0
  36. package/src/components/Bar.jsx +295 -0
  37. package/src/components/Bar.spec.jsx +133 -0
  38. package/src/components/Claudy.jsx +81 -0
  39. package/src/components/ClaudyIcon.jsx +18 -0
  40. package/src/components/Drawer.jsx +227 -0
  41. package/src/components/Drawer.spec.jsx +98 -0
  42. package/src/components/SearchBar.jsx +358 -0
  43. package/src/components/Settings/SettingsContent.jsx +163 -0
  44. package/src/components/Settings/StorageData.jsx +29 -0
  45. package/src/components/Settings/helper.js +8 -0
  46. package/src/components/Settings/index.jsx +220 -0
  47. package/src/components/StorageIcon.jsx +16 -0
  48. package/src/components/SupportModal.jsx +59 -0
  49. package/src/components/__snapshots__/Bar.spec.jsx.snap +302 -0
  50. package/src/config/claudyActions.json +20 -0
  51. package/src/config/persistWhitelist.json +4 -0
  52. package/src/dom.js +80 -0
  53. package/src/index.jsx +242 -0
  54. package/src/index.spec.jsx +34 -0
  55. package/src/lib/api/helpers.js +13 -0
  56. package/src/lib/api/index.jsx +145 -0
  57. package/src/lib/exceptions.js +89 -0
  58. package/src/lib/expiringMemoize.js +13 -0
  59. package/src/lib/icon.js +77 -0
  60. package/src/lib/intents.js +16 -0
  61. package/src/lib/logger.js +11 -0
  62. package/src/lib/middlewares/appsI18n.js +57 -0
  63. package/src/lib/realtime.js +43 -0
  64. package/src/lib/reducers/apps.js +175 -0
  65. package/src/lib/reducers/apps.spec.js +59 -0
  66. package/src/lib/reducers/content.js +50 -0
  67. package/src/lib/reducers/context.js +86 -0
  68. package/src/lib/reducers/index.js +73 -0
  69. package/src/lib/reducers/locale.js +22 -0
  70. package/src/lib/reducers/settings.js +111 -0
  71. package/src/lib/reducers/theme.js +48 -0
  72. package/src/lib/reducers/unserializable.js +26 -0
  73. package/src/lib/stack-client.js +401 -0
  74. package/src/lib/stack.js +79 -0
  75. package/src/lib/store/index.js +44 -0
  76. package/src/locales/de.json +57 -0
  77. package/src/locales/en.json +57 -0
  78. package/src/locales/es.json +57 -0
  79. package/src/locales/fr.json +57 -0
  80. package/src/locales/it.json +57 -0
  81. package/src/locales/ja.json +57 -0
  82. package/src/locales/nl_NL.json +57 -0
  83. package/src/locales/pl.json +57 -0
  84. package/src/locales/ru.json +57 -0
  85. package/src/locales/sq.json +57 -0
  86. package/src/locales/zh_CN.json +57 -0
  87. package/src/proptypes/index.js +10 -0
  88. package/src/queries/index.js +16 -0
  89. package/src/styles/apps.css +248 -0
  90. package/src/styles/banner.css +64 -0
  91. package/src/styles/bar.css +106 -0
  92. package/src/styles/base.css +21 -0
  93. package/src/styles/claudy.css +98 -0
  94. package/src/styles/drawer.css +126 -0
  95. package/src/styles/index.styl +33 -0
  96. package/src/styles/indicators.css +58 -0
  97. package/src/styles/nav.css +81 -0
  98. package/src/styles/navigation_item.css +34 -0
  99. package/src/styles/searchbar.css +156 -0
  100. package/src/styles/settings.css +34 -0
  101. package/src/styles/storage.css +22 -0
  102. package/src/styles/supportModal.css +20 -0
  103. package/src/styles/theme.styl +25 -0
@@ -0,0 +1,302 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Bar should change allow theme overrides 1`] = `
4
+ <div
5
+ className="coz-bar-wrapper coz-theme-primary"
6
+ style={
7
+ Object {
8
+ "--cozBarThemePrimaryColor": "red",
9
+ }
10
+ }
11
+ >
12
+ <div
13
+ id="cozy-bar-modal-dom-place"
14
+ />
15
+ <div
16
+ className="coz-bar-container"
17
+ >
18
+ <button
19
+ className="coz-bar-btn coz-bar-burger"
20
+ data-tutorial="apps-mobile"
21
+ onClick={[Function]}
22
+ type="button"
23
+ >
24
+ <Icon
25
+ color="currentColor"
26
+ height={16}
27
+ icon={[Function]}
28
+ spin={false}
29
+ width={16}
30
+ />
31
+ <span
32
+ className="coz-bar-hidden"
33
+ >
34
+ drawer
35
+ </span>
36
+ </button>
37
+ <Apps />
38
+ <div
39
+ className="u-flex-grow"
40
+ />
41
+ <withI18n(Connect(Settings))
42
+ toggleSupport={[Function]}
43
+ />
44
+ <Connect(Drawer)
45
+ drawerListener={[Function]}
46
+ isClaudyLoading={false}
47
+ onClaudy={false}
48
+ onClose={[Function]}
49
+ toggleSupport={[Function]}
50
+ visible={false}
51
+ />
52
+ </div>
53
+ </div>
54
+ `;
55
+
56
+ exports[`Bar should change theme 1`] = `
57
+ <div
58
+ className="coz-bar-wrapper coz-theme-primary"
59
+ style={Object {}}
60
+ >
61
+ <div
62
+ id="cozy-bar-modal-dom-place"
63
+ />
64
+ <div
65
+ className="coz-bar-container"
66
+ >
67
+ <button
68
+ className="coz-bar-btn coz-bar-burger"
69
+ data-tutorial="apps-mobile"
70
+ onClick={[Function]}
71
+ type="button"
72
+ >
73
+ <Icon
74
+ color="currentColor"
75
+ height={16}
76
+ icon={[Function]}
77
+ spin={false}
78
+ width={16}
79
+ />
80
+ <span
81
+ className="coz-bar-hidden"
82
+ >
83
+ drawer
84
+ </span>
85
+ </button>
86
+ <Apps />
87
+ <div
88
+ className="u-flex-grow"
89
+ />
90
+ <withI18n(Connect(Settings))
91
+ toggleSupport={[Function]}
92
+ />
93
+ <Connect(Drawer)
94
+ drawerListener={[Function]}
95
+ isClaudyLoading={false}
96
+ onClaudy={false}
97
+ onClose={[Function]}
98
+ toggleSupport={[Function]}
99
+ visible={false}
100
+ />
101
+ </div>
102
+ </div>
103
+ `;
104
+
105
+ exports[`Bar should display the Searchbar 1`] = `
106
+ <div
107
+ className="coz-bar-wrapper coz-theme-default"
108
+ style={Object {}}
109
+ >
110
+ <div
111
+ id="cozy-bar-modal-dom-place"
112
+ />
113
+ <div
114
+ className="coz-bar-container"
115
+ >
116
+ <button
117
+ className="coz-bar-btn coz-bar-burger"
118
+ data-tutorial="apps-mobile"
119
+ onClick={[Function]}
120
+ type="button"
121
+ >
122
+ <Icon
123
+ color="currentColor"
124
+ height={16}
125
+ icon={[Function]}
126
+ spin={false}
127
+ width={16}
128
+ />
129
+ <span
130
+ className="coz-bar-hidden"
131
+ >
132
+ drawer
133
+ </span>
134
+ </button>
135
+ <Apps
136
+ isPublic={false}
137
+ />
138
+ <div
139
+ className="u-flex-grow"
140
+ >
141
+ <withI18n(SearchBar) />
142
+ </div>
143
+ <withI18n(Connect(Settings))
144
+ toggleSupport={[Function]}
145
+ />
146
+ <Connect(Drawer)
147
+ drawerListener={[Function]}
148
+ isClaudyLoading={false}
149
+ onClaudy={false}
150
+ onClose={[Function]}
151
+ toggleSupport={[Function]}
152
+ visible={false}
153
+ />
154
+ </div>
155
+ </div>
156
+ `;
157
+
158
+ exports[`Bar should have correct dispatch props provided by the store 1`] = `
159
+ Object {
160
+ "fetchApps": [Function],
161
+ "fetchContext": [Function],
162
+ "fetchSettingsData": [Function],
163
+ }
164
+ `;
165
+
166
+ exports[`Bar should have correct state props provided by the store with the initial state 1`] = `
167
+ Object {
168
+ "barCenter": undefined,
169
+ "barLeft": undefined,
170
+ "barRight": undefined,
171
+ "barSearch": undefined,
172
+ "claudyEnabled": false,
173
+ "hasFetchedApps": false,
174
+ "isDrive": false,
175
+ "theme": "default",
176
+ "themeOverrides": Object {},
177
+ "webviewContext": undefined,
178
+ }
179
+ `;
180
+
181
+ exports[`Bar should not display searchbar if we are not on a public page 1`] = `
182
+ <div
183
+ className="coz-bar-wrapper coz-theme-default"
184
+ style={Object {}}
185
+ >
186
+ <div
187
+ id="cozy-bar-modal-dom-place"
188
+ />
189
+ <div
190
+ className="coz-bar-container"
191
+ >
192
+ <Apps
193
+ isPublic={true}
194
+ />
195
+ <div
196
+ className="u-flex-grow"
197
+ />
198
+ </div>
199
+ </div>
200
+ `;
201
+
202
+ exports[`Bar should not display searchbar if we are not on Cozy Drive 1`] = `
203
+ <div
204
+ className="coz-bar-wrapper coz-theme-default"
205
+ style={Object {}}
206
+ >
207
+ <div
208
+ id="cozy-bar-modal-dom-place"
209
+ />
210
+ <div
211
+ className="coz-bar-container"
212
+ >
213
+ <button
214
+ className="coz-bar-btn coz-bar-burger"
215
+ data-tutorial="apps-mobile"
216
+ onClick={[Function]}
217
+ type="button"
218
+ >
219
+ <Icon
220
+ color="currentColor"
221
+ height={16}
222
+ icon={[Function]}
223
+ spin={false}
224
+ width={16}
225
+ />
226
+ <span
227
+ className="coz-bar-hidden"
228
+ >
229
+ drawer
230
+ </span>
231
+ </button>
232
+ <Apps
233
+ isPublic={false}
234
+ />
235
+ <div
236
+ className="u-flex-grow"
237
+ />
238
+ <withI18n(Connect(Settings))
239
+ toggleSupport={[Function]}
240
+ />
241
+ <Connect(Drawer)
242
+ drawerListener={[Function]}
243
+ isClaudyLoading={false}
244
+ onClaudy={false}
245
+ onClose={[Function]}
246
+ toggleSupport={[Function]}
247
+ visible={false}
248
+ />
249
+ </div>
250
+ </div>
251
+ `;
252
+
253
+ exports[`Bar should not display searchbar if we are on mobile 1`] = `
254
+ <div
255
+ className="coz-bar-wrapper coz-theme-default"
256
+ style={Object {}}
257
+ >
258
+ <div
259
+ id="cozy-bar-modal-dom-place"
260
+ />
261
+ <div
262
+ className="coz-bar-container"
263
+ >
264
+ <button
265
+ className="coz-bar-btn coz-bar-burger"
266
+ data-tutorial="apps-mobile"
267
+ onClick={[Function]}
268
+ type="button"
269
+ >
270
+ <Icon
271
+ color="currentColor"
272
+ height={16}
273
+ icon={[Function]}
274
+ spin={false}
275
+ width={16}
276
+ />
277
+ <span
278
+ className="coz-bar-hidden"
279
+ >
280
+ drawer
281
+ </span>
282
+ </button>
283
+ <Apps
284
+ isPublic={false}
285
+ />
286
+ <div
287
+ className="u-flex-grow"
288
+ />
289
+ <withI18n(Connect(Settings))
290
+ toggleSupport={[Function]}
291
+ />
292
+ <Connect(Drawer)
293
+ drawerListener={[Function]}
294
+ isClaudyLoading={false}
295
+ onClaudy={false}
296
+ onClose={[Function]}
297
+ toggleSupport={[Function]}
298
+ visible={false}
299
+ />
300
+ </div>
301
+ </div>
302
+ `;
@@ -0,0 +1,20 @@
1
+ {
2
+ "desktop": {
3
+ "icon": "icon-laptop.svg",
4
+ "link": {
5
+ "type": "external"
6
+ }
7
+ },
8
+ "mobile": {
9
+ "icon": "icon-phone.svg",
10
+ "link": {
11
+ "type": "external"
12
+ }
13
+ },
14
+ "support": {
15
+ "icon": "icon-question-mark.svg",
16
+ "link": {
17
+ "type": "external"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,4 @@
1
+ [
2
+ "apps",
3
+ "context"
4
+ ]
package/src/dom.js ADDED
@@ -0,0 +1,80 @@
1
+ const APP_SELECTOR = '[role=application]'
2
+
3
+ // return an empty object by default to avoid checking existance
4
+ const getAppNodeDataSet = () => {
5
+ const appNode = document.querySelector(APP_SELECTOR)
6
+ if (!appNode || !appNode.dataset) return {}
7
+ return appNode.dataset
8
+ }
9
+
10
+ const getDefaultStackURL = isPublic => {
11
+ const data = getAppNodeDataSet()
12
+ if (!data.cozyDomain) {
13
+ if (!isPublic) {
14
+ // eslint-disable-next-line no-console
15
+ console.warn(
16
+ `Cozy-bar can't discover the cozy's URL, and will probably fail to initialize the connection with the stack.`
17
+ )
18
+ }
19
+ return ''
20
+ }
21
+
22
+ const protocol = window.location.protocol
23
+ return `${protocol}//${data.cozyDomain}`
24
+ }
25
+
26
+ const getDefaultToken = isPublic => {
27
+ const data = getAppNodeDataSet()
28
+ if (!data.cozyToken) {
29
+ if (!isPublic) {
30
+ // eslint-disable-next-line no-console
31
+ console.warn(
32
+ `Cozy-bar can't discover the app's token, and will probably fail to initialize the connection with the stack.`
33
+ )
34
+ }
35
+ return ''
36
+ }
37
+ return data.cozyToken
38
+ }
39
+
40
+ const getDefaultIcon = () => {
41
+ const linkNode = document.querySelector('link[rel="icon"][sizes^="32"]')
42
+ if (linkNode !== null) {
43
+ return linkNode.getAttribute('href')
44
+ } else {
45
+ return 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
46
+ }
47
+ }
48
+
49
+ const getAppNamePrefix = () => {
50
+ const data = getAppNodeDataSet()
51
+ return data.cozyAppNamePrefix || null
52
+ }
53
+
54
+ const getAppSlug = () => {
55
+ const data = getAppNodeDataSet()
56
+ return data.cozyAppSlug || null
57
+ }
58
+
59
+ const getUserActionRequired = () => {
60
+ const meta = document.querySelector('meta[name=user-action-required]')
61
+ const data = meta && meta.dataset
62
+ if (data) {
63
+ const { title, code, detail, links } = data
64
+ if (code) {
65
+ // we suppose that at least code will always exist
66
+ return { title, code, detail, links }
67
+ }
68
+ }
69
+ return undefined
70
+ }
71
+
72
+ export {
73
+ getDefaultStackURL,
74
+ getDefaultToken,
75
+ getDefaultIcon,
76
+ getAppNamePrefix,
77
+ getAppSlug,
78
+ getUserActionRequired,
79
+ APP_SELECTOR
80
+ }
package/src/index.jsx ADDED
@@ -0,0 +1,242 @@
1
+ /* global __VERSION__ */
2
+
3
+ import { isMobileApp } from 'cozy-device-helper'
4
+
5
+ import stack from 'lib/stack'
6
+ import {
7
+ getLocale,
8
+ onRealtimeCreate,
9
+ onRealtimeDelete,
10
+ setLocale,
11
+ setInfos
12
+ } from 'lib/reducers'
13
+
14
+ import { createBarAPI, createBarProxiedAPI } from 'lib/api'
15
+
16
+ import {
17
+ getAppNamePrefix,
18
+ getAppSlug,
19
+ getDefaultIcon,
20
+ getDefaultStackURL,
21
+ getDefaultToken,
22
+ getUserActionRequired,
23
+ APP_SELECTOR
24
+ } from './dom'
25
+
26
+ import enLocale from 'locales/en.json'
27
+ import frLocale from 'locales/fr.json'
28
+ import esLocale from 'locales/es.json'
29
+
30
+ const locales = {
31
+ en: enLocale,
32
+ fr: frLocale,
33
+ es: esLocale
34
+ }
35
+
36
+ const createBarElement = () => {
37
+ const targetName = isMobileApp() ? 'mobile' : 'browser'
38
+ const barNode = document.createElement('div')
39
+ barNode.setAttribute('id', 'coz-bar')
40
+ barNode.setAttribute('role', 'banner')
41
+ barNode.classList.add(`coz-target--${targetName}`)
42
+ return barNode
43
+ }
44
+
45
+ const injectBarInDOM = data => {
46
+ if (document.getElementById('coz-bar') !== null) {
47
+ return
48
+ }
49
+
50
+ const barNode = createBarElement()
51
+ const appNode = document.querySelector(APP_SELECTOR)
52
+ if (!appNode) {
53
+ // eslint-disable-next-line no-console
54
+ console.warn(
55
+ `Cozy-bar is looking for a "${APP_SELECTOR}" tag that contains your application and can't find it :'(… The BAR is now disabled`
56
+ )
57
+ return null
58
+ }
59
+
60
+ document.body.insertBefore(barNode, appNode)
61
+
62
+ // method to put cozy-bar z-index on the top when Drawer visible and vice versa
63
+ data.onDrawer = visible => {
64
+ barNode.dataset.drawerVisible = visible
65
+ }
66
+
67
+ // specific layout behaviour if banner displayed
68
+ if (data.userActionRequired) {
69
+ document.body.classList.add('has-banner')
70
+ }
71
+
72
+ return barNode
73
+ }
74
+
75
+ const renderBar = (barNode, options) => {
76
+ // import React related modules on init only
77
+ const React = require('react')
78
+ const { render } = require('react-dom')
79
+ const { connect, Provider } = require('react-redux')
80
+ const I18n = require('cozy-ui/react/I18n').default
81
+ const Bar = require('components/Bar').default
82
+ const CozyProvider = require('cozy-client').CozyProvider
83
+
84
+ const { cozyClient } = options
85
+
86
+ // we connect the I18n component to the store to listen
87
+ // locale change from the api setLocale()
88
+ const EnhancedI18n = connect(state => ({
89
+ lang: getLocale(state)
90
+ }))(I18n)
91
+
92
+ const barComponent = (
93
+ <Provider store={options.reduxStore}>
94
+ <EnhancedI18n dictRequire={lang => locales[lang]}>
95
+ {cozyClient ? (
96
+ <CozyProvider client={cozyClient}>
97
+ <Bar {...options} />
98
+ </CozyProvider>
99
+ ) : (
100
+ <Bar {...options} />
101
+ )}
102
+ </EnhancedI18n>
103
+ </Provider>
104
+ )
105
+
106
+ render(barComponent, barNode)
107
+ // for testing only
108
+ return barComponent
109
+ }
110
+
111
+ const makeCozyClientAutomatically = ({ cozyURL, token, isPublic }) => {
112
+ const ccURI = cozyURL || getDefaultStackURL(isPublic)
113
+ const ccToken = token || getDefaultToken(isPublic)
114
+ const ccOptions = {
115
+ uri: ccURI,
116
+ token: ccToken
117
+ }
118
+
119
+ const CozyClient = require('cozy-client').default
120
+
121
+ // eslint-disable-next-line no-console
122
+ console.warn('Automatically made cozyClient. Options: ', ccOptions)
123
+ return new CozyClient(ccOptions)
124
+ }
125
+
126
+ let exposedAPI = {}
127
+
128
+ /**
129
+ * Initializes the cozy bar
130
+ *
131
+ * It can be initialized either with a cozyClient instance
132
+ * or a { cozyURL, ssl, token } tupple.
133
+ *
134
+ * @function
135
+ * @param {Object} options
136
+ * @param {string} options.appName - App name to be displayed in the bar
137
+ * @param {string} options.appNamePrefix
138
+ * @param {string} options.lang - Language for the bar
139
+ * @param {string} options.iconPath -
140
+ * @param {Object} options.cozyClient - a cozy client instance
141
+ * @param {string} options.cozyURL - URL or domain of the stack
142
+ * @param {boolean} options.ssl - Tells if we should use a secure
143
+ * protocol required if cozyURL does
144
+ * not have a protocol
145
+ * @param {string} arg.token - Access token for the stack
146
+ * @param {boolean} arg.isPublic
147
+ * @param {Function} arg.onLogout
148
+ */
149
+ const init = async ({
150
+ appName,
151
+ appNamePrefix = getAppNamePrefix(),
152
+ appSlug = getAppSlug(),
153
+ lang,
154
+ iconPath = getDefaultIcon(),
155
+ cozyClient,
156
+ cozyURL,
157
+ token,
158
+ replaceTitleOnMobile = false,
159
+ isPublic = false,
160
+ onLogOut
161
+ } = {}) => {
162
+ // Force public mode in `/public` URLs
163
+ if (!isPublic && /^\/public/.test(window.location.pathname)) {
164
+ isPublic = true
165
+ }
166
+
167
+ if (!cozyClient) {
168
+ cozyClient = makeCozyClientAutomatically({ cozyURL, token, isPublic })
169
+ }
170
+
171
+ // store
172
+ const getOrCreateStore = require('lib/store').default
173
+ const reduxStore = getOrCreateStore()
174
+
175
+ reduxStore.dispatch(setInfos(appName, appNamePrefix, appSlug))
176
+ stack.init({
177
+ cozyClient,
178
+ onCreate: data => reduxStore.dispatch(onRealtimeCreate(data)),
179
+ onDelete: data => reduxStore.dispatch(onRealtimeDelete(data))
180
+ })
181
+ if (lang) {
182
+ reduxStore.dispatch(setLocale(lang))
183
+ }
184
+
185
+ // Assign all api methods to the bar object
186
+ const apiMethods = createBarAPI(reduxStore)
187
+ Object.assign(exposedAPI, apiMethods)
188
+
189
+ const options = {
190
+ appName,
191
+ appNamePrefix,
192
+ appSlug,
193
+ cozyClient,
194
+ iconPath,
195
+ replaceTitleOnMobile,
196
+ isPublic,
197
+ onLogOut,
198
+ userActionRequired: getUserActionRequired(),
199
+ reduxStore
200
+ }
201
+
202
+ const barNode = injectBarInDOM(options)
203
+ renderBar(barNode, options)
204
+ }
205
+
206
+ const updateAccessToken = accessToken => {
207
+ stack.updateAccessToken(accessToken)
208
+ }
209
+
210
+ const proxiedAPI = createBarProxiedAPI(exposedAPI)
211
+
212
+ const {
213
+ setBarCenter,
214
+ setBarLeft,
215
+ setBarRight,
216
+ setBarSearch,
217
+ BarCenter,
218
+ BarRight,
219
+ BarLeft,
220
+ BarSearch,
221
+ setTheme,
222
+ setWebviewContext
223
+ } = proxiedAPI
224
+
225
+ const version = __VERSION__
226
+
227
+ export {
228
+ init,
229
+ version,
230
+ setBarCenter,
231
+ setBarLeft,
232
+ setBarRight,
233
+ setBarSearch,
234
+ BarLeft,
235
+ BarRight,
236
+ BarCenter,
237
+ BarSearch,
238
+ setTheme,
239
+ setWebviewContext,
240
+ setLocale,
241
+ updateAccessToken
242
+ }
@@ -0,0 +1,34 @@
1
+ import CozyClient from 'cozy-client'
2
+ import jestFetchMock from 'jest-fetch-mock'
3
+
4
+ import * as cozyBar from './index'
5
+
6
+ describe('init', () => {
7
+ beforeAll(() => {
8
+ global.fetch = jestFetchMock
9
+ })
10
+
11
+ beforeEach(() => {
12
+ jest.spyOn(console, 'error')
13
+ const div = document.createElement('div')
14
+ div.setAttribute('role', 'application')
15
+ document.body.appendChild(div)
16
+ })
17
+
18
+ afterEach(() => {
19
+ // eslint-disable-next-line no-console
20
+ console.error.mockRestore()
21
+ })
22
+
23
+ it('should init the bar', () => {
24
+ const client = new CozyClient({})
25
+ cozyBar.init({
26
+ appName: 'App',
27
+ cozyClient: client,
28
+ lang: 'fr'
29
+ })
30
+ cozyBar.setBarCenter('Page title')
31
+ // eslint-disable-next-line no-console
32
+ expect(console.error).not.toHaveBeenCalled()
33
+ })
34
+ })
@@ -0,0 +1,13 @@
1
+ export const locations = ['left', 'center', 'right', 'search']
2
+
3
+ const upperFirstLetter = val => {
4
+ return val[0].toUpperCase() + val.slice(1)
5
+ }
6
+
7
+ export const getJsApiName = location => {
8
+ return `setBar${upperFirstLetter(location)}`
9
+ }
10
+
11
+ export const getReactApiName = location => {
12
+ return `Bar${upperFirstLetter(location)}`
13
+ }