UNPKG

@craftercms/studio-ui

Version:

Services, components, models & utils to build CrafterCMS authoring extensions.

351 lines (349 loc) 13.3 kB
/* * 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;