UNPKG

@craftercms/studio-ui

Version:

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

151 lines (149 loc) 5.27 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 { defineMessages, useIntl } from 'react-intl'; import { useDispatch } from 'react-redux'; import React, { useEffect, useState } from 'react'; import { closePathSelectionDialog, pathSelectionDialogClosed, showPathSelectionDialog } from '../../state/actions/dialogs'; import { batchActions, dispatchDOMEvent } from '../../state/actions/misc'; import InputBase from '@mui/material/InputBase'; import IconButton from '@mui/material/IconButton'; import CloseIcon from '@mui/icons-material/Close'; import { makeStyles } from 'tss-react/mui'; import Paper from '@mui/material/Paper'; import SiteExplorer from '../../icons/SiteExplorer'; import { createCustomDocumentEventListener } from '../../utils/dom'; const useStyles = makeStyles()((theme) => ({ pathSelectorInputRoot: { flexGrow: 1 }, pathSelectorWrapper: { flex: 1, minHeight: 40, display: 'flex', cursor: 'pointer', padding: '0 0 0 10px', '&:hover:not(.disabled)': { borderColor: theme.palette.action.active }, '&.disabled': { opacity: 0.7, cursor: 'default' } }, invisibleInput: { border: 0, padding: '0 0 0 5px', height: '100%', cursor: 'pointer', background: 'none', '&:focus': { borderColor: 'none', boxShadow: 'inherit' }, '&:disabled': { cursor: 'default' } } })); const messages = defineMessages({ searchIn: { id: 'pathSelector.inputPlaceholderText', defaultMessage: 'Select path' } }); export function PathSelector(props) { const { onPathSelected, value, disabled = false, stripXmlIndex = true, rootPath } = props; const { formatMessage } = useIntl(); const dispatch = useDispatch(); const { classes, cx } = useStyles(); const [path, setPath] = useState(value !== null && value !== void 0 ? value : ''); useEffect(() => { setPath(value !== null && value !== void 0 ? value : ''); }, [value]); const onClean = (e) => { e.stopPropagation(); e.preventDefault(); let cleanPath = rootPath !== null && rootPath !== void 0 ? rootPath : ''; setPath(cleanPath); onPathSelected(cleanPath); }; const onOpenPathSelectionDialog = () => { var _a; const callbackId = 'pathSelectionDialogCallback'; const callbackAccept = 'accept'; dispatch( showPathSelectionDialog({ rootPath: rootPath !== null && rootPath !== void 0 ? rootPath : `/${(_a = path.split('/')[1]) !== null && _a !== void 0 ? _a : ''}`, initialPath: path, showCreateFolderOption: false, allowSwitchingRootPath: !Boolean(rootPath), stripXmlIndex, onClosed: batchActions([dispatchDOMEvent({ id: callbackId, action: 'close' }), pathSelectionDialogClosed()]), onOk: batchActions([dispatchDOMEvent({ id: callbackId, action: callbackAccept }), closePathSelectionDialog()]) }) ); createCustomDocumentEventListener(callbackId, (detail) => { if (detail.action === callbackAccept) { const path = detail.path; setPath(path); onPathSelected(path); } }); }; return React.createElement( Paper, { variant: 'outlined', onClick: disabled ? null : onOpenPathSelectionDialog, className: cx(classes.pathSelectorWrapper, disabled && 'disabled') }, React.createElement(InputBase, { classes: { root: classes.pathSelectorInputRoot, input: classes.invisibleInput }, disabled: disabled, readOnly: true, value: path, placeholder: formatMessage(messages.searchIn), startAdornment: disabled ? null : React.createElement(SiteExplorer, { sx: { color: 'text.secondary' } }), endAdornment: !disabled && value ? React.createElement(IconButton, { onClick: onClean, size: 'small' }, React.createElement(CloseIcon, null)) : null }) ); } export default PathSelector;