UNPKG

@craftercms/studio-ui

Version:

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

318 lines (316 loc) 11.6 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 useStyles from './styles'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import React, { useCallback, useMemo, useState } from 'react'; import ClearRoundedIcon from '@mui/icons-material/ClearRounded'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { AdapterMoment as DateAdapter } from '@mui/x-date-pickers/AdapterMoment'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import Tooltip from '@mui/material/Tooltip'; import IconButton from '@mui/material/IconButton'; import moment from 'moment-timezone'; import { useDebouncedInput } from '../../hooks/useDebouncedInput'; const translations = defineMessages({ siteId: { id: 'auditGridFilterPopover.filterBySite', defaultMessage: 'Filter by Project' }, user: { id: 'auditGridFilterPopover.filterByUser', defaultMessage: 'Filter by User' }, origin: { id: 'auditGridFilterPopover.filterByOrigin', defaultMessage: 'Filter by Origin' }, operations: { id: 'auditGridFilterPopover.filterByOperations', defaultMessage: 'Filter by Operations' }, target: { id: 'auditGridFilterPopover.filterByTarget', defaultMessage: 'Filter by Target Value' }, allOperations: { id: 'auditGridFilterPopover.allOperations', defaultMessage: 'All Operations' } }); export function AuditGridFilterPopoverBody(props) { var _a, _b; const { filterId, value, onFilterChange, timezone, onTimezoneSelected, onResetFilter, onClose } = props; const { classes } = useStyles(); const { sites, users, operations, origins, timezones } = props.options; const { formatMessage } = useIntl(); const [keyword, setKeyword] = useState((_a = props.value) !== null && _a !== void 0 ? _a : ''); const [fromDate, setFromDate] = useState(props.dateFrom ? moment(props.dateFrom) : null); const [toDate, setToDate] = useState(props.dateTo ? moment(props.dateTo) : null); const onSearch = useCallback((keywords) => onFilterChange(filterId, keywords), [onFilterChange, filterId]); const onSearch$ = useDebouncedInput(onSearch, 400); const options = useMemo(() => { switch (filterId) { case 'siteId': { return [ { id: 'all', value: 'all', name: React.createElement(FormattedMessage, { id: 'auditGrid.allSites', defaultMessage: 'All Projects' }) }, { id: 'studio_root', value: 'studio_root', name: React.createElement(FormattedMessage, { id: 'words.system', defaultMessage: 'System' }) }, ...sites.map((site) => ({ id: site.id, name: site.name, value: site.id })) ]; } case 'user': { return [ { id: 'all', value: 'all', name: React.createElement(FormattedMessage, { id: 'auditGrid.allUsers', defaultMessage: 'All Users' }) }, ...users.map((user) => ({ id: user.id.toString(), name: user.username, value: user.username })) ]; } case 'origin': { return [ { id: 'all', value: 'all', name: React.createElement(FormattedMessage, { id: 'auditGrid.allOrigins', defaultMessage: 'All Origins' }) }, ...origins ]; } case 'operations': { return [ { id: 'all', value: 'all', name: formatMessage(translations.allOperations) }, ...operations ]; } } }, [filterId, formatMessage, operations, origins, sites, users]); const onTextFieldChanges = (e) => { onSearch$.next(e.target.value); setKeyword(e.target.value); }; const onMultipleSelectChanges = (e) => { const lastString = e.target.value[e.target.value.length - 1]; if (lastString === 'all' || e.target.value.length === 0) { onFilterChange(filterId, 'all'); } else { const values = e.target.value.filter((value) => value !== 'all'); onFilterChange(filterId, values.join()); } }; const onFromDateSelected = (date) => { if (date.isValid()) { onFilterChange('dateFrom', (date === null || date === void 0 ? void 0 : date.format()) || 'all'); } setFromDate(date); }; const onToDateSelected = (date) => { if (date.isValid()) { onFilterChange('dateTo', (date === null || date === void 0 ? void 0 : date.format()) || 'all'); } setToDate(date); }; const onClearDates = () => { setToDate(null); setFromDate(null); onResetFilter(['dateFrom', 'dateTo']); }; const onClearTextField = () => { onResetFilter(filterId); setKeyword(''); }; return React.createElement( React.Fragment, null, React.createElement( Box, { display: 'flex', justifyContent: 'end', marginBottom: '10px' }, React.createElement( IconButton, { onClick: onClose }, React.createElement(ClearRoundedIcon, { fontSize: 'small' }) ) ), filterId === 'operationTimestamp' && React.createElement( LocalizationProvider, { dateAdapter: DateAdapter }, React.createElement( 'form', { noValidate: true, autoComplete: 'off' }, React.createElement( Box, { className: classes.timestampFiltersContainer }, React.createElement(DateTimePicker, { label: React.createElement(FormattedMessage, { id: 'words.from', defaultMessage: 'From' }), value: fromDate, onChange: onFromDateSelected, renderInput: (props) => React.createElement(TextField, Object.assign({}, props)) }), React.createElement(DateTimePicker, { label: React.createElement(FormattedMessage, { id: 'words.to', defaultMessage: 'To' }), value: toDate, onChange: onToDateSelected, renderInput: (props) => React.createElement(TextField, Object.assign({}, props)) }), React.createElement( Button, { className: classes.clearButton, disabled: !toDate && !fromDate, variant: 'text', color: 'primary', onClick: () => onClearDates() }, React.createElement(FormattedMessage, { id: 'words.clear', defaultMessage: 'Clear' }) ) ), React.createElement(Autocomplete, { disableClearable: true, options: timezones, getOptionLabel: (option) => option, value: timezone, onChange: (e, value) => { onTimezoneSelected(value); }, fullWidth: true, renderInput: (params) => React.createElement( TextField, Object.assign({}, params, { label: React.createElement(FormattedMessage, { id: 'auditGrid.timezone', defaultMessage: 'Timezone' }), variant: 'outlined' }) ) }) ) ), ['siteId', 'user', 'origin'].includes(filterId) && React.createElement( Box, { display: 'flex', alignItems: 'center' }, React.createElement( TextField, { fullWidth: true, select: true, label: formatMessage(translations[filterId]), value: value ? value : 'all', onChange: (e) => onFilterChange(filterId, e.target.value) }, options.map((option) => React.createElement(MenuItem, { key: option.id, value: option.value }, option.name)) ), React.createElement( Button, { className: classes.clearButton, disabled: !value, variant: 'text', color: 'primary', onClick: () => onResetFilter(filterId) }, React.createElement(FormattedMessage, { id: 'words.clear', defaultMessage: 'Clear' }) ) ), filterId === 'operations' && React.createElement( Box, { display: 'flex', alignItems: 'center' }, React.createElement( TextField, { fullWidth: true, select: true, label: formatMessage(translations[filterId]), value: (_b = value === null || value === void 0 ? void 0 : value.split(',')) !== null && _b !== void 0 ? _b : ['all'], SelectProps: { multiple: true }, onChange: onMultipleSelectChanges }, options.map((option) => React.createElement(MenuItem, { key: option.id, value: option.value }, option.name)) ), React.createElement( Button, { className: classes.clearButton, disabled: !value, variant: 'text', color: 'primary', onClick: () => onResetFilter(filterId) }, React.createElement(FormattedMessage, { id: 'words.clear', defaultMessage: 'Clear' }) ) ), 'target' === filterId && React.createElement(TextField, { value: keyword, label: formatMessage(translations[filterId]), InputProps: { endAdornment: keyword && React.createElement( Tooltip, { title: React.createElement(FormattedMessage, { id: 'words.clear', defaultMessage: 'Clear' }) }, React.createElement( IconButton, { size: 'small', className: classes.clearButton, onClick: () => onClearTextField() }, React.createElement(ClearRoundedIcon, null) ) ) }, fullWidth: true, onChange: onTextFieldChanges }) ); } export default AuditGridFilterPopoverBody;