cozy-bar 1.17.1

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 (181) hide show
  1. package/.eslintrc.json +7 -0
  2. package/.github/auto-merge.yml +7 -0
  3. package/.nvmrc +1 -0
  4. package/.transifexrc.tpl +4 -0
  5. package/.travis.yml +28 -0
  6. package/.tx/config +8 -0
  7. package/CHANGELOG.md +493 -0
  8. package/CODEOWNERS +2 -0
  9. package/CONTRIBUTING.md +135 -0
  10. package/LICENSE +21 -0
  11. package/README.md +172 -0
  12. package/babel.config.js +3 -0
  13. package/config/aliases/globalReact.js +1 -0
  14. package/config/aliases/globalReactDOM.js +1 -0
  15. package/config/webpack.config.analyzer.js +10 -0
  16. package/config/webpack.config.base.js +61 -0
  17. package/config/webpack.config.dev.js +16 -0
  18. package/config/webpack.config.extract.js +84 -0
  19. package/config/webpack.config.inline-styles.js +82 -0
  20. package/config/webpack.config.jsx.js +14 -0
  21. package/config/webpack.config.prod.js +18 -0
  22. package/config/webpack.js +31 -0
  23. package/config/webpack.vars.js +11 -0
  24. package/dist/cozy-bar.css +9445 -0
  25. package/dist/cozy-bar.css.map +1 -0
  26. package/dist/cozy-bar.js +122668 -0
  27. package/dist/cozy-bar.js.map +1 -0
  28. package/dist/cozy-bar.min.css +9 -0
  29. package/dist/cozy-bar.min.css.map +1 -0
  30. package/dist/cozy-bar.min.js +57 -0
  31. package/dist/cozy-bar.min.js.map +1 -0
  32. package/dist/cozy-bar.mobile.js +123719 -0
  33. package/dist/cozy-bar.mobile.js.map +1 -0
  34. package/dist/cozy-bar.mobile.min.js +57 -0
  35. package/dist/cozy-bar.mobile.min.js.map +1 -0
  36. package/docs/dev.md +20 -0
  37. package/examples/Procfile +3 -0
  38. package/examples/icon.png +0 -0
  39. package/examples/index.html +7 -0
  40. package/examples/index.jsx +122 -0
  41. package/examples/logs.js +3 -0
  42. package/package.json +163 -0
  43. package/postcss.config.js +23 -0
  44. package/public/fonts/Lato-Bold.woff2 +0 -0
  45. package/public/fonts/Lato-Regular.woff2 +0 -0
  46. package/public/fonts.css +13 -0
  47. package/public/icon-type-folder-32.png +0 -0
  48. package/public/index.html +63 -0
  49. package/renovate.json +5 -0
  50. package/src/assets/icons/16/icon-claudy.svg +5 -0
  51. package/src/assets/icons/16/icon-cozy-16.svg +1 -0
  52. package/src/assets/icons/16/icon-cube-16.svg +6 -0
  53. package/src/assets/icons/16/icon-logout-16.svg +3 -0
  54. package/src/assets/icons/16/icon-magnifier-16.svg +6 -0
  55. package/src/assets/icons/16/icon-people-16.svg +3 -0
  56. package/src/assets/icons/16/icon-phone-16.svg +3 -0
  57. package/src/assets/icons/16/icon-question-mark-16.svg +3 -0
  58. package/src/assets/icons/16/icon-storage-16.svg +3 -0
  59. package/src/assets/icons/24/icon-arrow-left.svg +3 -0
  60. package/src/assets/icons/32/icon-claudy.svg +1 -0
  61. package/src/assets/icons/apps/icon-collect.svg +25 -0
  62. package/src/assets/icons/apps/icon-drive.svg +17 -0
  63. package/src/assets/icons/apps/icon-market-soon.svg +25 -0
  64. package/src/assets/icons/apps/icon-photos.svg +19 -0
  65. package/src/assets/icons/apps/icon-soon.svg +21 -0
  66. package/src/assets/icons/apps/icon-store.svg +19 -0
  67. package/src/assets/icons/claudyActions/icon-bills.svg +6 -0
  68. package/src/assets/icons/claudyActions/icon-laptop.svg +7 -0
  69. package/src/assets/icons/claudyActions/icon-phone.svg +8 -0
  70. package/src/assets/icons/claudyActions/icon-question-mark.svg +6 -0
  71. package/src/assets/icons/comingsoon/icon-bank.svg +12 -0
  72. package/src/assets/icons/comingsoon/icon-sante.svg +12 -0
  73. package/src/assets/icons/comingsoon/icon-store.svg +6 -0
  74. package/src/assets/icons/icon-cozy.svg +3 -0
  75. package/src/assets/icons/icon-shield.svg +3 -0
  76. package/src/assets/icons/spinner.svg +4 -0
  77. package/src/assets/sprites/icon-apps.svg +1 -0
  78. package/src/assets/sprites/icon-cozy-home.svg +16 -0
  79. package/src/components/Apps/AppItem.jsx +117 -0
  80. package/src/components/Apps/AppItemPlaceholder.jsx +12 -0
  81. package/src/components/Apps/AppNavButtons.jsx +88 -0
  82. package/src/components/Apps/AppsContent.jsx +89 -0
  83. package/src/components/Apps/ButtonCozyHome.jsx +30 -0
  84. package/src/components/Apps/ButtonCozyHome.spec.jsx +53 -0
  85. package/src/components/Apps/IconCozyHome.jsx +24 -0
  86. package/src/components/Apps/index.jsx +81 -0
  87. package/src/components/Banner.jsx +41 -0
  88. package/src/components/Bar.jsx +293 -0
  89. package/src/components/Bar.spec.jsx +133 -0
  90. package/src/components/Claudy.jsx +81 -0
  91. package/src/components/Drawer.jsx +227 -0
  92. package/src/components/Drawer.spec.jsx +98 -0
  93. package/src/components/SearchBar.jsx +358 -0
  94. package/src/components/Settings/SettingsContent.jsx +145 -0
  95. package/src/components/Settings/StorageData.jsx +29 -0
  96. package/src/components/Settings/helper.js +8 -0
  97. package/src/components/Settings/index.jsx +218 -0
  98. package/src/components/SupportModal.jsx +59 -0
  99. package/src/components/__snapshots__/Bar.spec.jsx.snap +302 -0
  100. package/src/config/claudyActions.yaml +14 -0
  101. package/src/config/persistWhitelist.yaml +2 -0
  102. package/src/dom.js +80 -0
  103. package/src/index.jsx +235 -0
  104. package/src/index.spec.jsx +34 -0
  105. package/src/lib/api/helpers.js +13 -0
  106. package/src/lib/api/index.jsx +145 -0
  107. package/src/lib/exceptions.js +89 -0
  108. package/src/lib/expiringMemoize.js +13 -0
  109. package/src/lib/icon.js +77 -0
  110. package/src/lib/importIcons.js +14 -0
  111. package/src/lib/intents.js +16 -0
  112. package/src/lib/logger.js +6 -0
  113. package/src/lib/middlewares/appsI18n.js +57 -0
  114. package/src/lib/realtime.js +43 -0
  115. package/src/lib/reducers/apps.js +175 -0
  116. package/src/lib/reducers/apps.spec.js +59 -0
  117. package/src/lib/reducers/content.js +50 -0
  118. package/src/lib/reducers/context.js +83 -0
  119. package/src/lib/reducers/index.js +73 -0
  120. package/src/lib/reducers/locale.js +22 -0
  121. package/src/lib/reducers/settings.js +111 -0
  122. package/src/lib/reducers/theme.js +48 -0
  123. package/src/lib/reducers/unserializable.js +26 -0
  124. package/src/lib/stack-client.js +401 -0
  125. package/src/lib/stack.js +79 -0
  126. package/src/lib/store/index.js +54 -0
  127. package/src/locales/de.json +57 -0
  128. package/src/locales/en.json +57 -0
  129. package/src/locales/es.json +57 -0
  130. package/src/locales/fr.json +57 -0
  131. package/src/locales/it.json +57 -0
  132. package/src/locales/ja.json +57 -0
  133. package/src/locales/nl_NL.json +57 -0
  134. package/src/locales/pl.json +57 -0
  135. package/src/locales/ru.json +57 -0
  136. package/src/locales/sq.json +57 -0
  137. package/src/locales/zh_CN.json +57 -0
  138. package/src/proptypes/index.js +10 -0
  139. package/src/queries/index.js +16 -0
  140. package/src/styles/apps.css +248 -0
  141. package/src/styles/banner.css +64 -0
  142. package/src/styles/bar.css +106 -0
  143. package/src/styles/base.css +41 -0
  144. package/src/styles/claudy.css +99 -0
  145. package/src/styles/drawer.css +126 -0
  146. package/src/styles/index.styl +33 -0
  147. package/src/styles/indicators.css +58 -0
  148. package/src/styles/nav.css +81 -0
  149. package/src/styles/navigation_item.css +39 -0
  150. package/src/styles/searchbar.css +158 -0
  151. package/src/styles/settings.css +44 -0
  152. package/src/styles/storage.css +22 -0
  153. package/src/styles/supportModal.css +20 -0
  154. package/src/styles/theme.styl +25 -0
  155. package/test/__mocks__/fileMock.js +3 -0
  156. package/test/__snapshots__/index.spec.js.snap +41 -0
  157. package/test/components/AppItem.spec.jsx +113 -0
  158. package/test/components/AppsContent.spec.jsx +116 -0
  159. package/test/components/Settings/helper.spec.js +23 -0
  160. package/test/components/__snapshots__/AppsContent.spec.jsx.snap +90 -0
  161. package/test/index.spec.js +24 -0
  162. package/test/jestLib/I18n.js +15 -0
  163. package/test/jestLib/setup.js +14 -0
  164. package/test/lib/__snapshots__/api.spec.jsx.snap +67 -0
  165. package/test/lib/__snapshots__/stack.spec.js.snap +3 -0
  166. package/test/lib/api.spec.jsx +142 -0
  167. package/test/lib/mockStackClient.js +7 -0
  168. package/test/lib/stack-client/stack-client.appiconprops.spec.js +65 -0
  169. package/test/lib/stack-client/stack-client.compare.spec.js +20 -0
  170. package/test/lib/stack-client/stack-client.cozyfetchjson.spec.js +46 -0
  171. package/test/lib/stack-client/stack-client.cozyurl.spec.js +29 -0
  172. package/test/lib/stack-client/stack-client.getapp.spec.js +72 -0
  173. package/test/lib/stack-client/stack-client.getapps.spec.js +72 -0
  174. package/test/lib/stack-client/stack-client.getcontext.spec.js +96 -0
  175. package/test/lib/stack-client/stack-client.getstoragedata.spec.js +85 -0
  176. package/test/lib/stack-client/stack-client.init.spec.js +56 -0
  177. package/test/lib/stack-client/stack-client.intents.spec.js +27 -0
  178. package/test/lib/stack-client/stack-client.logout.spec.js +40 -0
  179. package/test/lib/stack.spec.js +60 -0
  180. package/test/store/__snapshots__/index.spec.js.snap +14 -0
  181. package/test/store/index.spec.js +41 -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="test-file-stub"
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="test-file-stub"
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="test-file-stub"
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="test-file-stub"
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="test-file-stub"
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,14 @@
1
+ desktop:
2
+ icon: icon-laptop.svg
3
+ link:
4
+ type: external
5
+
6
+ mobile:
7
+ icon: icon-phone.svg
8
+ link:
9
+ type: external
10
+
11
+ support:
12
+ icon: icon-question-mark.svg
13
+ link:
14
+ type: external
@@ -0,0 +1,2 @@
1
+ - apps
2
+ - context
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,235 @@
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
+ import 'styles/index.styl'
26
+ import 'lib/importIcons'
27
+
28
+ const createBarElement = () => {
29
+ const targetName = isMobileApp() ? 'mobile' : 'browser'
30
+ const barNode = document.createElement('div')
31
+ barNode.setAttribute('id', 'coz-bar')
32
+ barNode.setAttribute('role', 'banner')
33
+ barNode.classList.add(`coz-target--${targetName}`)
34
+ return barNode
35
+ }
36
+
37
+ const injectBarInDOM = data => {
38
+ if (document.getElementById('coz-bar') !== null) {
39
+ return
40
+ }
41
+
42
+ const barNode = createBarElement()
43
+ const appNode = document.querySelector(APP_SELECTOR)
44
+ if (!appNode) {
45
+ // eslint-disable-next-line no-console
46
+ console.warn(
47
+ `Cozy-bar is looking for a "${APP_SELECTOR}" tag that contains your application and can't find it :'(… The BAR is now disabled`
48
+ )
49
+ return null
50
+ }
51
+
52
+ document.body.insertBefore(barNode, appNode)
53
+
54
+ // method to put cozy-bar z-index on the top when Drawer visible and vice versa
55
+ data.onDrawer = visible => {
56
+ barNode.dataset.drawerVisible = visible
57
+ }
58
+
59
+ // specific layout behaviour if banner displayed
60
+ if (data.userActionRequired) {
61
+ document.body.classList.add('has-banner')
62
+ }
63
+
64
+ return barNode
65
+ }
66
+
67
+ const renderBar = (barNode, options) => {
68
+ // import React related modules on init only
69
+ const React = require('react')
70
+ const { render } = require('react-dom')
71
+ const { connect, Provider } = require('react-redux')
72
+ const I18n = require('cozy-ui/react/I18n').default
73
+ const Bar = require('components/Bar').default
74
+ const CozyProvider = require('cozy-client').CozyProvider
75
+
76
+ const { cozyClient } = options
77
+
78
+ // we connect the I18n component to the store to listen
79
+ // locale change from the api setLocale()
80
+ const EnhancedI18n = connect(state => ({
81
+ lang: getLocale(state)
82
+ }))(I18n)
83
+
84
+ const barComponent = (
85
+ <Provider store={options.reduxStore}>
86
+ <EnhancedI18n dictRequire={lang => require(`locales/${lang}`)}>
87
+ {cozyClient ? (
88
+ <CozyProvider client={cozyClient}>
89
+ <Bar {...options} />
90
+ </CozyProvider>
91
+ ) : (
92
+ <Bar {...options} />
93
+ )}
94
+ </EnhancedI18n>
95
+ </Provider>
96
+ )
97
+
98
+ render(barComponent, barNode)
99
+ // for testing only
100
+ return barComponent
101
+ }
102
+
103
+ const makeCozyClientAutomatically = ({ cozyURL, token, isPublic }) => {
104
+ const ccURI = cozyURL || getDefaultStackURL(isPublic)
105
+ const ccToken = token || getDefaultToken(isPublic)
106
+ const ccOptions = {
107
+ uri: ccURI,
108
+ token: ccToken
109
+ }
110
+
111
+ const CozyClient = require('cozy-client').default
112
+
113
+ // eslint-disable-next-line no-console
114
+ console.warn('Automatically made cozyClient. Options: ', ccOptions)
115
+ return new CozyClient(ccOptions)
116
+ }
117
+
118
+ let exposedAPI = {}
119
+
120
+ /**
121
+ * Initializes the cozy bar
122
+ *
123
+ * It can be initialized either with a cozyClient instance
124
+ * or a { cozyURL, ssl, token } tupple.
125
+ *
126
+ * @function
127
+ * @param {Object} arg
128
+ * @param {string} arg.appName - App name to be displayed in the bar
129
+ * @param {string} arg.appNamePrefix
130
+ * @param {string} arg.lang - Language for the bar
131
+ * @param {string} arg.iconPath -
132
+ * @param {Object} arg.cozyClient - a cozy client instance
133
+ * @param {string} arg.cozyURL - URL or domain of the stack
134
+ * @param {boolean} arg.ssl - Tells if we should use a secure
135
+ * protocol required if cozyURL does
136
+ * not have a protocol
137
+ * @param {string} arg.token - Access token for the stack
138
+ * @param {boolean} arg.replaceTitleOnMobile
139
+ * @param {boolean} arg.isPublic
140
+ * @param {Function} arg.onLogout
141
+ */
142
+ const init = async ({
143
+ appName,
144
+ appNamePrefix = getAppNamePrefix(),
145
+ appSlug = getAppSlug(),
146
+ lang,
147
+ iconPath = getDefaultIcon(),
148
+ cozyClient,
149
+ cozyURL,
150
+ token,
151
+ replaceTitleOnMobile = false,
152
+ isPublic = false,
153
+ onLogOut
154
+ } = {}) => {
155
+ // Force public mode in `/public` URLs
156
+ if (!isPublic && /^\/public/.test(window.location.pathname)) {
157
+ isPublic = true
158
+ }
159
+
160
+ if (!cozyClient) {
161
+ cozyClient = makeCozyClientAutomatically({ cozyURL, token, isPublic })
162
+ }
163
+
164
+ // store
165
+ const getOrCreateStore = require('lib/store').default
166
+ const reduxStore = getOrCreateStore()
167
+
168
+ reduxStore.dispatch(setInfos(appName, appNamePrefix, appSlug))
169
+ stack.init({
170
+ cozyClient,
171
+ onCreate: data => reduxStore.dispatch(onRealtimeCreate(data)),
172
+ onDelete: data => reduxStore.dispatch(onRealtimeDelete(data))
173
+ })
174
+ if (lang) {
175
+ reduxStore.dispatch(setLocale(lang))
176
+ }
177
+
178
+ // Assign all api methods to the bar object
179
+ const apiMethods = createBarAPI(reduxStore)
180
+ Object.assign(exposedAPI, apiMethods)
181
+
182
+ const options = {
183
+ appName,
184
+ appNamePrefix,
185
+ appSlug,
186
+ cozyClient,
187
+ iconPath,
188
+ replaceTitleOnMobile,
189
+ isPublic,
190
+ onLogOut,
191
+ userActionRequired: getUserActionRequired(),
192
+ reduxStore
193
+ }
194
+
195
+ const barNode = injectBarInDOM(options)
196
+ renderBar(barNode, options)
197
+ }
198
+
199
+ const updateAccessToken = accessToken => {
200
+ stack.updateAccessToken(accessToken)
201
+ }
202
+
203
+ const proxiedAPI = createBarProxiedAPI(exposedAPI)
204
+
205
+ const {
206
+ setBarCenter,
207
+ setBarLeft,
208
+ setBarRight,
209
+ setBarSearch,
210
+ BarCenter,
211
+ BarRight,
212
+ BarLeft,
213
+ BarSearch,
214
+ setTheme,
215
+ setWebviewContext
216
+ } = proxiedAPI
217
+
218
+ const version = __VERSION__
219
+
220
+ export {
221
+ init,
222
+ version,
223
+ setBarCenter,
224
+ setBarLeft,
225
+ setBarRight,
226
+ setBarSearch,
227
+ BarLeft,
228
+ BarRight,
229
+ BarCenter,
230
+ BarSearch,
231
+ setTheme,
232
+ setWebviewContext,
233
+ setLocale,
234
+ updateAccessToken
235
+ }
@@ -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
+ }