...
 
Commits (8)
......@@ -199,14 +199,12 @@
"cancel": "Cancel"
},
"Notifications": {
"check": "Check as read",
"remove": "Remove"
},
"NotificationsDrawer": {
"checkAll": "Check all the notifications as read",
"NotificationsDisplay": {
"empty": "You have no notifications",
"removeAll": "Remove all the notifications",
"confirmRemoveAll": "Are you sure you want to delete all the notifications ?",
"removeAllRead": "Remove all the notifications read"
"confirmRemoveAll": "Are you sure you want to delete all the notifications ?"
},
"Footer": {
"personalData": "Personal Data",
......
......@@ -199,14 +199,12 @@
"cancel": "Annuler"
},
"Notifications": {
"check": "Marquer comme lu",
"remove": "Supprimer"
},
"NotificationsDrawer": {
"checkAll": "Marquer toutes les notifications comme lues",
"NotificationsDisplay": {
"empty": "Vous n'avez aucune notification.",
"removeAll": "Supprimer toutes les notifications",
"confirmRemoveAll": "Êtes vous sûr de vouloir supprimer toutes les notifications ?",
"removeAllRead": "Supprimer toutes les notifications lues"
"confirmRemoveAll": "Êtes vous sûr de vouloir supprimer toutes les notifications ?"
},
"Footer": {
"personalData": "Données Personnelles",
......
......@@ -34,6 +34,7 @@ Notifications.schema = new SimpleSchema(
type: String,
label: getLabel('api.notifications.labels.type'),
},
link: { type: String, optional: true, label: getLabel('api.notifications.labels.link') },
createdAt: {
type: Date,
label: getLabel('api.notifications.labels.createdAt'),
......@@ -58,6 +59,7 @@ Notifications.publicFields = {
userId: 1,
title: 1,
content: 1,
link: 1,
type: 1,
createdAt: 1,
read: 1,
......
......@@ -24,6 +24,7 @@ export function createRoleNotification(currentUser, userId, groupId, role, setRo
role: roleLabel,
group: group.name,
}),
link: `/groups/${group.slug}`,
type,
};
createNotification._execute({ userId: currentUser }, { data: newNotif });
......@@ -48,6 +49,7 @@ export function createRequestNotification(currentUser, userId, groupId) {
name: user.username,
group: group.name,
}),
link: `/admingroups/${groupId}`,
type: 'request',
};
if (currentUser !== uid) {
......@@ -67,7 +69,7 @@ export function createGroupNotification(currentUser, groupId, title, content) {
const group = Groups.findOne({ _id: groupId }, { fields: Groups.adminFields });
const usersToSend = [...new Set([...group.admins, ...group.animators, ...group.members])]; // Concats arrays and removes duplicate user ids
usersToSend.forEach((uid) => {
const newNotif = { userId: uid, title, content, type: 'group' };
const newNotif = { userId: uid, title, content, link: `/groups/${group.slug}`, type: 'group' };
createNotification._execute({ userId: currentUser }, { data: newNotif });
});
}
......
......@@ -6,10 +6,12 @@ import SimpleSchema from 'simpl-schema';
export function checkDomain(email) {
let res = false;
const domainMail = email.split('@')[1];
// Put whiteDomain in config ?
const whiteDomains = [/^ac-[a-z-]*\.fr/, /^[a-z-]*\.gouv\.fr/];
const whiteDomains = Meteor.settings.private.whiteDomains || [];
whiteDomains.forEach((whiteDomain) => {
if (whiteDomain.test(domainMail)) res = true;
if (new RegExp(whiteDomain).test(domainMail)) {
console.log(` Email domain matches ${whiteDomain}: user activated`);
res = true;
}
});
return res;
}
......
......@@ -74,7 +74,7 @@ const useStyles = ({ type }, member, candidate) =>
},
}));
function GroupDetailsPersSpace({ group = {}, member, candidate, admin, animator }) {
function GroupDetailsPersSpace({ group = {}, member, candidate, admin, animator, isMobile }) {
const { type } = group;
const classes = useStyles(group, member || animator, candidate)();
......@@ -120,7 +120,7 @@ function GroupDetailsPersSpace({ group = {}, member, candidate, admin, animator
<Avatar className={classes.avatar}>{iconHeader}</Avatar>
)}
<CardContent className={classes.cardContent}>
<Typography className={classes.serviceName} gutterBottom noWrap variant="h6" component="h2">
<Typography className={classes.serviceName} gutterBottom noWrap={!isMobile} variant="h6" component="h2">
{group.name}
</Typography>
</CardContent>
......@@ -162,6 +162,7 @@ GroupDetailsPersSpace.propTypes = {
candidate: PropTypes.bool.isRequired,
admin: PropTypes.bool.isRequired,
animator: PropTypes.bool.isRequired,
isMobile: PropTypes.bool.isRequired,
};
export default GroupDetailsPersSpace;
......@@ -56,7 +56,10 @@ function TopBar({ publicMenu, root }) {
},
});
const handleDrawerOpen = () => updateGlobalState('drawerOpen', true);
const handleNotifsOpen = () => {
const notifState = notificationPage.notifsOpen || false;
updateGlobalState('notifsOpen', !notifState);
};
return (
<AppBar position="fixed" className={classes.root}>
......@@ -69,7 +72,7 @@ function TopBar({ publicMenu, root }) {
{publicMenu ? null : (
<>
<MainMenu user={user} />
<IconButton onClick={() => handleDrawerOpen()}>
<IconButton onClick={() => handleNotifsOpen()}>
<NotificationsBell />
</IconButton>
</>
......
......@@ -10,11 +10,11 @@ import {
ListItem,
ListItemIcon,
ListItemText,
Checkbox,
Typography,
makeStyles,
IconButton,
Tooltip,
Badge,
} from '@material-ui/core';
import i18n from 'meteor/universe:i18n';
......@@ -23,7 +23,7 @@ const useStyles = makeStyles(() => ({
display: 'inline',
},
isRead: {
backgroundColor: 'lightGrey',
backgroundColor: '#F9F9FD',
},
button: {
display: 'block',
......@@ -48,13 +48,6 @@ const useStyles = makeStyles(() => ({
const Notification = ({ notification, toast }) => {
const { _id, type, title, content, createdAt, read } = notification;
const classes = useStyles();
const handleToggle = () => {
Meteor.call('notifications.markNotificationAsRead', { notificationId: _id }, (err) => {
if (err) {
msg.error(err.reason);
}
});
};
const handleRemove = () => {
Meteor.call('notifications.removeNotification', { notificationId: _id }, (err) => {
......@@ -81,18 +74,32 @@ const Notification = ({ notification, toast }) => {
return (
<ListItem alignItems="flex-start" className={read ? classes.isRead : null}>
<ListItemIcon className={classes.leftIcon}>{notifIcon()}</ListItemIcon>
<ListItemIcon className={classes.leftIcon}>
<Badge
invisible={read}
variant="dot"
badgeContent=" "
overlap="circle"
color="primary"
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
>
{notifIcon()}
</Badge>
</ListItemIcon>
<ListItemText
primary={
<>
{title}
&nbsp;
<Typography component="span" variant="caption" className={classes.inline} color="textSecondary">
<Typography variant="caption" className={classes.inline} color="textSecondary">
{createdAt.toLocaleDateString()}
</Typography>
</>
}
secondary={<div>{content}</div>}
secondary={<span>{content}</span>}
/>
{toast ? null : (
<div className={classes.rightIcon}>
......@@ -104,18 +111,6 @@ const Notification = ({ notification, toast }) => {
<CloseIcon />
</IconButton>
</Tooltip>
<Tooltip
title={i18n.__('components.Notifications.check')}
aria-label={i18n.__('components.Notifications.check')}
>
<Checkbox
edge="end"
onChange={handleToggle}
checked={read}
disabled={read}
className={classes.buttonMargin}
/>
</Tooltip>
</div>
)}
</ListItem>
......
......@@ -40,7 +40,7 @@ const NotificationsBell = ({ nonReadNotifsCount }) => {
const classes = useStyles();
return (
<>
<div id="NotificationsBell">
{nonReadNotifsCount > 0 ? (
<Badge className={classes.badge} badgeContent={nonReadNotifsCount} color="primary">
<NotificationsIcon />
......@@ -48,7 +48,7 @@ const NotificationsBell = ({ nonReadNotifsCount }) => {
) : (
<NotificationsNoneIcon />
)}
</>
</div>
);
};
......
......@@ -4,12 +4,8 @@ import { withTracker } from 'meteor/react-meteor-data';
import { makeStyles } from '@material-ui/core/styles';
import Divider from '@material-ui/core/Divider';
import IconButton from '@material-ui/core/IconButton';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import DoneAllIcon from '@material-ui/icons/DoneAll';
import HighlightOff from '@material-ui/icons/HighlightOff';
import DeleteOutlineIcon from '@material-ui/icons/DeleteOutline';
import { Fade, Typography, Tooltip } from '@material-ui/core';
import Drawer from '@material-ui/core/Drawer';
import CancelIcon from '@material-ui/icons/Cancel';
import { Fade, Typography, Paper, Popper } from '@material-ui/core';
import i18n from 'meteor/universe:i18n';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
......@@ -21,31 +17,46 @@ import Notifications from '../../../api/notifications/notifications';
import { useAppContext } from '../../contexts/context';
import Notification from './Notification';
const drawerWidth = 300;
const useStyles = makeStyles((theme) => ({
drawer: {
width: drawerWidth,
flexShrink: 0,
popper: {
zIndex: 1300,
marginTop: 20,
},
paper: {
width: 400,
outline: 'none',
border: `2px solid ${theme.palette.primary.main}`,
boxShadow: theme.shadows[5],
padding: theme.spacing(1),
},
drawerPaper: {
width: drawerWidth,
notifsList: {
maxHeight: 400,
overflowY: 'scroll',
},
drawerHeader: {
divflex: {
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
justifyContent: 'flex-start',
justifyContent: 'space-between',
},
title: {
marginLeft: theme.spacing(7),
},
space: {
margin: 'auto',
footer: {
textAlign: 'center',
marginTop: 10,
},
button: {
padding: 5,
textTransform: 'none',
color: theme.palette.primary.main,
backgroundColor: theme.palette.tertiary.main,
'&:hover': {
backgroundColor: theme.palette.primary.main,
color: theme.palette.tertiary.main,
},
},
}));
const NotificationDrawer = ({ notifications, ready }) => {
const NotificationsDisplay = ({ notifications, ready }) => {
const classes = useStyles();
const [{ notificationPage }, dispatch] = useAppContext();
const [open, setOpen] = useState(false);
......@@ -59,14 +70,14 @@ const NotificationDrawer = ({ notifications, ready }) => {
},
});
const handleDrawerClose = () => updateGlobalState('drawerOpen', false);
const handleReadAll = () => {
const handleNotifsClose = () => {
// On notifs close : mark all as read
Meteor.call('notifications.markAllNotificationAsRead', {}, (err) => {
if (err) {
msg.error(err.reason);
}
});
updateGlobalState('notifsOpen', false);
};
const handleRemoveAll = () => {
......@@ -78,14 +89,6 @@ const NotificationDrawer = ({ notifications, ready }) => {
setOpen(false);
};
const handleRemoveAllRead = () => {
Meteor.call('notifications.removeAllNotificationRead', {}, (err) => {
if (err) {
msg.error(err.reason);
}
});
};
const handleOpenDialog = () => {
if (notifications.length !== 0) {
setOpen(true);
......@@ -101,88 +104,73 @@ const NotificationDrawer = ({ notifications, ready }) => {
{!ready ? (
<Spinner />
) : (
<Fade in>
<div key="right">
<Drawer
anchor="right"
open={notificationPage.drawerOpen}
classes={{
paper: classes.drawerPaper,
}}
onClose={handleDrawerClose}
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerClose}>
<ChevronRightIcon />
<Popper
className={classes.popper}
open={notificationPage.notifsOpen || false}
onClose={handleNotifsClose}
anchorEl={document.getElementById('NotificationsBell')}
placement="bottom-end"
>
<Fade in={notificationPage.notifsOpen}>
<Paper className={classes.paper}>
<div className={classes.divflex}>
<Typography variant="h6" className={classes.title}>
Notifications
</Typography>
<IconButton onClick={handleNotifsClose}>
<CancelIcon />
</IconButton>
<Typography variant="button">Notifications</Typography>
<div className={classes.space} />
<Tooltip
title={i18n.__('components.NotificationsDrawer.checkAll')}
aria-label={i18n.__('components.NotificationsDrawer.checkAll')}
>
<IconButton onClick={handleReadAll} className={classes.button}>
<DoneAllIcon />
</IconButton>
</Tooltip>
<Tooltip
title={i18n.__('components.NotificationsDrawer.removeAllRead')}
aria-label={i18n.__('components.NotificationsDrawer.removeAllRead')}
>
<IconButton onClick={handleRemoveAllRead} className={classes.button}>
<HighlightOff />
</IconButton>
</Tooltip>
<Tooltip
title={i18n.__('components.NotificationsDrawer.removeAll')}
aria-label={i18n.__('components.NotificationsDrawer.removeAll')}
>
<IconButton onClick={handleOpenDialog} className={classes.button}>
<DeleteOutlineIcon />
</IconButton>
</Tooltip>
<Dialog
open={open}
onClose={handleCloseDialog}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{i18n.__('components.NotificationsDrawer.confirmRemoveAll')}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog} color="primary">
Non
</Button>
<Button onClick={handleRemoveAll} color="primary" autoFocus>
Oui
</Button>
</DialogActions>
</Dialog>
</div>
<Dialog
open={open}
onClose={handleCloseDialog}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogContent>
<DialogContentText id="alert-dialog-description">
{i18n.__('components.NotificationsDisplay.confirmRemoveAll')}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCloseDialog} color="primary">
Non
</Button>
<Button onClick={handleRemoveAll} color="primary" autoFocus>
Oui
</Button>
</DialogActions>
</Dialog>
<Divider />
{notifications.map((notif, index) => [
<Notification key={notif._id} notification={notif} />,
notifications.length !== index + 1 ? (
<Divider className={classes.divider} key={`div-${notif._id}`} />
) : null,
])}
</Drawer>
</div>
</Fade>
<div className={classes.notifsList}>
{notifications.map((notif, index) => [
<Notification key={notif._id} notification={notif} />,
notifications.length !== index + 1 ? (
<Divider className={classes.divider} key={`div-${notif._id}`} />
) : null,
])}
</div>
{notifications.length === 0 ? (
<Typography className={classes.footer} variant="body2">
{i18n.__('components.NotificationsDisplay.empty')}
</Typography>
) : (
<div className={classes.footer}>
<Button className={classes.button} variant="body2" onClick={handleOpenDialog}>
{i18n.__('components.NotificationsDisplay.removeAll')}
</Button>
</div>
)}
</Paper>
</Fade>
</Popper>
)}
</>
);
};
NotificationDrawer.propTypes = {
NotificationsDisplay.propTypes = {
notifications: PropTypes.arrayOf(PropTypes.object).isRequired,
ready: PropTypes.bool.isRequired,
};
......@@ -194,4 +182,4 @@ export default withTracker(() => {
notifications,
ready: subscription.ready(),
};
})(NotificationDrawer);
})(NotificationsDisplay);
......@@ -69,7 +69,7 @@ const useStyles = makeStyles((theme) => ({
},
}));
function PersonalLinkDetails({ link, globalEdit, delLink, updateLink }) {
function PersonalLinkDetails({ link, globalEdit, delLink, updateLink, isMobile }) {
const { title = '', url = '', element_id: elementId } = link;
const classes = useStyles();
......@@ -125,10 +125,10 @@ function PersonalLinkDetails({ link, globalEdit, delLink, updateLink }) {
</Avatar>
)}
<CardContent className={globalEdit ? classes.cardContentEdit : classes.cardContent}>
<Typography className={classes.linkName} gutterBottom noWrap variant="h6" component="h2">
<Typography className={classes.linkName} gutterBottom noWrap={!isMobile} variant="h6" component="h2">
{state.title || i18n.__('components.PersonalLinkDetails.titleLabel')}
</Typography>
<Typography variant="body2" className={classes.linkUrl} noWrap component="p">
<Typography variant="body2" className={classes.linkUrl} noWrap={!isMobile} component="p">
{state.url || i18n.__('components.PersonalLinkDetails.urlLabel')}
</Typography>
</CardContent>
......@@ -168,6 +168,7 @@ PersonalLinkDetails.propTypes = {
globalEdit: PropTypes.bool.isRequired,
updateLink: PropTypes.func.isRequired,
delLink: PropTypes.func.isRequired,
isMobile: PropTypes.bool.isRequired,
};
export default PersonalLinkDetails;
......@@ -13,7 +13,7 @@ import VerticalAlignTopIcon from '@material-ui/icons/VerticalAlignTop';
import VerticalAlignBottomIcon from '@material-ui/icons/VerticalAlignBottom';
import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
import { Grid, makeStyles, Typography, IconButton, Paper as div, Tooltip } from '@material-ui/core';
import { Grid, makeStyles, Typography, IconButton, Tooltip } from '@material-ui/core';
import { useAppContext } from '../../contexts/context';
import Services from '../../../api/services/services';
import Groups from '../../../api/groups/groups';
......@@ -29,6 +29,7 @@ const useStyles = makeStyles((theme) => ({
'&::before': {
content: 'none',
},
backgroundColor: '#f9f9fd',
},
cursorPointer: {
cursor: 'pointer',
......@@ -50,6 +51,7 @@ const useStyles = makeStyles((theme) => ({
gridItem: {
position: 'relative',
'&.sortable-ghost': { opacity: 0.3 },
minHeight: 201,
},
handle: {
zIndex: 10,
......@@ -147,7 +149,7 @@ const PersonalZone = ({
setExpanded,
}) => {
const classes = useStyles();
const [{ userId }] = useAppContext();
const [{ userId, isMobile }] = useAppContext();
const [localIsExpanded, setIsExpanded] = useState(isExpanded || true);
const memberGroups = useTracker(() => Roles.getScopesForUser(userId, 'member'));
......@@ -310,7 +312,7 @@ const PersonalZone = ({
lg={3}
>
<div className={customDrag ? classes.handle : null} />
<ServiceDetailsPersSpace service={myservice} />
<ServiceDetailsPersSpace service={myservice} customDrag={customDrag} isMobile={isMobile} />
</Grid>
);
}
......@@ -329,6 +331,7 @@ const PersonalZone = ({
<div className={customDrag ? classes.handle : null} />
<GroupDetailsPersSpace
group={mygroup}
isMobile={isMobile}
candidate={candidateGroups.includes(elem.element_id)}
member={memberGroups.includes(elem.element_id)}
animator={animatorGroups.includes(elem.element_id)}
......@@ -351,6 +354,7 @@ const PersonalZone = ({
<div className={customDrag ? classes.handle : null} />
<PersonalLinkDetails
link={elem}
isMobile={isMobile}
globalEdit={customDrag}
updateLink={(linkId) => updatePersonalLink(index, linkId)}
delLink={(newLink) => delPersonalLink(index, newLink)}
......
......@@ -56,7 +56,7 @@ const useStyles = makeStyles((theme) => ({
},
}));
function ServiceDetailsPersSpace({ service }) {
function ServiceDetailsPersSpace({ service, customDrag, isMobile }) {
const classes = useStyles();
const history = useHistory();
const favButtonLabel = i18n.__('components.ServiceDetails.favButtonLabelNoFav');
......@@ -92,7 +92,7 @@ function ServiceDetailsPersSpace({ service }) {
<Typography
className={service.state === 5 ? classes.serviceNameDiasbled : classes.serviceName}
gutterBottom
noWrap
noWrap={!isMobile}
variant="h6"
component="h2"
>
......@@ -108,11 +108,13 @@ function ServiceDetailsPersSpace({ service }) {
</CardContent>
</CardActionArea>
<CardActions className={classes.cardActions}>
<Tooltip title={favButtonLabel} aria-label={favButtonLabel}>
<Button variant="outlined" size="small" className={classes.fab} onClick={handleFavorite}>
<RemoveIcon />
</Button>
</Tooltip>
{customDrag ? (
<Tooltip title={favButtonLabel} aria-label={favButtonLabel}>
<Button variant="outlined" size="small" className={classes.fab} onClick={handleFavorite}>
<RemoveIcon />
</Button>
</Tooltip>
) : null}
</CardActions>
</Card>
);
......@@ -120,6 +122,8 @@ function ServiceDetailsPersSpace({ service }) {
ServiceDetailsPersSpace.propTypes = {
service: PropTypes.objectOf(PropTypes.any).isRequired,
customDrag: PropTypes.bool.isRequired,
isMobile: PropTypes.bool.isRequired,
};
export default ServiceDetailsPersSpace;
......@@ -25,7 +25,7 @@ import ArticlesPage from '../pages/articles/ArticlesPage';
import EditArticlePage from '../pages/articles/EditArticlePage';
import MediaStoragePage from '../pages/MediaStoragePage';
import AdminSettingsPage from '../pages/admin/AdminSettingsPage';
import NotificationDrawer from '../components/notifications/NotificationDrawer';
import NotificationsDisplay from '../components/notifications/NotificationsDisplay';
// dynamic imports
const AdminSingleServicePage = lazy(() => import('../pages/admin/AdminSingleServicePage'));
......@@ -137,7 +137,7 @@ function MainLayout() {
{isMobile && <MobileMenu />}
</main>
)}
<NotificationDrawer />
<NotificationsDisplay />
<CustomToast />
</div>
);
......
......@@ -19,84 +19,88 @@ import Services from '../../api/services/services';
import Spinner from '../components/system/Spinner';
import PersonalSpaces from '../../api/personalspaces/personalspaces';
import PersonalZone from '../components/personalspace/PersonalZone';
import { useAppContext } from '../contexts/context';
const useStyles = makeStyles((theme) => ({
flex: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
},
cardGrid: {
paddingTop: theme.spacing(0),
paddingBottom: theme.spacing(2),
},
chip: {
margin: theme.spacing(1),
},
badge: { position: 'inherit' },
gridItem: {
position: 'relative',
'&.sortable-ghost': { opacity: 0.3 },
},
ghost: {
opacity: '1 !important',
},
spaceBetween: {
display: 'flex',
justifyContent: 'space-between',
},
handle: {
cursor: 'grab',
position: 'absolute',
textAlign: 'center',
width: 'calc(100% - 32px)',
backgroundColor: theme.palette.primary.main,
opacity: 0.2,
height: 20,
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
'&::after': {
content: '""',
width: '80%',
height: '3px',
backgroundColor: 'white',
display: 'inline-block',
marginBottom: '3px',
borderRadius: theme.shape.borderRadius,
const useStyles = (isMobile) =>
makeStyles((theme) => ({
flex: {
display: 'flex',
flexDirection: isMobile ? 'column' : 'row',
justifyContent: 'space-between',
alignItems: isMobile ? 'flex-start' : 'center',
},
},
zoneButton: {
color: theme.palette.primary.main,
opacity: 0.5,
cursor: 'pointer',
'&:hover': {
opacity: 1,
color: theme.palette.error.main,
cardGrid: {
paddingTop: theme.spacing(0),
paddingBottom: theme.spacing(2),
},
},
zoneButtonEnd: {
marginTop: 30,
opacity: 0.5,
cursor: 'pointer',
'&:hover': {
opacity: 1,
color: theme.palette.error.main,
chip: {
margin: theme.spacing(1),
},
},
divider: {
marginTop: 30,
marginBottom: 10,
},
goIcon: {
marginLeft: 8,
verticalAlign: 'bottom',
},
}));
badge: { position: 'inherit' },
gridItem: {
position: 'relative',
'&.sortable-ghost': { opacity: 0.3 },
},
ghost: {
opacity: '1 !important',
},
spaceBetween: {
display: 'flex',
justifyContent: 'space-between',
},
handle: {
cursor: 'grab',
position: 'absolute',
textAlign: 'center',
width: 'calc(100% - 32px)',
backgroundColor: theme.palette.primary.main,
opacity: 0.2,
height: 20,
borderTopLeftRadius: theme.shape.borderRadius,
borderTopRightRadius: theme.shape.borderRadius,
'&::after': {
content: '""',
width: '80%',
height: '3px',
backgroundColor: 'white',
display: 'inline-block',
marginBottom: '3px',
borderRadius: theme.shape.borderRadius,
},
},
zoneButton: {
color: theme.palette.primary.main,
opacity: 0.5,
cursor: 'pointer',
'&:hover': {
opacity: 1,
color: theme.palette.error.main,
},
},
zoneButtonEnd: {
marginTop: 30,
opacity: 0.5,
cursor: 'pointer',
'&:hover': {
opacity: 1,
color: theme.palette.error.main,
},
},
divider: {
marginTop: 30,
marginBottom: 10,
},
goIcon: {
marginLeft: 8,
verticalAlign: 'bottom',
},
}));
function PersonalPage({ personalspace, isLoading, allServices, allGroups }) {
const AUTOSAVE_INTERVAL = 3000;
const classes = useStyles();
const [{ isMobile }] = useAppContext();
const [customDrag, setcustomDrag] = useState(false);
const classes = useStyles(isMobile)();
const handleCustomDrag = (event) => {
setcustomDrag(event.target.checked);
......
......@@ -45,6 +45,10 @@
"minioSecret": "Pr6SvbtBkutUHmdlN2uYWi5g7oo5EZquMq9k2t00",
"apiKeys": [
"849b7648-14b8-4154-9ef2-8d1dc4c2b7e9"
],
"whiteDomains": [
"^ac-[a-z-]*\\.fr",
"^[a-z-]*\\.gouv.fr"
]
}
}