cozy-ui 127.10.1 → 127.12.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/package.json +1 -1
  3. package/react/Contacts/GroupsSelect/GroupCreation.jsx +95 -0
  4. package/react/Contacts/GroupsSelect/GroupsSelect.jsx +159 -0
  5. package/react/Contacts/GroupsSelect/GroupsSelect.spec.jsx +248 -0
  6. package/react/Contacts/GroupsSelect/GroupsSelectProvider.jsx +39 -0
  7. package/react/Contacts/GroupsSelect/Readme.md +1 -0
  8. package/react/Contacts/GroupsSelect/SelectBox/Control.jsx +36 -0
  9. package/react/Contacts/GroupsSelect/SelectBox/EditGroupName.jsx +52 -0
  10. package/react/Contacts/GroupsSelect/SelectBox/Menu.jsx +26 -0
  11. package/react/Contacts/GroupsSelect/SelectBox/Option.jsx +67 -0
  12. package/react/Contacts/GroupsSelect/SelectBox/SelectContainer.jsx +15 -0
  13. package/react/Contacts/GroupsSelect/SelectBox/styles.styl +2 -0
  14. package/react/Contacts/GroupsSelect/helpers.js +25 -0
  15. package/react/Contacts/GroupsSelect/locales/en.json +21 -0
  16. package/react/Contacts/GroupsSelect/locales/fr.json +21 -0
  17. package/react/Contacts/GroupsSelect/locales/index.jsx +12 -0
  18. package/react/Contacts/GroupsSelect/styles.styl +47 -0
  19. package/react/Contacts/GroupsSelect/useGroupSelect.jsx +88 -0
  20. package/react/Contacts/Header/GroupsSelection.jsx +74 -0
  21. package/react/Contacts/Header/ImportDropdown.jsx +78 -0
  22. package/react/Contacts/Header/Readme.md +40 -0
  23. package/react/Contacts/Header/SearchInput.jsx +19 -0
  24. package/react/Contacts/Header/index.jsx +79 -0
  25. package/react/Contacts/Header/locales/en.json +15 -0
  26. package/react/Contacts/Header/locales/fr.json +15 -0
  27. package/react/Contacts/Header/locales/index.jsx +12 -0
  28. package/react/Contacts/Readme.md +1 -0
  29. package/react/ContactsList/ContactCell.jsx +58 -0
  30. package/react/ContactsList/helpers.js +50 -1
  31. package/react/ContactsList/helpers.spec.js +50 -1
  32. package/react/ContactsList/locales/en.json +3 -1
  33. package/react/ContactsList/locales/fr.json +3 -1
  34. package/react/providers/Selection/Readme.md +28 -0
  35. package/react/providers/Selection/index.jsx +85 -0
  36. package/transpiled/react/Contacts/GroupsSelect/GroupCreation.d.ts +3 -0
  37. package/transpiled/react/Contacts/GroupsSelect/GroupCreation.js +133 -0
  38. package/transpiled/react/Contacts/GroupsSelect/GroupsSelect.d.ts +56 -0
  39. package/transpiled/react/Contacts/GroupsSelect/GroupsSelect.js +181 -0
  40. package/transpiled/react/Contacts/GroupsSelect/GroupsSelect.spec.d.ts +22 -0
  41. package/transpiled/react/Contacts/GroupsSelect/GroupsSelectProvider.d.ts +5 -0
  42. package/transpiled/react/Contacts/GroupsSelect/GroupsSelectProvider.js +38 -0
  43. package/transpiled/react/Contacts/GroupsSelect/SelectBox/Control.d.ts +14 -0
  44. package/transpiled/react/Contacts/GroupsSelect/SelectBox/Control.js +37 -0
  45. package/transpiled/react/Contacts/GroupsSelect/SelectBox/EditGroupName.d.ts +7 -0
  46. package/transpiled/react/Contacts/GroupsSelect/SelectBox/EditGroupName.js +71 -0
  47. package/transpiled/react/Contacts/GroupsSelect/SelectBox/Menu.d.ts +7 -0
  48. package/transpiled/react/Contacts/GroupsSelect/SelectBox/Menu.js +34 -0
  49. package/transpiled/react/Contacts/GroupsSelect/SelectBox/Option.d.ts +18 -0
  50. package/transpiled/react/Contacts/GroupsSelect/SelectBox/Option.js +66 -0
  51. package/transpiled/react/Contacts/GroupsSelect/SelectBox/SelectContainer.d.ts +2 -0
  52. package/transpiled/react/Contacts/GroupsSelect/SelectBox/SelectContainer.js +12 -0
  53. package/transpiled/react/Contacts/GroupsSelect/helpers.d.ts +9 -0
  54. package/transpiled/react/Contacts/GroupsSelect/helpers.js +30 -0
  55. package/transpiled/react/Contacts/GroupsSelect/locales/index.d.ts +6 -0
  56. package/transpiled/react/Contacts/GroupsSelect/locales/index.js +49 -0
  57. package/transpiled/react/Contacts/GroupsSelect/useGroupSelect.d.ts +11 -0
  58. package/transpiled/react/Contacts/GroupsSelect/useGroupSelect.js +179 -0
  59. package/transpiled/react/Contacts/Header/GroupsSelection.d.ts +7 -0
  60. package/transpiled/react/Contacts/Header/GroupsSelection.js +84 -0
  61. package/transpiled/react/Contacts/Header/ImportDropdown.d.ts +4 -0
  62. package/transpiled/react/Contacts/Header/ImportDropdown.js +88 -0
  63. package/transpiled/react/Contacts/Header/SearchInput.d.ts +4 -0
  64. package/transpiled/react/Contacts/Header/SearchInput.js +24 -0
  65. package/transpiled/react/Contacts/Header/index.d.ts +26 -0
  66. package/transpiled/react/Contacts/Header/index.js +72 -0
  67. package/transpiled/react/Contacts/Header/locales/index.d.ts +6 -0
  68. package/transpiled/react/Contacts/Header/locales/index.js +37 -0
  69. package/transpiled/react/ContactsList/ContactCell.d.ts +8 -0
  70. package/transpiled/react/ContactsList/ContactCell.js +68 -0
  71. package/transpiled/react/ContactsList/helpers.d.ts +1 -0
  72. package/transpiled/react/ContactsList/helpers.js +51 -1
  73. package/transpiled/react/ContactsList/locales/withContactsListLocales.js +6 -2
  74. package/transpiled/react/providers/Selection/index.d.ts +6 -0
  75. package/transpiled/react/providers/Selection/index.js +99 -0
  76. package/transpiled/react/stylesheet.css +1 -1
@@ -0,0 +1,67 @@
1
+ import PropTypes from 'prop-types'
2
+ import React from 'react'
3
+
4
+ import EditGroupName from './EditGroupName'
5
+ import { ActionsOption, Option as DefaultOption } from '../../../SelectBox'
6
+
7
+ const Option = props => {
8
+ const { name: groupName, id: groupId, withNoAction } = props.data
9
+ const {
10
+ editedGroupId,
11
+ setEditedGroupId,
12
+ deleteGroup,
13
+ renameGroup,
14
+ withCheckbox
15
+ } = props.selectProps
16
+
17
+ if (editedGroupId === groupId) {
18
+ return (
19
+ <EditGroupName
20
+ groupId={groupId}
21
+ groupName={groupName}
22
+ setEditedGroupId={setEditedGroupId}
23
+ renameGroup={renameGroup}
24
+ />
25
+ )
26
+ }
27
+
28
+ if (withNoAction) {
29
+ return <DefaultOption {...props} />
30
+ }
31
+
32
+ return (
33
+ <ActionsOption
34
+ {...props}
35
+ withCheckbox={withCheckbox}
36
+ actions={[
37
+ {
38
+ icon: 'pen',
39
+ onClick: ({ data }) => setEditedGroupId(data.id),
40
+ iconProps: {
41
+ 'data-testid': `ActionsOption_${props.children}-icon_pen`
42
+ }
43
+ },
44
+ {
45
+ icon: 'trash',
46
+ onClick: ({ data }) => deleteGroup(data)
47
+ }
48
+ ]}
49
+ />
50
+ )
51
+ }
52
+
53
+ Option.propTypes = {
54
+ selectProps: PropTypes.shape({
55
+ editedGroupId: PropTypes.string.isRequired,
56
+ deleteGroup: PropTypes.func.isRequired,
57
+ setEditedGroupId: PropTypes.func.isRequired,
58
+ withCheckbox: PropTypes.bool
59
+ }),
60
+ data: PropTypes.shape({
61
+ name: PropTypes.string.isRequired,
62
+ id: PropTypes.string,
63
+ withNoAction: PropTypes.bool
64
+ })
65
+ }
66
+
67
+ export default Option
@@ -0,0 +1,15 @@
1
+ import classNames from 'classnames'
2
+ import React from 'react'
3
+
4
+ import { components } from '../../../SelectBox'
5
+
6
+ const SelectContainer = props => {
7
+ return (
8
+ <components.SelectContainer
9
+ {...props}
10
+ className={classNames(props.className, 'react-select__custom__container')}
11
+ />
12
+ )
13
+ }
14
+
15
+ export default SelectContainer
@@ -0,0 +1,2 @@
1
+ .menu
2
+ min-width fit-content
@@ -0,0 +1,25 @@
1
+ export const isExistingGroup = (groupsAlreadyCreated, groupToCreate) => {
2
+ const isNameAlreadyUsed =
3
+ groupsAlreadyCreated.find(
4
+ group => group.name.toLowerCase() === groupToCreate.name.toLowerCase()
5
+ ) !== undefined
6
+
7
+ return isNameAlreadyUsed
8
+ }
9
+
10
+ /**
11
+ * Returns the group defined as default in the group filter
12
+ */
13
+ export const defaultSelectedGroup = {
14
+ name: 'Contacts.GroupsSelect.filter.all-groups',
15
+ withNoAction: true
16
+ }
17
+
18
+ /**
19
+ * Returns the translated group defined as default in the group filter
20
+ * @param {function} t - Translate
21
+ */
22
+ export const translatedDefaultSelectedGroup = t => ({
23
+ ...defaultSelectedGroup,
24
+ name: t(defaultSelectedGroup.name)
25
+ })
@@ -0,0 +1,21 @@
1
+ {
2
+ "Contacts": {
3
+ "GroupsSelect": {
4
+ "create": "Create a group",
5
+ "name": "Name of the group",
6
+ "already_exists": "The group %{name} already exists.",
7
+ "manage": "Groups",
8
+ "filter": {
9
+ "all-groups": "All groups"
10
+ },
11
+ "created": {
12
+ "success": "The group has been created correctly.",
13
+ "error": "The group has not been created."
14
+ },
15
+ "renamed": {
16
+ "success": "The group has been renamed correctly.",
17
+ "error": "The group has not been renamed."
18
+ }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "Contacts": {
3
+ "GroupsSelect": {
4
+ "create": "Créer un groupe",
5
+ "name": "Nom du groupe",
6
+ "already_exists": "Le groupe %{name} existe déjà.",
7
+ "manage": "Groupes",
8
+ "filter": {
9
+ "all-groups": "Tous les groupes"
10
+ },
11
+ "created": {
12
+ "success": "Le groupe a bien été créé.",
13
+ "error": "Le groupe n'a pas été créé."
14
+ },
15
+ "renamed": {
16
+ "success": "Le groupe a bien été renommé.",
17
+ "error": "Le groupe n'a pas été renommé."
18
+ }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,12 @@
1
+ import en from './en.json'
2
+ import fr from './fr.json'
3
+ // import { getI18n } from '../../../providers/I18n/helpers'
4
+ // import withOnlyLocales from '../../../providers/I18n/withOnlyLocales'
5
+
6
+ export const locales = {
7
+ en,
8
+ fr
9
+ }
10
+
11
+ // export const getOwnI18n = () => getI18n(undefined, lang => locales[lang])
12
+ // export default withOnlyLocales(locales)
@@ -0,0 +1,47 @@
1
+ @require 'cozy-ui'
2
+
3
+ .container
4
+ height rem(48)
5
+ display flex
6
+ align-items center
7
+ color var(--primaryTextColor)
8
+
9
+ .contact-group-creation-divider
10
+ width 100%
11
+ border-top 1px solid var(--dividerColor)
12
+
13
+ .contact-group-create-div-icon
14
+ display flex
15
+ align-items center
16
+ flex 1
17
+
18
+ /*since we keep the existing style of
19
+ react-select for the menu and we only
20
+ want to override width & zindex... important
21
+ is important. Right positionning is just set,
22
+ it overrides nothing so there's no need for
23
+ !important */
24
+ :global(.react-select__menu) // @stylint ignore Naming imposed by react-select
25
+ width rem(384) !important
26
+ z-index 100000 !important
27
+ right 0
28
+
29
+ +small-screen()
30
+ top auto !important
31
+ width 100% !important
32
+
33
+ :global(.react-select__container) // @stylint ignore Naming imposed by react-select
34
+ display inline-block
35
+ vertical-align middle
36
+
37
+ :global(.react-select__menu-notice--no-options) // @stylint ignore Naming imposed by react-select
38
+ color var(--primaryTextColor)
39
+ margin-left .5rem !important
40
+ height rem(48)
41
+ display flex
42
+ align-items center
43
+
44
+ :global(.react-select__menu-list) // @stylint ignore Naming imposed by react-select
45
+ text-align initial
46
+ +small-screen()
47
+ max-width inherit !important
@@ -0,0 +1,88 @@
1
+ import get from 'lodash/get'
2
+
3
+ import { useSelectedGroup } from './GroupsSelectProvider'
4
+ import { isExistingGroup } from './helpers'
5
+ import { locales } from './locales'
6
+ import { useAlert } from '../../providers/Alert'
7
+ import { useI18n, useExtendI18n } from '../../providers/I18n'
8
+
9
+ const useGroupsSelect = ({
10
+ allGroups,
11
+ onGroupCreated,
12
+ client,
13
+ onGroupCreate,
14
+ onGroupUpdate
15
+ }) => {
16
+ const { selectedGroup, setSelectedGroup } = useSelectedGroup()
17
+ const { showAlert } = useAlert()
18
+ useExtendI18n(locales)
19
+ const { t } = useI18n()
20
+
21
+ const createGroupSelf = async group => {
22
+ if (!group.name) return
23
+
24
+ if (isExistingGroup(allGroups, group)) {
25
+ return showAlert({
26
+ severity: 'error',
27
+ message: t('Contacts.GroupsSelect.already_exists', {
28
+ name: group.name
29
+ })
30
+ })
31
+ }
32
+
33
+ try {
34
+ const { data: createdGroup } = await onGroupCreate(client, group)
35
+ if (onGroupCreated) {
36
+ onGroupCreated(createdGroup)
37
+ }
38
+ return showAlert({
39
+ severity: 'success',
40
+ message: t('Contacts.GroupsSelect.created.success')
41
+ })
42
+ } catch {
43
+ return showAlert({
44
+ severity: 'error',
45
+ message: t('Contacts.GroupsSelect.created.error')
46
+ })
47
+ }
48
+ }
49
+
50
+ const renameGroupSelf = async (groupId, newName) => {
51
+ const group = allGroups.find(group => group.id === groupId)
52
+ const allOtherGroups = allGroups.filter(group => group.id !== groupId)
53
+ const isRenamedGroupSelected =
54
+ get(group, '_id') === get(selectedGroup, '_id')
55
+
56
+ if (isExistingGroup(allOtherGroups, { name: newName })) {
57
+ return showAlert({
58
+ severity: 'error',
59
+ message: t('Contacts.GroupsSelect.already_exists', {
60
+ name: newName
61
+ })
62
+ })
63
+ }
64
+
65
+ try {
66
+ const { data } = await onGroupUpdate(client, { ...group, name: newName })
67
+ if (isRenamedGroupSelected) {
68
+ setSelectedGroup(data)
69
+ }
70
+ return showAlert({
71
+ severity: 'success',
72
+ message: t('Contacts.GroupsSelect.renamed.success')
73
+ })
74
+ } catch {
75
+ return showAlert({
76
+ severity: 'error',
77
+ message: t('Contacts.GroupsSelect.renamed.error')
78
+ })
79
+ }
80
+ }
81
+
82
+ return {
83
+ createGroup: createGroupSelf,
84
+ renameGroup: renameGroupSelf
85
+ }
86
+ }
87
+
88
+ export default useGroupsSelect
@@ -0,0 +1,74 @@
1
+ import React from 'react'
2
+
3
+ import { locales } from './locales'
4
+ import { ControlDefault } from '../../SelectBox'
5
+ import { useBreakpoints } from '../../providers/Breakpoints'
6
+ import { useI18n, useExtendI18n } from '../../providers/I18n'
7
+ import GroupsSelect from '../GroupsSelect/GroupsSelect'
8
+ import { useSelectedGroup } from '../GroupsSelect/GroupsSelectProvider'
9
+ import { translatedDefaultSelectedGroup } from '../GroupsSelect/helpers'
10
+
11
+ const setGroupsSelectOptions = (allGroups, defaultSelectedGroup) =>
12
+ allGroups.length > 0 ? [defaultSelectedGroup].concat(allGroups) : allGroups
13
+
14
+ const useGroupsSelectCustomStyles = () => {
15
+ const { isMobile } = useBreakpoints()
16
+
17
+ return {
18
+ container: base => ({
19
+ ...base,
20
+ width: isMobile ? '100%' : '50%'
21
+ }),
22
+ noOptionsMessage: base => ({ ...base, textAlign: 'left' })
23
+ }
24
+ }
25
+
26
+ const ControlDefaultWithTestId = ({ ...props }) => {
27
+ return (
28
+ <ControlDefault
29
+ {...props}
30
+ innerProps={{
31
+ ...props.innerProps,
32
+ 'data-testid': 'selectBox-controlDefault',
33
+ className: 'u-bdrs-4'
34
+ }}
35
+ />
36
+ )
37
+ }
38
+
39
+ const GroupsSelection = ({
40
+ allGroups,
41
+ onGroupCreate,
42
+ onGroupUpdate,
43
+ onGroupDelete
44
+ }) => {
45
+ useExtendI18n(locales)
46
+ const { t } = useI18n()
47
+ const { selectedGroup, setSelectedGroup } = useSelectedGroup()
48
+
49
+ const groupsSelectOptions = setGroupsSelectOptions(
50
+ allGroups,
51
+ translatedDefaultSelectedGroup(t)
52
+ )
53
+
54
+ const groupsSelectCustomStyles = useGroupsSelectCustomStyles()
55
+
56
+ return (
57
+ <GroupsSelect
58
+ allGroups={groupsSelectOptions}
59
+ value={selectedGroup}
60
+ noOptionsMessage={() => t('Contacts.Header.filter.no-group')}
61
+ styles={groupsSelectCustomStyles}
62
+ closeMenuOnSelect={true}
63
+ components={{
64
+ Control: ControlDefaultWithTestId
65
+ }}
66
+ onChange={setSelectedGroup}
67
+ onGroupCreate={onGroupCreate}
68
+ onGroupUpdate={onGroupUpdate}
69
+ onGroupDelete={onGroupDelete}
70
+ />
71
+ )
72
+ }
73
+
74
+ export default GroupsSelection
@@ -0,0 +1,78 @@
1
+ import React, { useState, useRef } from 'react'
2
+
3
+ import { useClient, generateWebLink } from 'cozy-client'
4
+ import { CONTACTS_DOCTYPE } from 'cozy-client/dist/models/contact'
5
+
6
+ import { locales } from './locales'
7
+ import AppIcon from '../../AppIcon'
8
+ import AppLinker from '../../AppLinker'
9
+ import Button from '../../Buttons'
10
+ import Icon from '../../Icon'
11
+ import BottomIcon from '../../Icons/Bottom'
12
+ import TeamIcon from '../../Icons/Team'
13
+ import Link from '../../Link'
14
+ import ActionMenu, { ActionMenuItem } from '../../deprecated/ActionMenu'
15
+ import { useI18n, useExtendI18n } from '../../providers/I18n'
16
+
17
+ const ImportDropdown = ({ onContactImport }) => {
18
+ useExtendI18n(locales)
19
+ const { t } = useI18n()
20
+ const client = useClient()
21
+ const anchorRef = useRef()
22
+ const [showMenu, setShowMenu] = useState(false)
23
+
24
+ const storeURL = generateWebLink({
25
+ cozyUrl: client.getStackClient().uri,
26
+ hash: `discover/?type=konnector&doctype=${CONTACTS_DOCTYPE}`,
27
+ pathname: '/',
28
+ slug: 'store',
29
+ subDomainType: client.getInstanceOptions().subdomain
30
+ })
31
+
32
+ return (
33
+ <>
34
+ <Button
35
+ ref={anchorRef}
36
+ variant="secondary"
37
+ label={t('Contacts.Header.import.title')}
38
+ endIcon={<Icon icon={BottomIcon} />}
39
+ fullWidth
40
+ onClick={() => setShowMenu(v => !v)}
41
+ />
42
+
43
+ {showMenu && (
44
+ <ActionMenu
45
+ anchorElRef={anchorRef}
46
+ popperOptions={{ placement: 'bottom-end' }}
47
+ onClose={() => setShowMenu(false)}
48
+ >
49
+ <ActionMenuItem
50
+ left={<Icon icon={TeamIcon} />}
51
+ onClick={onContactImport}
52
+ >
53
+ {t('Contacts.Header.import.vcard')}
54
+ </ActionMenuItem>
55
+
56
+ <AppLinker app={{ slug: 'store' }} href={storeURL}>
57
+ {({ onClick, href }) => (
58
+ <ActionMenuItem
59
+ left={<AppIcon app="store" className="u-h-1 u-w-1" />}
60
+ onClick={onClick}
61
+ >
62
+ <Link
63
+ className="u-p-0"
64
+ href={href}
65
+ style={{ color: 'var(--primaryTextColor)' }}
66
+ >
67
+ {t('Contacts.Header.import.store')}
68
+ </Link>
69
+ </ActionMenuItem>
70
+ )}
71
+ </AppLinker>
72
+ </ActionMenu>
73
+ )}
74
+ </>
75
+ )
76
+ }
77
+
78
+ export default ImportDropdown
@@ -0,0 +1,40 @@
1
+ <!-- For styleguidist, a .md file is needed in directories -->
2
+
3
+ Must be used within `SelectedGroupProvider` and `AlertProvider`.
4
+
5
+ ```jsx
6
+ import Header from 'cozy-ui/transpiled/react/Contacts/Header'
7
+ import SelectedGroupProvider from 'cozy-ui/transpiled/react/Contacts/GroupsSelect/GroupsSelectProvider'
8
+ import AlertProvider from 'cozy-ui/transpiled/react/providers/Alert'
9
+ import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
10
+
11
+ ;
12
+
13
+ <DemoProvider>
14
+ <AlertProvider>
15
+ <SelectedGroupProvider>
16
+ <Header
17
+ allGroups={[]}
18
+ onContactCreate={() => {
19
+ console.info('onCreateContact')
20
+ }}
21
+ onContactImport={() => {
22
+ console.info('onImportContact')
23
+ }}
24
+ onGroupCreate={() => {
25
+ console.info('onGroupCreate')
26
+ }}
27
+ onGroupUpdate={() => {
28
+ console.info('onGroupUpdate')
29
+ }}
30
+ onGroupDelete={() => {
31
+ console.info('onGroupDelete')
32
+ }}
33
+ onSearch={searchValue => {
34
+ console.info(`onSearch with ${searchValue}`)
35
+ }}
36
+ />
37
+ </SelectedGroupProvider>
38
+ </AlertProvider>
39
+ </DemoProvider>
40
+ ```
@@ -0,0 +1,19 @@
1
+ import debounce from 'lodash/debounce'
2
+ import React, { useMemo } from 'react'
3
+
4
+ import SearchBar from '../../SearchBar'
5
+
6
+ const SearchInput = ({ setSearchValue }) => {
7
+ const delayedSetSearchValue = useMemo(
8
+ () => debounce(searchValue => setSearchValue(searchValue), 375),
9
+ [setSearchValue]
10
+ )
11
+
12
+ const handleOnChange = ev => {
13
+ delayedSetSearchValue(ev.target.value)
14
+ }
15
+
16
+ return <SearchBar size="small" elevation={0} onChange={handleOnChange} />
17
+ }
18
+
19
+ export default SearchInput
@@ -0,0 +1,79 @@
1
+ import cx from 'classnames'
2
+ import PropTypes from 'prop-types'
3
+ import React from 'react'
4
+
5
+ import GroupsSelection from './GroupsSelection'
6
+ import ImportDropdown from './ImportDropdown'
7
+ import SearchInput from './SearchInput'
8
+ import { locales } from './locales'
9
+ import Button from '../../Buttons'
10
+ import Icon from '../../Icon'
11
+ import PersonAddIcon from '../../Icons/PersonAdd'
12
+ import { useBreakpoints } from '../../providers/Breakpoints'
13
+ import { useI18n, useExtendI18n } from '../../providers/I18n'
14
+
15
+ const Header = ({
16
+ allGroups,
17
+ onContactCreate,
18
+ onContactImport,
19
+ onSearch,
20
+ onGroupCreate,
21
+ onGroupDelete,
22
+ onGroupUpdate
23
+ }) => {
24
+ useExtendI18n(locales)
25
+ const { t } = useI18n()
26
+ const { isMobile } = useBreakpoints()
27
+
28
+ return (
29
+ <div className={!isMobile ? 'u-flex u-flex-justify-between' : undefined}>
30
+ <div
31
+ className={cx('u-flex u-flex-items-center u-w-auto-s u-w-5 u-maw-6', {
32
+ 'u-mb-1': isMobile,
33
+ 'u-mr-1': !isMobile
34
+ })}
35
+ >
36
+ <Button
37
+ className="u-mr-half"
38
+ variant="ghost"
39
+ startIcon={<Icon icon={PersonAddIcon} />}
40
+ label={t('Contacts.Header.create')}
41
+ fullWidth
42
+ onClick={onContactCreate}
43
+ />
44
+ <ImportDropdown onContactImport={onContactImport} />
45
+ </div>
46
+ <div
47
+ className={
48
+ !isMobile
49
+ ? 'u-flex u-flex-items-center u-flex-justify-end u-flex-grow-1 u-maw-7'
50
+ : undefined
51
+ }
52
+ >
53
+ <GroupsSelection
54
+ allGroups={allGroups}
55
+ onGroupCreate={onGroupCreate}
56
+ onGroupUpdate={onGroupUpdate}
57
+ onGroupDelete={onGroupDelete}
58
+ />
59
+ <SearchInput setSearchValue={onSearch} />
60
+ </div>
61
+ </div>
62
+ )
63
+ }
64
+
65
+ Header.propTypes = {
66
+ allGroups: PropTypes.array,
67
+ onContactCreate: PropTypes.func,
68
+ onContactImport: PropTypes.func,
69
+ onSearch: PropTypes.func,
70
+ onGroupCreate: PropTypes.func,
71
+ onGroupUpdate: PropTypes.func,
72
+ onGroupDelete: PropTypes.func
73
+ }
74
+
75
+ Header.defaultProps = {
76
+ allGroups: []
77
+ }
78
+
79
+ export default Header
@@ -0,0 +1,15 @@
1
+ {
2
+ "Contacts": {
3
+ "Header": {
4
+ "create": "Create",
5
+ "filter": {
6
+ "no-group": "Create contact groups to facilitate filing and sharing!"
7
+ },
8
+ "import": {
9
+ "title": "Import",
10
+ "store": "From other sources",
11
+ "vcard": "From a vCard file"
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "Contacts": {
3
+ "Header": {
4
+ "create": "Créer",
5
+ "filter": {
6
+ "no-group": "Créer des groupes de contacts pour faciliter leur classement et le partage !"
7
+ },
8
+ "import": {
9
+ "title": "Importer",
10
+ "store": "Depuis d'autres sources",
11
+ "vcard": "Depuis un fichier vCard"
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,12 @@
1
+ import en from './en.json'
2
+ import fr from './fr.json'
3
+ // import { getI18n } from '../../../providers/I18n/helpers'
4
+ // import withOnlyLocales from '../../../providers/I18n/withOnlyLocales'
5
+
6
+ export const locales = {
7
+ en,
8
+ fr
9
+ }
10
+
11
+ // export const getOwnI18n = () => getI18n(undefined, lang => locales[lang])
12
+ // export default withOnlyLocales(locales)
@@ -0,0 +1 @@
1
+ <!-- For styleguidist, a .md file is needed in directories -->