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.
- package/LICENSE +21 -0
- package/README.md +174 -0
- package/dist/cozy-bar.min.js +77 -0
- package/dist/cozy-bar.min.js.map +1 -0
- package/package.json +165 -0
- package/src/assets/icons/16/icon-storage-16.svg +3 -0
- package/src/assets/icons/24/icon-arrow-left.svg +3 -0
- package/src/assets/icons/32/icon-claudy.svg +1 -0
- package/src/assets/icons/apps/icon-collect.svg +25 -0
- package/src/assets/icons/apps/icon-drive.svg +17 -0
- package/src/assets/icons/apps/icon-market-soon.svg +25 -0
- package/src/assets/icons/apps/icon-photos.svg +19 -0
- package/src/assets/icons/apps/icon-soon.svg +21 -0
- package/src/assets/icons/apps/icon-store.svg +19 -0
- package/src/assets/icons/claudyActions/icon-bills.svg +6 -0
- package/src/assets/icons/claudyActions/icon-laptop.svg +7 -0
- package/src/assets/icons/claudyActions/icon-phone.svg +8 -0
- package/src/assets/icons/claudyActions/icon-question-mark.svg +6 -0
- package/src/assets/icons/comingsoon/icon-bank.svg +12 -0
- package/src/assets/icons/comingsoon/icon-sante.svg +12 -0
- package/src/assets/icons/comingsoon/icon-store.svg +6 -0
- package/src/assets/icons/icon-cozy.svg +3 -0
- package/src/assets/icons/icon-shield.svg +3 -0
- package/src/assets/icons/spinner.svg +4 -0
- package/src/assets/sprites/icon-apps.svg +1 -0
- package/src/assets/sprites/icon-cozy-home.svg +16 -0
- package/src/components/Apps/AppItem.jsx +117 -0
- package/src/components/Apps/AppItemPlaceholder.jsx +12 -0
- package/src/components/Apps/AppNavButtons.jsx +94 -0
- package/src/components/Apps/AppsContent.jsx +91 -0
- package/src/components/Apps/ButtonCozyHome.jsx +30 -0
- package/src/components/Apps/ButtonCozyHome.spec.jsx +53 -0
- package/src/components/Apps/IconCozyHome.jsx +38 -0
- package/src/components/Apps/index.jsx +72 -0
- package/src/components/Banner.jsx +41 -0
- package/src/components/Bar.jsx +295 -0
- package/src/components/Bar.spec.jsx +133 -0
- package/src/components/Claudy.jsx +81 -0
- package/src/components/ClaudyIcon.jsx +18 -0
- package/src/components/Drawer.jsx +227 -0
- package/src/components/Drawer.spec.jsx +98 -0
- package/src/components/SearchBar.jsx +358 -0
- package/src/components/Settings/SettingsContent.jsx +163 -0
- package/src/components/Settings/StorageData.jsx +29 -0
- package/src/components/Settings/helper.js +8 -0
- package/src/components/Settings/index.jsx +220 -0
- package/src/components/StorageIcon.jsx +16 -0
- package/src/components/SupportModal.jsx +59 -0
- package/src/components/__snapshots__/Bar.spec.jsx.snap +302 -0
- package/src/config/claudyActions.json +20 -0
- package/src/config/persistWhitelist.json +4 -0
- package/src/dom.js +80 -0
- package/src/index.jsx +242 -0
- package/src/index.spec.jsx +34 -0
- package/src/lib/api/helpers.js +13 -0
- package/src/lib/api/index.jsx +145 -0
- package/src/lib/exceptions.js +89 -0
- package/src/lib/expiringMemoize.js +13 -0
- package/src/lib/icon.js +77 -0
- package/src/lib/intents.js +16 -0
- package/src/lib/logger.js +11 -0
- package/src/lib/middlewares/appsI18n.js +57 -0
- package/src/lib/realtime.js +43 -0
- package/src/lib/reducers/apps.js +175 -0
- package/src/lib/reducers/apps.spec.js +59 -0
- package/src/lib/reducers/content.js +50 -0
- package/src/lib/reducers/context.js +86 -0
- package/src/lib/reducers/index.js +73 -0
- package/src/lib/reducers/locale.js +22 -0
- package/src/lib/reducers/settings.js +111 -0
- package/src/lib/reducers/theme.js +48 -0
- package/src/lib/reducers/unserializable.js +26 -0
- package/src/lib/stack-client.js +401 -0
- package/src/lib/stack.js +79 -0
- package/src/lib/store/index.js +44 -0
- package/src/locales/de.json +57 -0
- package/src/locales/en.json +57 -0
- package/src/locales/es.json +57 -0
- package/src/locales/fr.json +57 -0
- package/src/locales/it.json +57 -0
- package/src/locales/ja.json +57 -0
- package/src/locales/nl_NL.json +57 -0
- package/src/locales/pl.json +57 -0
- package/src/locales/ru.json +57 -0
- package/src/locales/sq.json +57 -0
- package/src/locales/zh_CN.json +57 -0
- package/src/proptypes/index.js +10 -0
- package/src/queries/index.js +16 -0
- package/src/styles/apps.css +248 -0
- package/src/styles/banner.css +64 -0
- package/src/styles/bar.css +106 -0
- package/src/styles/base.css +21 -0
- package/src/styles/claudy.css +98 -0
- package/src/styles/drawer.css +126 -0
- package/src/styles/index.styl +33 -0
- package/src/styles/indicators.css +58 -0
- package/src/styles/nav.css +81 -0
- package/src/styles/navigation_item.css +34 -0
- package/src/styles/searchbar.css +156 -0
- package/src/styles/settings.css +34 -0
- package/src/styles/storage.css +22 -0
- package/src/styles/supportModal.css +20 -0
- package/src/styles/theme.styl +25 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
import { connect } from 'react-redux'
|
|
3
|
+
|
|
4
|
+
import BottomIcon from 'cozy-ui/react/Icons/Bottom'
|
|
5
|
+
import Icon from 'cozy-ui/react/Icon'
|
|
6
|
+
import TopIcon from 'cozy-ui/react/Icons/Top'
|
|
7
|
+
import { translate } from 'cozy-ui/react/I18n'
|
|
8
|
+
|
|
9
|
+
import { ButtonCozyHome } from 'components/Apps/ButtonCozyHome'
|
|
10
|
+
import { getHomeApp } from 'lib/reducers'
|
|
11
|
+
import { isFetchingApps } from 'lib/reducers'
|
|
12
|
+
|
|
13
|
+
class AppNavButton extends Component {
|
|
14
|
+
render() {
|
|
15
|
+
const {
|
|
16
|
+
homeApp,
|
|
17
|
+
handleClick,
|
|
18
|
+
appName,
|
|
19
|
+
appNamePrefix,
|
|
20
|
+
appSlug,
|
|
21
|
+
iconPath,
|
|
22
|
+
isFetchingApps,
|
|
23
|
+
isPublic,
|
|
24
|
+
opened,
|
|
25
|
+
t
|
|
26
|
+
} = this.props
|
|
27
|
+
|
|
28
|
+
const isHomeApp = homeApp && homeApp.isCurrentApp
|
|
29
|
+
|
|
30
|
+
if (!isPublic && isFetchingApps) {
|
|
31
|
+
return (
|
|
32
|
+
<div className="coz-nav-apps-btns --loading">
|
|
33
|
+
<div className="coz-nav-apps-btns-home coz-loading-placeholder" />
|
|
34
|
+
<div className="coz-nav-apps-btns-main coz-loading-placeholder" />
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const displayName =
|
|
40
|
+
!isHomeApp && appNamePrefix
|
|
41
|
+
? [
|
|
42
|
+
t(`${appSlug}.name_prefix`, {
|
|
43
|
+
_: appNamePrefix
|
|
44
|
+
}),
|
|
45
|
+
t(`${appSlug}.name`, {
|
|
46
|
+
_: appName
|
|
47
|
+
})
|
|
48
|
+
].join(' ')
|
|
49
|
+
: t(`${appSlug}.name`, { _: appName })
|
|
50
|
+
|
|
51
|
+
const homeHref = !isPublic && homeApp && homeApp.href
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<div className={`coz-nav-apps-btns${isHomeApp ? ' --currentHome' : ''}`}>
|
|
55
|
+
<ButtonCozyHome homeHref={homeHref} />
|
|
56
|
+
|
|
57
|
+
{!isHomeApp && <span className="coz-nav-apps-btns-sep" />}
|
|
58
|
+
|
|
59
|
+
<button
|
|
60
|
+
type="button"
|
|
61
|
+
onClick={isPublic ? null : handleClick}
|
|
62
|
+
className="coz-nav-apps-btns-main"
|
|
63
|
+
aria-controls="coz-nav-pop--apps"
|
|
64
|
+
data-tutorial="apps"
|
|
65
|
+
disabled={isPublic}
|
|
66
|
+
>
|
|
67
|
+
{!isHomeApp && (
|
|
68
|
+
<img className="coz-bar-hide-sm" src={iconPath} width="28" alt="" />
|
|
69
|
+
)}
|
|
70
|
+
<span className="coz-nav-app-name">{displayName}</span>
|
|
71
|
+
{!isPublic && (
|
|
72
|
+
<Icon
|
|
73
|
+
icon={opened ? TopIcon : BottomIcon}
|
|
74
|
+
color="#95999d"
|
|
75
|
+
size="12"
|
|
76
|
+
/>
|
|
77
|
+
)}
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const mapStateToProps = state => ({
|
|
85
|
+
homeApp: getHomeApp(state),
|
|
86
|
+
isFetchingApps: isFetchingApps(state)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const mapDispatchToProps = () => ({})
|
|
90
|
+
|
|
91
|
+
export default connect(
|
|
92
|
+
mapStateToProps,
|
|
93
|
+
mapDispatchToProps
|
|
94
|
+
)(translate()(AppNavButton))
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
import { connect } from 'react-redux'
|
|
3
|
+
import Proptypes from 'prop-types'
|
|
4
|
+
|
|
5
|
+
import { translate } from 'cozy-ui/react/I18n'
|
|
6
|
+
import Icon from 'cozy-ui/transpiled/react/Icon'
|
|
7
|
+
import CloudIcon from 'cozy-ui/transpiled/react/Icons/Cloud'
|
|
8
|
+
|
|
9
|
+
import withBreakpoints from 'cozy-ui/react/helpers/withBreakpoints'
|
|
10
|
+
import { getApps, getHomeApp, isFetchingApps } from 'lib/reducers'
|
|
11
|
+
|
|
12
|
+
import AppItem from 'components/Apps/AppItem'
|
|
13
|
+
import AppItemPlaceholder from 'components/Apps/AppItemPlaceholder'
|
|
14
|
+
|
|
15
|
+
const sorter = fn => (itemA, itemB) => fn(itemA) > fn(itemB)
|
|
16
|
+
|
|
17
|
+
export class AppsContent extends Component {
|
|
18
|
+
constructor(props, context) {
|
|
19
|
+
super(props, context)
|
|
20
|
+
this.translateApp = translateApp(this.props.t)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
render() {
|
|
24
|
+
const {
|
|
25
|
+
t,
|
|
26
|
+
apps,
|
|
27
|
+
breakpoints,
|
|
28
|
+
homeApp,
|
|
29
|
+
isFetchingApps,
|
|
30
|
+
onAppSwitch
|
|
31
|
+
} = this.props
|
|
32
|
+
const { isMobile } = breakpoints
|
|
33
|
+
const isHomeApp = homeApp && homeApp.isCurrentApp
|
|
34
|
+
const homeSlug = homeApp && homeApp.slug
|
|
35
|
+
|
|
36
|
+
if (!isFetchingApps && (!apps || !apps.length)) {
|
|
37
|
+
return <p className="coz-nav--error coz-nav-group">{t('no_apps')}</p>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div className="coz-nav-pop-content">
|
|
42
|
+
<ul className="coz-nav-group">
|
|
43
|
+
{isMobile && homeApp && (
|
|
44
|
+
<AppItem app={homeApp} useHomeIcon onAppSwitch={onAppSwitch} />
|
|
45
|
+
)}
|
|
46
|
+
{isFetchingApps
|
|
47
|
+
? new Array(3)
|
|
48
|
+
.fill({})
|
|
49
|
+
.map((nothing, index) => <AppItemPlaceholder key={index} />)
|
|
50
|
+
: apps
|
|
51
|
+
.filter(app => app.slug !== homeSlug)
|
|
52
|
+
.sort(sorter(this.translateApp))
|
|
53
|
+
.map((app, index) => (
|
|
54
|
+
<AppItem app={app} key={index} onAppSwitch={onAppSwitch} />
|
|
55
|
+
))}
|
|
56
|
+
</ul>
|
|
57
|
+
{homeApp && !isMobile && !isHomeApp && (
|
|
58
|
+
<a role="menuitem" href={homeApp.href} className="coz-apps-home-btn">
|
|
59
|
+
<Icon icon={CloudIcon} />
|
|
60
|
+
{t('menu.home')}
|
|
61
|
+
</a>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
AppsContent.propTypes = {
|
|
68
|
+
homeApp: Proptypes.shape({
|
|
69
|
+
isCurrentApp: Proptypes.bool,
|
|
70
|
+
slug: Proptypes.string
|
|
71
|
+
}),
|
|
72
|
+
apps: Proptypes.array,
|
|
73
|
+
isFetchingApps: Proptypes.bool.isRequired
|
|
74
|
+
}
|
|
75
|
+
const translateApp = t => app => {
|
|
76
|
+
const namePrefix = app.namePrefix
|
|
77
|
+
? t(`${app.slug}.namePrefix`, { _: app.namePrefix })
|
|
78
|
+
: null
|
|
79
|
+
const name = t(`${app.slug}.name`, { _: app.name })
|
|
80
|
+
return namePrefix ? `${namePrefix} ${name}` : `${name}`
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const mapStateToProps = state => ({
|
|
84
|
+
apps: getApps(state),
|
|
85
|
+
homeApp: getHomeApp(state),
|
|
86
|
+
isFetchingApps: isFetchingApps(state)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
export default connect(mapStateToProps)(
|
|
90
|
+
translate()(withBreakpoints()(AppsContent))
|
|
91
|
+
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import IconCozyHome from './IconCozyHome'
|
|
4
|
+
|
|
5
|
+
export const ButtonCozyHome = ({ webviewContext, homeHref }) => {
|
|
6
|
+
if (webviewContext)
|
|
7
|
+
return (
|
|
8
|
+
<button
|
|
9
|
+
onClick={() => {
|
|
10
|
+
webviewContext.call('backToHome')
|
|
11
|
+
}}
|
|
12
|
+
className="coz-nav-apps-btns-home --flagship"
|
|
13
|
+
>
|
|
14
|
+
<IconCozyHome className="coz-nav-apps-btns-home-svg" />
|
|
15
|
+
</button>
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
if (homeHref)
|
|
19
|
+
return (
|
|
20
|
+
<a href={homeHref} className="coz-nav-apps-btns-home">
|
|
21
|
+
<IconCozyHome className="coz-nav-apps-btns-home-svg" />
|
|
22
|
+
</a>
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<span className="coz-nav-apps-btns-home">
|
|
27
|
+
<IconCozyHome className="coz-nav-apps-btns-home-svg" />
|
|
28
|
+
</span>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { shallow } from 'enzyme'
|
|
3
|
+
|
|
4
|
+
import { ButtonCozyHome } from 'components/Apps/ButtonCozyHome'
|
|
5
|
+
|
|
6
|
+
const homeHref = 'foo'
|
|
7
|
+
const expectedCall = 'backToHome'
|
|
8
|
+
const webviewContext = {
|
|
9
|
+
call: jest.fn()
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('ButtonCozyHome', () => {
|
|
13
|
+
it('should render a span with no props', () => {
|
|
14
|
+
const render = shallow(<ButtonCozyHome />)
|
|
15
|
+
const element = render.getElement()
|
|
16
|
+
|
|
17
|
+
expect(element.type).toBe('span')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should render an anchor with correct href when homeHref', () => {
|
|
21
|
+
const render = shallow(<ButtonCozyHome homeHref={homeHref} />)
|
|
22
|
+
const element = render.getElement()
|
|
23
|
+
|
|
24
|
+
expect(element.type).toBe('a')
|
|
25
|
+
expect(element.props.href).toBe(homeHref)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should render a button when webviewContext', () => {
|
|
29
|
+
const render = shallow(<ButtonCozyHome webviewContext={webviewContext} />)
|
|
30
|
+
const element = render.getElement()
|
|
31
|
+
|
|
32
|
+
expect(element.type).toBe('button')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('should give priority to button if both webviewContext and homeHref are present', () => {
|
|
36
|
+
const render = shallow(
|
|
37
|
+
<ButtonCozyHome homeHref={homeHref} webviewContext={webviewContext} />
|
|
38
|
+
)
|
|
39
|
+
const element = render.getElement()
|
|
40
|
+
|
|
41
|
+
expect(element.type).toBe('button')
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it('should call the correct context method on click', () => {
|
|
45
|
+
const render = shallow(
|
|
46
|
+
<ButtonCozyHome homeHref={homeHref} webviewContext={webviewContext} />
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
render.simulate('click')
|
|
50
|
+
|
|
51
|
+
expect(webviewContext.call).toBeCalledWith(expectedCall)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React, { PureComponent } from 'react'
|
|
2
|
+
|
|
3
|
+
import AppIcon from 'cozy-ui/react/AppIcon'
|
|
4
|
+
|
|
5
|
+
import stack from 'lib/stack'
|
|
6
|
+
|
|
7
|
+
/* Generated with node_modules/.bin/svgr src/assets/sprites/icon-cozy-home.svg */
|
|
8
|
+
function SvgIconCozyHome(props) {
|
|
9
|
+
return (
|
|
10
|
+
<svg width={32} height={32} {...props}>
|
|
11
|
+
<g fill="none" fillRule="evenodd">
|
|
12
|
+
<circle fill="#297EF2" fillRule="nonzero" cx={16} cy={16} r={16} />
|
|
13
|
+
<path
|
|
14
|
+
d="M19.314 17.561a.555.555 0 01-.82.12 4.044 4.044 0 01-2.499.862 4.04 4.04 0 01-2.494-.86.557.557 0 01-.815-.12.547.547 0 01.156-.748c.214-.14.229-.421.229-.424a.555.555 0 01.176-.385.504.504 0 01.386-.145.544.544 0 01.528.553c0 .004 0 .153-.054.36a2.954 2.954 0 003.784-.008 1.765 1.765 0 01-.053-.344.546.546 0 01.536-.561h.01c.294 0 .538.237.545.532 0 0 .015.282.227.422a.544.544 0 01.158.746m2.322-6.369a5.94 5.94 0 00-1.69-3.506A5.651 5.651 0 0015.916 6a5.648 5.648 0 00-4.029 1.687 5.936 5.936 0 00-1.691 3.524 5.677 5.677 0 00-3.433 1.737 5.966 5.966 0 00-1.643 4.137C5.12 20.347 7.704 23 10.882 23h10.236c3.176 0 5.762-2.653 5.762-5.915 0-3.083-2.31-5.623-5.244-5.893"
|
|
15
|
+
fill="#FFF"
|
|
16
|
+
/>
|
|
17
|
+
</g>
|
|
18
|
+
</svg>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class IconCozyHome extends PureComponent {
|
|
23
|
+
render() {
|
|
24
|
+
const { className } = this.props
|
|
25
|
+
const fetchIcon = () =>
|
|
26
|
+
`${stack.get.cozyURL()}/assets/images/icon-cozy-home.svg`
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<AppIcon
|
|
30
|
+
fetchIcon={fetchIcon}
|
|
31
|
+
fallbackIcon={SvgIconCozyHome}
|
|
32
|
+
className={className}
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default IconCozyHome
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
|
|
3
|
+
import AppsContent from 'components/Apps/AppsContent'
|
|
4
|
+
import AppNavButtons from 'components/Apps/AppNavButtons'
|
|
5
|
+
|
|
6
|
+
class Apps extends Component {
|
|
7
|
+
constructor(props) {
|
|
8
|
+
super(props)
|
|
9
|
+
this.state = {
|
|
10
|
+
opened: false
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
componentDidMount() {
|
|
15
|
+
document.body.addEventListener('click', this.onClickOutside)
|
|
16
|
+
this.modalContainer = document.getElementById('cozy-bar-modal-dom-place')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
componentWillUnmount() {
|
|
20
|
+
document.body.removeEventListener('click', this.onClickOutside)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
onClickOutside = event => {
|
|
24
|
+
if (this.state.opened) {
|
|
25
|
+
// if it's not a cozy-bar nav popup, close the opened popup
|
|
26
|
+
if (
|
|
27
|
+
!this.rootRef.contains(event.target) &&
|
|
28
|
+
!this.modalContainer.contains(event.target)
|
|
29
|
+
) {
|
|
30
|
+
this.setState({ opened: false })
|
|
31
|
+
event.stopPropagation()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
toggleMenu = () => {
|
|
37
|
+
this.setState({ opened: !this.state.opened })
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// data-tutorial attribute allows to be targeted in an application tutorial
|
|
41
|
+
render() {
|
|
42
|
+
const { appName, appNamePrefix, appSlug, iconPath, isPublic } = this.props
|
|
43
|
+
const { opened } = this.state
|
|
44
|
+
return (
|
|
45
|
+
<nav
|
|
46
|
+
className="coz-nav coz-nav-apps"
|
|
47
|
+
ref={ref => {
|
|
48
|
+
this.rootRef = ref
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
<AppNavButtons
|
|
52
|
+
appName={appName}
|
|
53
|
+
appNamePrefix={appNamePrefix}
|
|
54
|
+
appSlug={appSlug}
|
|
55
|
+
iconPath={iconPath}
|
|
56
|
+
handleClick={this.toggleMenu}
|
|
57
|
+
opened={opened}
|
|
58
|
+
isPublic={isPublic}
|
|
59
|
+
/>
|
|
60
|
+
<div
|
|
61
|
+
className="coz-nav-pop coz-nav-pop--apps"
|
|
62
|
+
id="coz-nav-pop--apps"
|
|
63
|
+
aria-hidden={!opened}
|
|
64
|
+
>
|
|
65
|
+
<AppsContent />
|
|
66
|
+
</div>
|
|
67
|
+
</nav>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default Apps
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { Component } from 'react'
|
|
2
|
+
import { ButtonLink } from 'cozy-ui/react/Button'
|
|
3
|
+
import { translate } from 'cozy-ui/react/I18n'
|
|
4
|
+
|
|
5
|
+
class Banner extends Component {
|
|
6
|
+
constructor(props) {
|
|
7
|
+
super(props)
|
|
8
|
+
this.state = { unmounted: true }
|
|
9
|
+
this.animate = this.animate.bind(this)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
animate() {
|
|
13
|
+
// To animate we have to use a setTimeout to
|
|
14
|
+
// force a CSS class update and trigger CSS animation
|
|
15
|
+
return setTimeout(() => {
|
|
16
|
+
this.setState(() => ({ unmounted: false }))
|
|
17
|
+
}, 100)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
componentDidMount() {
|
|
21
|
+
this.animate()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
render() {
|
|
25
|
+
const { t, code, links } = this.props
|
|
26
|
+
const { unmounted } = this.state
|
|
27
|
+
return (
|
|
28
|
+
<div className={`coz-bar-banner${unmounted ? ' unmounted' : ''}`}>
|
|
29
|
+
<p>{t(`banner.${code}.description`)}</p>
|
|
30
|
+
<ButtonLink
|
|
31
|
+
className="coz-bar-banner-button"
|
|
32
|
+
size="tiny"
|
|
33
|
+
href={links}
|
|
34
|
+
label={t(`banner.${code}.CTA`)}
|
|
35
|
+
/>
|
|
36
|
+
</div>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default translate()(Banner)
|