diff --git a/assets/icons/illus/cozy-authentification.svg b/assets/icons/illus/cozy-authentification.svg
new file mode 100644
index 0000000000..3ee946131c
--- /dev/null
+++ b/assets/icons/illus/cozy-authentification.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/ui/eye-closed.svg b/assets/icons/ui/eye-closed.svg
index 279c8a2871..8ce79592ed 100644
--- a/assets/icons/ui/eye-closed.svg
+++ b/assets/icons/ui/eye-closed.svg
@@ -1,7 +1 @@
-
+
\ No newline at end of file
diff --git a/docs/styleguide.config.js b/docs/styleguide.config.js
index 3438bd63b6..f555f4e210 100644
--- a/docs/styleguide.config.js
+++ b/docs/styleguide.config.js
@@ -93,6 +93,7 @@ module.exports = {
'../react/NoSsr',
'../react/OutlinedInput',
'../react/Paper',
+ '../react/PasswordField',
'../react/PieChart',
'../react/Progress',
'../react/ProgressionBanner',
diff --git a/react/CozyDialogs/PermissionDialog.jsx b/react/CozyDialogs/PermissionDialog.jsx
new file mode 100644
index 0000000000..514d4d938e
--- /dev/null
+++ b/react/CozyDialogs/PermissionDialog.jsx
@@ -0,0 +1,94 @@
+import React from 'react'
+import cx from 'classnames'
+
+import { makeStyles } from '../styles'
+import CozyTheme from '../CozyTheme'
+import ConfirmDialog from './ConfirmDialog'
+import PropTypes from 'prop-types'
+import Icon from '../Icon'
+import Paper from '../Paper'
+
+const useStyles = makeStyles({
+ floatingIcon: {
+ top: '-2.25rem',
+ width: '4.5rem',
+ height: '4.5rem'
+ }
+})
+
+/**
+ * Dialog for confirmation actions linked to the Cozy system (permissions, authentication, etc.)
+ */
+const PermissionDialog = ({
+ open,
+ icon,
+ title,
+ content,
+ actions,
+ actionsLayout,
+ onClose
+}) => {
+ const styles = useStyles()
+
+ return (
+
+
+
+
+
+
+
+ {title}
+ >
+ }
+ content={content}
+ actions={actions}
+ actionsLayout={actionsLayout}
+ onClose={onClose}
+ />
+
+ )
+}
+
+PermissionDialog.propTypes = {
+ /** To open/close the modal */
+ open: PropTypes.bool.isRequired,
+ /** Icon to describe the action to be taken */
+ icon: PropTypes.func.isRequired,
+ /** Title of the modal */
+ title: PropTypes.string.isRequired,
+ /** Content of the modal */
+ content: PropTypes.node,
+ /** Actions of the modal */
+ actions: PropTypes.node,
+ /** Actions can be displayed as "rows" or "columns" */
+ actionsLayout: PropTypes.oneOf(['row', 'column']),
+ /** Triggered function on modal close action */
+ onClose: PropTypes.func
+}
+
+export default PermissionDialog
diff --git a/react/CozyDialogs/Readme.md b/react/CozyDialogs/Readme.md
index 49f4efaca9..0b05a09812 100644
--- a/react/CozyDialogs/Readme.md
+++ b/react/CozyDialogs/Readme.md
@@ -59,7 +59,8 @@ import {
ConfirmDialog,
IllustrationDialog,
FixedDialog,
- FixedActionsDialog
+ FixedActionsDialog,
+ PermissionDialog
} from 'cozy-ui/transpiled/react/CozyDialogs'
import { BreakpointsProvider } from 'cozy-ui/transpiled/react/hooks/useBreakpoints'
@@ -77,6 +78,7 @@ import FormLabel from 'cozy-ui/transpiled/react/FormLabel'
import BottomSheet, { BottomSheetItem } from 'cozy-ui/transpiled/react/BottomSheet'
import Stack from 'cozy-ui/transpiled/react/Stack'
+import ToTheCloudIcon from 'cozy-ui/transpiled/react/Icons/ToTheCloud'
import CloudIcon from "cozy-ui/transpiled/react/Icons/Cloud"
import BackgroundImg from './background.png'
@@ -133,7 +135,8 @@ const dialogTitles = {
IllustrationDialog: ,
FixedDialog: 'Fixed Dialog',
FixedActionsDialog: 'Fixed Actions Dialog',
- Dialog: 'Dialog'
+ Dialog: 'Dialog',
+ PermissionDialog: 'Are you sure ?'
}
const dialogContents = {
@@ -141,7 +144,8 @@ const dialogContents = {
IllustrationDialog: "An IllustrationDialog contains short content." + content.ada.short,
FixedDialog: "A FixedDialog can contain very long content. Actions are at the bottom of the content are not visible to the user if she has not scrolled to the bottom. " + content.ada.long,
FixedActionsDialog: "A FixedActionsDialog can contain very long content. Actions are visible even without scrolling. " + content.ada.long,
- Dialog: "A normal Dialog should contain short content. " + content.ada.short
+ Dialog: "A normal Dialog should contain short content. " + content.ada.short,
+ PermissionDialog: "Content of a confirm dialog, precising what the actions will do, and asking the user if she is sure.",
}
const dialogActions = {
@@ -149,7 +153,8 @@ const dialogActions = {
IllustrationDialog: ,
FixedDialog: ,
FixedActionsDialog: ,
- Dialog:
+ Dialog: ,
+ PermissionDialog: ,
}
const dialogs = [
@@ -157,7 +162,8 @@ const dialogs = [
ConfirmDialog,
IllustrationDialog,
FixedDialog,
- FixedActionsDialog
+ FixedActionsDialog,
+ PermissionDialog
]
const StateRadio = ({ name, ...props }) => {
@@ -326,6 +332,7 @@ const setFlagshipVars = () => {
}
disableGutters={variant.disableGutters}
background={variant.withBackground ? `var(--paperBackgroundColor) repeat-x url(${BackgroundImg})` : undefined}
+ icon={DialogComponent === PermissionDialog ? CloudIcon : undefined}
content={
<>
diff --git a/react/CozyDialogs/SpecificDialogs/AuthentificationDialog.jsx b/react/CozyDialogs/SpecificDialogs/AuthentificationDialog.jsx
new file mode 100644
index 0000000000..c1b82ec760
--- /dev/null
+++ b/react/CozyDialogs/SpecificDialogs/AuthentificationDialog.jsx
@@ -0,0 +1,109 @@
+import React, { useMemo, useState } from 'react'
+import PropTypes from 'prop-types'
+
+import PermissionDialog from '../PermissionDialog'
+import Buttons from '../../Buttons'
+import { useI18n } from '../../I18n'
+import Typography from '../../Typography'
+import { useClient } from 'cozy-client'
+import CozyAuthentificationIcon from '../../Icons/CozyAuthentification'
+import PasswordField from '../../PasswordField'
+
+import withSpecificDialogsLocales from './withSpecificDialogsLocales'
+
+/**
+ * Dialog used to authenticate a user in the cozy system.
+ * The authentication logic is implemented in the applications.
+ */
+const AuthentificationDialog = ({
+ onClose,
+ onSubmit,
+ isLoading,
+ isOIDC,
+ error
+}) => {
+ const { t } = useI18n()
+ const client = useClient()
+ const [password, setPassword] = useState('')
+
+ const handleSubmit = e => {
+ e.preventDefault()
+ onSubmit(password)
+ }
+
+ const onPasswordChange = e => {
+ setPassword(e.currentTarget.value)
+ }
+
+ const passphraseResetUrl = useMemo(() => {
+ const url = new URL('/auth/passphrase_reset', client.getStackClient().uri)
+ return url.href
+ }, [client])
+
+ return (
+
+
+ {t('authentification-dialog.subtitle')}
+
+
+
+ {t('authentification-dialog.forgotten-password')}
+
+
+ }
+ actions={
+
+ }
+ />
+ )
+}
+
+AuthentificationDialog.defaultProps = {
+ isOIDC: false
+}
+
+AuthentificationDialog.propTypes = {
+ /** A function call on clicking the close button */
+ onClose: PropTypes.func,
+ /** A function call on submitting the form with the password entered */
+ onSubmit: PropTypes.func,
+ /** Waiting status, e.g. processing of form submission */
+ isLoading: PropTypes.bool,
+ /** Show specific wording for OIDC */
+ isOIDC: PropTypes.bool,
+ /** Error key to display a message */
+ error: PropTypes.string
+}
+
+export default withSpecificDialogsLocales(AuthentificationDialog)
diff --git a/react/CozyDialogs/SpecificDialogs/Readme.md b/react/CozyDialogs/SpecificDialogs/Readme.md
index c7c5f0691b..07cfc328dd 100644
--- a/react/CozyDialogs/SpecificDialogs/Readme.md
+++ b/react/CozyDialogs/SpecificDialogs/Readme.md
@@ -21,3 +21,61 @@ const [open, setOpen] = useState(isTesting());
{ setOpen(true) }} label="Open InstallFlagshipAppDialog" />
```
+
+### Authentification dialog
+
+Dialog used to authenticate a user in the cozy system. The authentication logic is implemented in the applications.
+
+```jsx
+import { AuthentificationDialog } from 'cozy-ui/transpiled/react/CozyDialogs'
+import Button from 'cozy-ui/transpiled/react/Buttons'
+import DemoProvider from 'cozy-ui/docs/components/DemoProvider'
+import Variants from 'cozy-ui/docs/components/Variants'
+import FormControlLabel from 'cozy-ui/transpiled/react/FormControlLabel'
+import RadioGroup from 'cozy-ui/transpiled/react/RadioGroup'
+import Radio from 'cozy-ui/transpiled/react/Radios'
+import FormControl from 'cozy-ui/transpiled/react/FormControl'
+import FormLabel from 'cozy-ui/transpiled/react/FormLabel'
+
+initialState = { showModal: false };
+
+const initialVariants = [{
+ closable: true,
+ loading: false,
+ oidc: false
+}]
+
+const initialErrors = [{
+ default: true,
+ invalid_password: false,
+ server_error: false
+}]
+
+const onClose = () => setState({ showModal: false })
+
+const onAuthentification = () => {
+ alert('authentification')
+ setState({ showModal: false })
+};
+
+
+ {variant => (
+
+ {error => (
+
+
+ )}
+
+ )}
+
+```
diff --git a/react/CozyDialogs/SpecificDialogs/index.jsx b/react/CozyDialogs/SpecificDialogs/index.jsx
index bbba582699..2e7e13b9a4 100644
--- a/react/CozyDialogs/SpecificDialogs/index.jsx
+++ b/react/CozyDialogs/SpecificDialogs/index.jsx
@@ -1 +1,2 @@
export { default as InstallFlagshipAppDialog } from './InstallFlagshipAppDialog'
+export { default as AuthentificationDialog } from './AuthentificationDialog'
diff --git a/react/CozyDialogs/SpecificDialogs/locales/en.json b/react/CozyDialogs/SpecificDialogs/locales/en.json
index 4c375dfd80..537a0f0270 100644
--- a/react/CozyDialogs/SpecificDialogs/locales/en.json
+++ b/react/CozyDialogs/SpecificDialogs/locales/en.json
@@ -3,5 +3,19 @@
"title": "Scan the QR Code",
"text": "or go directly to the App Store
or Play Store to install the Cozy Cloud app",
"a11n": "Go to the Cozy Cloud application download page"
+ },
+ "authentification-dialog": {
+ "title": "Login",
+ "title-oidc": "Cozy Pass",
+ "subtitle": "For security, please confirm your identity",
+ "label": "Cozy password",
+ "label-oidc": "Cozy Pass password",
+ "abort": "Leave",
+ "unlock": "Unlock",
+ "forgotten-password": "I forgot my password",
+ "errors": {
+ "invalid_password": "Incorrect password, try again.",
+ "server_error": "Something went wrong with the server. Please, reload the page."
+ }
}
}
diff --git a/react/CozyDialogs/SpecificDialogs/locales/fr.json b/react/CozyDialogs/SpecificDialogs/locales/fr.json
index b72053df60..ab06005bf7 100644
--- a/react/CozyDialogs/SpecificDialogs/locales/fr.json
+++ b/react/CozyDialogs/SpecificDialogs/locales/fr.json
@@ -3,5 +3,19 @@
"title": "Scannez le QR Code",
"text": "ou rendez vous directement sur l’App Store
ou sur le Play Store pour installer l’app Cloud Personnel Cozy",
"a11n": "Aller sur la page de téléchargement de l'application Cloud Personnel Cozy"
+ },
+ "authentification-dialog": {
+ "title": "Authentification",
+ "title-oidc": "Cozy Pass",
+ "subtitle": "Par sécurité, merci de confirmer votre identité",
+ "label": "Mot de passe Cozy",
+ "label-oidc": "Mot de passe Cozy Pass",
+ "abort": "Quitter",
+ "unlock": "Déverrouiller",
+ "forgotten-password": "J'ai oublié mon mot de passe",
+ "errors": {
+ "invalid_password": "Mot de passe incorrect, essayer à nouveau.",
+ "server_error": "Une erreur s'est produite. Merci de recharger la page."
+ }
}
}
diff --git a/react/CozyDialogs/index.jsx b/react/CozyDialogs/index.jsx
index c73231b028..34abdc642f 100644
--- a/react/CozyDialogs/index.jsx
+++ b/react/CozyDialogs/index.jsx
@@ -6,6 +6,10 @@ export { default as ConfirmDialog } from './ConfirmDialog'
export { default as FixedActionsDialog } from './FixedActionsDialog'
export { default as FixedDialog } from './FixedDialog'
export { default as IllustrationDialog } from './IllustrationDialog'
+export { default as PermissionDialog } from './PermissionDialog'
export { default as useCozyDialog } from './useCozyDialog'
export { default as TopAnchoredDialog } from './TopAnchoredDialog'
-export { InstallFlagshipAppDialog } from './SpecificDialogs'
+export {
+ InstallFlagshipAppDialog,
+ AuthentificationDialog
+} from './SpecificDialogs'
diff --git a/react/Icon/Readme.md b/react/Icon/Readme.md
index 084a8f8527..1b65deba0d 100644
--- a/react/Icon/Readme.md
+++ b/react/Icon/Readme.md
@@ -583,6 +583,8 @@ import CheckWhiteIcon from 'cozy-ui/transpiled/react/Icons/CheckWhite'
import DashWhiteIcon from 'cozy-ui/transpiled/react/Icons/DashWhite'
import KeychainIcon from 'cozy-ui/transpiled/react/Icons/Keychain'
import CozyUpgradeIcon from 'cozy-ui/transpiled/react/Icons/CozyUpgrade'
+import CozyAuthentificationIcon from 'cozy-ui/transpiled/react/Icons/CozyAuthentification'
+
const icons = [
CozyIcon,
@@ -617,7 +619,8 @@ const icons = [
CheckWhiteIcon,
DashWhiteIcon,
KeychainIcon,
- CozyUpgradeIcon
+ CozyUpgradeIcon,
+ CozyAuthentificationIcon
]
const wrapperStyle = {
@@ -657,7 +660,7 @@ import Icon from 'cozy-ui/transpiled/react/Icon'
import Typography from 'cozy-ui/transpiled/react/Typography'
import Sprite from 'cozy-ui/transpiled/react/Icon/Sprite'
-const availableIcons = ['cozy', 'cloud-broken', 'cozy-logo', 'device-laptop', 'device-phone', 'device-tablet', 'device-browser', 'file-type-audio', 'file-type-bin', 'file-type-code', 'file-type-files', 'file-type-folder', 'file-type-image', 'file-type-note', 'file-type-pdf', 'file-type-sheet', 'file-type-slide', 'file-type-text', 'file-type-video', 'file-type-zip', 'file-type-banking-account' , 'forbidden-sign', 'google', 'logout-large', 'top-select', 'bottom-select', 'check-white', 'dash-white', 'keychain', 'contacts', 'papers', 'store', 'cozy-upgrade']
+const availableIcons = ['cozy', 'cloud-broken', 'cozy-logo', 'device-laptop', 'device-phone', 'device-tablet', 'device-browser', 'file-type-audio', 'file-type-bin', 'file-type-code', 'file-type-files', 'file-type-folder', 'file-type-image', 'file-type-note', 'file-type-pdf', 'file-type-sheet', 'file-type-slide', 'file-type-text', 'file-type-video', 'file-type-zip', 'file-type-banking-account' , 'forbidden-sign', 'google', 'logout-large', 'top-select', 'bottom-select', 'check-white', 'dash-white', 'keychain', 'contacts', 'papers', 'store', 'cozy-upgrade', 'cozy-authentification']
;
diff --git a/react/Icons/CozyAuthentification.jsx b/react/Icons/CozyAuthentification.jsx
new file mode 100644
index 0000000000..5ab9604cfb
--- /dev/null
+++ b/react/Icons/CozyAuthentification.jsx
@@ -0,0 +1,21 @@
+// Automatically created, please run `scripts/generate-svgr-icon.sh assets/icons/illus/cozy-authentification.svg` to regenerate;
+import React from 'react'
+
+function SvgCozyAuthentification(props) {
+ return (
+
+ )
+}
+
+export default SvgCozyAuthentification
diff --git a/react/Icons/EyeClosed.jsx b/react/Icons/EyeClosed.jsx
index 519df2d4f2..20af131737 100644
--- a/react/Icons/EyeClosed.jsx
+++ b/react/Icons/EyeClosed.jsx
@@ -1,18 +1,11 @@
-// Automatically created, please run `scripts/generate-svg-icon.sh assets/icons/ui/eye-closed.svg` to regenerate;
+// Automatically created, please run `scripts/generate-svgr-icon.sh assets/icons/ui/eye-closed.svg` to regenerate;
import React from 'react'
function SvgEyeClosed(props) {
return (