From 1efe82228e63095bd6126a0dd8dfb5e64c734226 Mon Sep 17 00:00:00 2001 From: cballevre Date: Wed, 5 Jul 2023 15:27:17 +0200 Subject: [PATCH 1/5] feat: Add PermissionDialog --- react/CozyDialogs/PermissionDialog.jsx | 94 ++++++++++++++++++++++++++ react/CozyDialogs/Readme.md | 17 +++-- react/CozyDialogs/index.jsx | 1 + react/MuiCozyTheme/makeOverrides.js | 3 + 4 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 react/CozyDialogs/PermissionDialog.jsx 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/index.jsx b/react/CozyDialogs/index.jsx index c73231b028..bab9fc8a00 100644 --- a/react/CozyDialogs/index.jsx +++ b/react/CozyDialogs/index.jsx @@ -6,6 +6,7 @@ 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' diff --git a/react/MuiCozyTheme/makeOverrides.js b/react/MuiCozyTheme/makeOverrides.js index 963f1316d7..04364513f1 100644 --- a/react/MuiCozyTheme/makeOverrides.js +++ b/react/MuiCozyTheme/makeOverrides.js @@ -404,6 +404,9 @@ export const makeOverrides = theme => ({ width: '800px', maxWidth: '800px' } + }, + '&.overflow': { + overflowY: 'visible !important' // Allow the icon to overflow the dialog, otherwise it will be cut off } }, scrollPaper: { From da33511e3fdfa6a8e12accc89708fc3cb7fb6a84 Mon Sep 17 00:00:00 2001 From: cballevre Date: Mon, 3 Jul 2023 13:27:18 +0200 Subject: [PATCH 2/5] fix(EyeClosed): Remove withe stroke to adapt color change --- assets/icons/ui/eye-closed.svg | 8 +------- react/Icons/EyeClosed.jsx | 11 ++--------- 2 files changed, 3 insertions(+), 16 deletions(-) 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/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 ( - - + Date: Wed, 5 Jul 2023 15:15:24 +0200 Subject: [PATCH 3/5] feat: Add PasswordField --- docs/styleguide.config.js | 1 + react/PasswordField/Readme.md | 8 +++++ react/PasswordField/index.jsx | 53 +++++++++++++++++++++++++++++ react/PasswordField/locales/en.json | 6 ++++ react/PasswordField/locales/fr.json | 6 ++++ 5 files changed, 74 insertions(+) create mode 100644 react/PasswordField/Readme.md create mode 100644 react/PasswordField/index.jsx create mode 100644 react/PasswordField/locales/en.json create mode 100644 react/PasswordField/locales/fr.json 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/PasswordField/Readme.md b/react/PasswordField/Readme.md new file mode 100644 index 0000000000..54ec599643 --- /dev/null +++ b/react/PasswordField/Readme.md @@ -0,0 +1,8 @@ +```jsx +import PasswordField from 'cozy-ui/transpiled/react/PasswordField' +import DemoProvider from 'cozy-ui/docs/components/DemoProvider'; + + + + +``` diff --git a/react/PasswordField/index.jsx b/react/PasswordField/index.jsx new file mode 100644 index 0000000000..4da1a8cb0e --- /dev/null +++ b/react/PasswordField/index.jsx @@ -0,0 +1,53 @@ +import React, { useState } from 'react' + +import TextField from '../TextField' +import IconButton from '../IconButton' +import Icon from '../Icon' +import InputAdornment from '../InputAdornment' +import EyeIcon from '../Icons/Eye' +import EyeClosedIcon from '../Icons/EyeClosed' +import { useI18n } from '../I18n' +import withOnlyLocales from '../I18n/withOnlyLocales' + +import en from './locales/en.json' +import fr from './locales/fr.json' + +export const locales = { + en, + fr +} + +/** + * Password field with the option of hiding or displaying it + */ +const PasswordField = props => { + const { t } = useI18n() + const [hidden, setHidden] = useState(true) + + return ( + + + + ), + ...props.InputProps + }} + /> + ) +} + +export default withOnlyLocales(locales)(PasswordField) diff --git a/react/PasswordField/locales/en.json b/react/PasswordField/locales/en.json new file mode 100644 index 0000000000..94c2023f42 --- /dev/null +++ b/react/PasswordField/locales/en.json @@ -0,0 +1,6 @@ +{ + "password-field": { + "show": "Show password", + "hide": "Hide password" + } +} diff --git a/react/PasswordField/locales/fr.json b/react/PasswordField/locales/fr.json new file mode 100644 index 0000000000..18247076e2 --- /dev/null +++ b/react/PasswordField/locales/fr.json @@ -0,0 +1,6 @@ +{ + "password-field": { + "show": "Afficher le mot de passe", + "hide": "Masquer le mot de passe" + } +} From df294e59c69d1795c0ba45e6cd17e52dab59da2a Mon Sep 17 00:00:00 2001 From: cballevre Date: Tue, 27 Jun 2023 18:29:30 +0200 Subject: [PATCH 4/5] feat: Add CozyAuthentification illustration --- assets/icons/illus/cozy-authentification.svg | 1 + react/Icon/Readme.md | 7 +++++-- react/Icons/CozyAuthentification.jsx | 21 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 assets/icons/illus/cozy-authentification.svg create mode 100644 react/Icons/CozyAuthentification.jsx 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/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 From cde78f9c051fbe931d9b0480976c0a2e3c49a706 Mon Sep 17 00:00:00 2001 From: cballevre Date: Tue, 27 Jun 2023 18:30:59 +0200 Subject: [PATCH 5/5] feat: Add AuthentificationDialog --- .../AuthentificationDialog.jsx | 109 ++++++++++++++++++ react/CozyDialogs/SpecificDialogs/Readme.md | 58 ++++++++++ react/CozyDialogs/SpecificDialogs/index.jsx | 1 + .../SpecificDialogs/locales/en.json | 14 +++ .../SpecificDialogs/locales/fr.json | 14 +++ react/CozyDialogs/index.jsx | 5 +- 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 react/CozyDialogs/SpecificDialogs/AuthentificationDialog.jsx 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 bab9fc8a00..34abdc642f 100644 --- a/react/CozyDialogs/index.jsx +++ b/react/CozyDialogs/index.jsx @@ -9,4 +9,7 @@ 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'