@craftercms/studio-ui
Version:
Services, components, models & utils to build CrafterCMS authoring extensions.
351 lines (349 loc) • 13.3 kB
JavaScript
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react';
import { useStyles } from './styles';
import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded';
import DialogBody from '../DialogBody/DialogBody';
import Typography from '@mui/material/Typography';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import Divider from '@mui/material/Divider';
import Tooltip from '@mui/material/Tooltip';
import IconButton from '@mui/material/IconButton';
import ConfirmDropdown from '../ConfirmDropdown';
import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
import SecondaryButton from '../SecondaryButton';
import PrimaryButton from '../PrimaryButton';
import Box from '@mui/material/Box';
import TransferList from '../TransferList';
import InputLabel from '@mui/material/InputLabel';
import OutlinedInput from '@mui/material/OutlinedInput';
import FormHelperText from '@mui/material/FormHelperText';
import {
GROUP_DESCRIPTION_MAX_LENGTH,
GROUP_NAME_MAX_LENGTH,
GROUP_NAME_MIN_LENGTH,
validateGroupNameMinLength,
validateRequiredField
} from '../GroupManagement/utils';
import { excludeCommonItems } from '../TransferList/utils';
const translations = defineMessages({
confirmHelperText: {
id: 'editGroupDialog.helperText',
defaultMessage: 'Delete group "{name}"?'
},
confirmOk: {
id: 'words.yes',
defaultMessage: 'Yes'
},
confirmCancel: {
id: 'words.no',
defaultMessage: 'No'
}
});
export function EditGroupDialogUI(props) {
const { classes, cx: clsx } = useStyles();
const { formatMessage } = useIntl();
const {
title,
subtitle,
group,
groupNameError,
onDeleteGroup,
onSave,
submitOk,
onCancel,
onChangeValue,
onAddMembers,
onRemoveMembers,
onCloseButtonClick,
users,
members,
membersLookup,
inProgressIds,
isDirty,
isEdit,
transferListState,
sourceItemsAllChecked,
onFilterUsers,
onFetchMoreUsers,
hasMoreUsers,
disableAddMembers,
isSubmitting
} = props;
const {
sourceItems,
sourceFilterKeyword,
setSourceFilterKeyword,
targetItems,
filteredTargetItems,
targetFilterKeyword,
setTargetFilterKeyword,
checkedList,
onItemClicked,
onCheckAllClicked,
disableRemove,
targetItemsAllChecked
} = transferListState;
return React.createElement(
React.Fragment,
null,
React.createElement(
'header',
{ className: classes.header },
React.createElement('section', null, title, subtitle),
React.createElement(
'section',
{ className: classes.actions },
onDeleteGroup &&
isEdit &&
React.createElement(ConfirmDropdown, {
cancelText: formatMessage(translations.confirmCancel),
confirmText: formatMessage(translations.confirmOk),
confirmHelperText: formatMessage(translations.confirmHelperText, {
name: group.name
}),
iconTooltip: React.createElement(FormattedMessage, {
id: 'editGroupDialog.deleteGroup',
defaultMessage: 'Delete group'
}),
icon: DeleteRoundedIcon,
onConfirm: () => {
onDeleteGroup(group);
}
}),
React.createElement(
Tooltip,
{ title: React.createElement(FormattedMessage, { id: 'editGroupDialog.close', defaultMessage: 'Close' }) },
React.createElement(
IconButton,
{ edge: 'end', onClick: onCloseButtonClick, size: 'large' },
React.createElement(CloseRoundedIcon, null)
)
)
)
),
React.createElement(Divider, null),
React.createElement(
DialogBody,
{ className: classes.body },
React.createElement(
'section',
{ className: clsx(classes.section, 'noPaddingBottom') },
React.createElement(
Typography,
{ variant: 'subtitle1', className: classes.sectionTitle },
React.createElement(FormattedMessage, { id: 'editGroupDialog.groupDetails', defaultMessage: 'Group Details' })
),
React.createElement(
'form',
{
onSubmit: (e) => {
e.preventDefault();
onSave === null || onSave === void 0 ? void 0 : onSave();
}
},
React.createElement(
Box,
{ display: 'flex', alignItems: 'center', p: '15px 0 0 0' },
React.createElement(
InputLabel,
{ htmlFor: 'groupName', className: classes.label },
React.createElement(
Typography,
{ variant: 'subtitle2' },
React.createElement(FormattedMessage, { id: 'words.name', defaultMessage: 'Name' })
)
),
isEdit
? React.createElement(
Typography,
{ className: classes.fullWidth, color: 'textSecondary', noWrap: true, title: group.name },
group.name
)
: React.createElement(OutlinedInput, {
id: 'groupName',
onChange: (e) => onChangeValue({ key: 'name', value: e.currentTarget.value }),
value: group.name,
error: groupNameError,
fullWidth: true,
autoFocus: true,
inputProps: { maxLength: GROUP_NAME_MAX_LENGTH }
})
),
React.createElement(
Box,
{ display: 'flex', p: '0 0 15px' },
React.createElement('div', { className: classes.label }),
React.createElement(FormHelperText, {
error: groupNameError,
children: validateRequiredField(group.name, isDirty)
? React.createElement(FormattedMessage, {
id: 'editGroupDialog.requiredGroupName',
defaultMessage: 'Group name is required.'
})
: validateGroupNameMinLength(group.name)
? React.createElement(FormattedMessage, {
id: 'editGroupDialog.minLength',
defaultMessage: 'Min {length} characters.',
values: {
length: GROUP_NAME_MIN_LENGTH
}
})
: React.createElement(FormattedMessage, {
id: 'editGroupDialog.invalidMinLength',
defaultMessage:
'Max {length} characters, consisting of letters, numbers, dash (-), underscore (_) and dot (.).',
values: {
length: GROUP_NAME_MAX_LENGTH
}
})
})
),
React.createElement(
Box,
{ display: 'flex', alignItems: 'center', p: '15px 0' },
React.createElement(
InputLabel,
{ htmlFor: 'groupDescription', className: classes.label },
React.createElement(
Typography,
{ variant: 'subtitle2' },
React.createElement(FormattedMessage, { id: 'words.description', defaultMessage: 'Description' })
)
),
React.createElement(OutlinedInput, {
id: 'groupDescription',
onChange: (e) => onChangeValue({ key: 'desc', value: e.currentTarget.value }),
value: group.desc,
fullWidth: true,
autoFocus: isEdit,
inputProps: { maxLength: GROUP_DESCRIPTION_MAX_LENGTH },
disabled: group.externallyManaged
})
),
!group.externallyManaged &&
React.createElement(
'div',
{ className: classes.formActions },
isEdit &&
React.createElement(
SecondaryButton,
{ disabled: !isDirty || isSubmitting, onClick: onCancel },
React.createElement(FormattedMessage, { id: 'words.cancel', defaultMessage: 'Cancel' })
),
React.createElement(
PrimaryButton,
{ disabled: !submitOk, loading: isSubmitting, type: 'submit' },
React.createElement(FormattedMessage, { id: 'words.save', defaultMessage: 'Save' })
)
)
)
),
React.createElement(Divider, null),
React.createElement(
'section',
{ className: classes.section },
isEdit
? users &&
members &&
React.createElement(
React.Fragment,
null,
React.createElement(
Typography,
{ variant: 'subtitle1', className: classes.sectionTitleEdit },
React.createElement(FormattedMessage, {
id: 'editGroupDialog.groupMembers',
defaultMessage: 'Group Members'
})
),
React.createElement(TransferList, {
disabled: group.externallyManaged,
inProgressIds: inProgressIds,
source: {
title: React.createElement(FormattedMessage, { id: 'words.users', defaultMessage: 'Users' }),
items: sourceItems,
filterKeyword: sourceFilterKeyword,
setFilterKeyword: setSourceFilterKeyword,
disabledItems: membersLookup,
emptyStateMessage: React.createElement(FormattedMessage, {
id: 'transferList.noResults',
defaultMessage: 'No results, try to change the query'
}),
onItemClick: onItemClicked,
checkedList,
inProgressIds,
isAllChecked: sourceItemsAllChecked,
onCheckAllClicked: (items, checked) => {
onCheckAllClicked(excludeCommonItems(items, targetItems), checked);
},
onFilter: onFilterUsers,
onFetchMore: onFetchMoreUsers,
hasMoreItems: hasMoreUsers
},
target: {
title: React.createElement(FormattedMessage, { id: 'words.members', defaultMessage: 'Members' }),
items: filteredTargetItems,
filterKeyword: targetFilterKeyword,
setFilterKeyword: setTargetFilterKeyword,
emptyStateMessage: React.createElement(FormattedMessage, {
id: 'transferList.targetEmptyStateMessage',
defaultMessage: 'No members on this group'
}),
onItemClick: onItemClicked,
checkedList,
inProgressIds,
isAllChecked: targetItemsAllChecked,
onCheckAllClicked
},
disableAdd: disableAddMembers,
disableRemove: disableRemove,
addToTarget: onAddMembers,
removeFromTarget: onRemoveMembers
})
)
: React.createElement(
Box,
{ display: 'flex', justifyContent: 'center' },
React.createElement(
Typography,
{ variant: 'subtitle2', color: 'textSecondary' },
React.createElement(FormattedMessage, {
id: 'editGroupDialog.groupMemberHelperText',
defaultMessage: 'Group members are editable after creation'
})
)
)
)
)
);
}
export default EditGroupDialogUI;