UNPKG

@craftercms/studio-ui

Version:

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

194 lines (192 loc) 8.12 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 { FormattedMessage } from 'react-intl'; import { useStyles } from './styles'; import PathNavigatorHeader from './PathNavigatorHeader'; import Breadcrumbs from './PathNavigatorBreadcrumbs'; import PathNavigatorItem from './PathNavigatorItem'; import PathNavigatorList from './PathNavigatorList'; import Accordion from '@mui/material/Accordion'; import AccordionDetails from '@mui/material/AccordionDetails'; import { lookupItemByPath } from '../../utils/content'; import RefreshRounded from '@mui/icons-material/RefreshRounded'; import PathNavigatorSkeletonList from './PathNavigatorSkeletonList'; import { ErrorState } from '../ErrorState'; import { renderErrorState } from '../ErrorState/util'; import { Pagination } from '../Pagination'; import Box from '@mui/material/Box'; export function PathNavigatorUI(props) { const { classes, cx: clsx } = useStyles(); // region consts {...} = props const { state, itemsByPath, icon, container, title, onChangeCollapsed, onHeaderButtonClick, onCurrentParentMenu, onSearch, keyword, onBreadcrumbSelected, onSelectItem, onPathSelected, onPreview, onOpenItemMenu, onItemClicked, onPageChanged, computeActiveItems, onRowsPerPageChange } = props; // endregion const items = state.itemsInPath?.flatMap((path) => lookupItemByPath(path, itemsByPath) ?? []) ?? []; const levelDescriptor = itemsByPath[state.levelDescriptor]; return React.createElement( Accordion, { square: true, disableGutters: true, elevation: 0, TransitionProps: { unmountOnExit: true }, expanded: !state.collapsed, onChange: () => onChangeCollapsed(!state.collapsed), className: clsx( classes.accordion, props.classes?.root, container?.baseClass, container ? (state.collapsed ? container.collapsedClass : container.expandedClass) : void 0 ), style: { ...container?.baseStyle, ...(container ? (state.collapsed ? container.collapsedStyle : container.expandedStyle) : void 0) } }, React.createElement(PathNavigatorHeader, { icon: icon, title: title, locale: state.localeCode, // @see https://github.com/craftercms/craftercms/issues/5360 menuButtonIcon: React.createElement(RefreshRounded, null), onMenuButtonClick: onHeaderButtonClick ? (anchor) => onHeaderButtonClick(anchor, 'options') : null, collapsed: state.collapsed }), React.createElement( AccordionDetails, { className: clsx(classes.accordionDetails, props.classes?.body) }, state.isRootPathMissing ? React.createElement(ErrorState, { styles: { image: { display: 'none' } }, title: React.createElement(FormattedMessage, { id: 'pathNavigatorTree.missingRootPath', defaultMessage: `The path "{path}" doesn't exist`, values: { path: state.rootPath } }) }) : React.createElement( React.Fragment, null, React.createElement(Breadcrumbs, { keyword: keyword, breadcrumb: state.breadcrumb.map((path) => lookupItemByPath(path, itemsByPath)).filter(Boolean), onSearch: onSearch, onCrumbSelected: onBreadcrumbSelected, classes: { root: props.classes?.breadcrumbsRoot, searchRoot: props.classes?.breadcrumbsSearch } }), lookupItemByPath(state.currentPath, itemsByPath) && React.createElement(PathNavigatorItem, { item: lookupItemByPath(state.currentPath, itemsByPath), locale: state.localeCode, isLevelDescriptor: false, onOpenItemMenu: onCurrentParentMenu, onItemClicked: onItemClicked, showItemNavigateToButton: false, isCurrentPath: true }), state.isFetching ? React.createElement(PathNavigatorSkeletonList, { numOfItems: state.itemsInPath?.length > 0 ? state.itemsInPath.length : state.limit }) : state.error ? renderErrorState(state.error, { imageUrl: null }) : state.itemsInPath.length === 0 && !Boolean(levelDescriptor) ? React.createElement( Box, { display: 'flex', justifyContent: 'center', m: 1 }, React.createElement(FormattedMessage, { id: 'pathNavigator.noItemsAtLocation', defaultMessage: 'No items at this location' }) ) : React.createElement( React.Fragment, null, levelDescriptor && React.createElement(PathNavigatorItem, { item: levelDescriptor, locale: state.localeCode, isLevelDescriptor: true, onOpenItemMenu: onOpenItemMenu, onItemClicked: onItemClicked }), React.createElement(PathNavigatorList, { classes: { root: classes.childrenList }, isSelectMode: false, locale: state.localeCode, items: items, onSelectItem: onSelectItem, onPathSelected: onPathSelected, onPreview: onPreview, onOpenItemMenu: onOpenItemMenu, onItemClicked: onItemClicked, computeActiveItems: computeActiveItems }) ), state.total !== null && state.total > 0 && !(state.total === 1 && state.levelDescriptor) && React.createElement(Pagination, { showBottomBorder: true, classes: { root: props.classes?.paginationRoot }, // Do not consider levelDescriptor in pagination, as it will always be rendered at the beginning of the // PathNav view, indistinctly of the current page. count: state.levelDescriptor ? state.total - 1 : state.total, rowsPerPage: state.limit, page: state && Math.ceil(state.offset / state.limit), onRowsPerPageChange: onRowsPerPageChange, onPageChange: (e, page) => onPageChanged(page) }) ) ) ); } export default PathNavigatorUI;