Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ SENSENET_DEV_PORT=3000
# Development Settings (for hot reload)
CHOKIDAR_USEPOLLING=true
WATCHPACK_POLLING=true
DISABLE_VIEW_OPTIONS_MENU=false
WEBPACK_DEV_SERVER_CLIENT_WEB_SOCKET_URL=auto://0.0.0.0:0/ws

# Database Settings (if using database service)
# DB_PASSWORD=YourPassword123!
Expand All @@ -28,4 +30,4 @@ WATCHPACK_POLLING=true

# Backend API URL (if connecting to external backend)
# REACT_APP_SERVICE_URL=https://dev.demo.sensenet.com
# REACT_APP_IDENTITY_SERVER_URL=https://is.demo.sensenet.com
# REACT_APP_IDENTITY_SERVER_URL=https://is.demo.sensenet.com
128 changes: 100 additions & 28 deletions apps/sensenet/src/components/ContentBreadcrumbs.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,71 @@
import { createStyles, makeStyles } from '@material-ui/core'
import { Button, createStyles, IconButton, makeStyles, Tooltip } from '@material-ui/core'
import ArrowUpward from '@material-ui/icons/ArrowUpward'
import { GenericContent } from '@sensenet/default-content-types'
import { CurrentAncestorsContext, CurrentContentContext, useRepository } from '@sensenet/hooks-react'
import React, { useContext } from 'react'
import { useHistory } from 'react-router-dom'
import { ResponsivePersonalSettings } from '../context'
import { ResponsiveContext, ResponsivePersonalSettings } from '../context'
import { useSelectionService } from '../hooks'
import { getPrimaryActionUrl } from '../services'
import { BatchActions } from './BatchActions'
import { BreadcrumbItem, Breadcrumbs } from './Breadcrumbs'
import CopyPath from './CopyPath'

const useStyles = makeStyles(() => {
const useStyles = makeStyles((theme) => {
return createStyles({
buttonsWrapper: {
display: 'flex',
alignItems: 'center',
width: '100%',
minWidth: 0,
marginLeft: '10px',
overflow: 'hidden',
[theme.breakpoints.down('sm')]: {
marginLeft: 0,
width: '100%',
},
},
desktopBreadcrumbs: {
display: 'flex',
alignItems: 'center',
minWidth: 0,
overflow: 'hidden',
[theme.breakpoints.down('sm')]: {
display: 'none',
},
},
mobileLocation: {
display: 'none',
[theme.breakpoints.down('sm')]: {
display: 'flex',
alignItems: 'center',
minWidth: 0,
flex: '1 1 auto',
},
},
mobileLocationButton: {
minWidth: 0,
maxWidth: '100%',
paddingLeft: 4,
paddingRight: 4,
textTransform: 'none',
justifyContent: 'flex-start',
overflow: 'hidden',
'& .MuiButton-label': {
display: 'block',
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
},
},
mobileUpButton: {
flex: '0 0 auto',
padding: 6,
},
breadcrumbsArea: {
display: 'flex',
alignItems: 'center',
flex: '1 1 auto',
minWidth: 0,
overflow: 'hidden',
},
Expand Down Expand Up @@ -53,35 +97,63 @@ export const ContentBreadcrumbs = <T extends GenericContent = GenericContent>(pr
const { location } = history
const classes = useStyles()
const selectionService = useSelectionService()
const device = useContext(ResponsiveContext)

const items = [
...ancestors.map((content) => ({
displayName: content.DisplayName || content.Name,
title: content.Path,
url: getPrimaryActionUrl({ content, repository, uiSettings, location }),
content,
})),
{
displayName: parent.DisplayName || parent.Name,
title: parent.Path,
url: getPrimaryActionUrl({ content: parent, repository, uiSettings, location }),
content: parent,
},
]

const handleItemClick = (item: BreadcrumbItem<T>) => {
selectionService.activeContent.setValue(item.content)
props.onItemClick
? props.onItemClick(item)
: history.push(getPrimaryActionUrl({ content: item.content, repository, uiSettings, location }))
}

const parentItem = items[items.length - 1]
const ancestorItem = items[items.length - 2]

return (
<div className={classes.buttonsWrapper}>
<div className={classes.breadcrumbsArea}>
<div className={classes.copyPathArea}>
<CopyPath copyText={parent.Path} />
</div>
<Breadcrumbs<T>
items={[
...ancestors.map((content) => ({
displayName: content.DisplayName || content.Name,
title: content.Path,
url: getPrimaryActionUrl({ content, repository, uiSettings, location }),
content,
})),
{
displayName: parent.DisplayName || parent.Name,
title: parent.Path,
url: getPrimaryActionUrl({ content: parent, repository, uiSettings, location }),
content: parent,
},
]}
onItemClick={(_ev, item) => {
selectionService.activeContent.setValue(item.content)
props.onItemClick
? props.onItemClick(item)
: history.push(getPrimaryActionUrl({ content: item.content, repository, uiSettings, location }))
}}
/>
{device === 'mobile' ? (
<div className={classes.mobileLocation}>
{ancestorItem ? (
<Tooltip title={ancestorItem.title} placement="bottom">
<IconButton
className={classes.mobileUpButton}
aria-label="Go up"
size="small"
onClick={() => handleItemClick(ancestorItem)}>
<ArrowUpward fontSize="small" />
</IconButton>
</Tooltip>
) : null}
<Tooltip title={parentItem.title} placement="bottom">
<Button className={classes.mobileLocationButton} aria-label={parentItem.displayName}>
{parentItem.displayName}
</Button>
</Tooltip>
</div>
) : (
<div className={classes.desktopBreadcrumbs}>
<div className={classes.copyPathArea}>
<CopyPath copyText={parent.Path} />
</div>
<Breadcrumbs<T> items={items} onItemClick={(_ev, item) => handleItemClick(item)} />
</div>
)}
</div>
{props.batchActions && (
<div className={classes.actionsArea}>
Expand Down
26 changes: 23 additions & 3 deletions apps/sensenet/src/components/appbar/desktop-app-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { clsx } from 'clsx'
import React, { useContext, useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import logo from '../../assets/sensenet_white.png'
import { ResponsivePersonalSettings } from '../../context'
import { ResponsiveContext, ResponsivePersonalSettings } from '../../context'
import { globals, useGlobalStyles } from '../../globalStyles'
import { CommandPalette } from '../command-palette/CommandPalette'
import { DesktopNavMenu } from './desktop-nav-menu'

const useStyles = makeStyles(() => {
const useStyles = makeStyles((theme) => {
return createStyles({
appBar: {
position: 'relative',
Expand All @@ -25,9 +25,20 @@ const useStyles = makeStyles(() => {
minHeight: '42px',
paddingLeft: '6px',
paddingRight: 0,
[theme.breakpoints.down('sm')]: {
paddingLeft: '2px',
},
},
logo: {
marginRight: '21px',
[theme.breakpoints.down('sm')]: {
marginRight: '4px',
},
},
drawerButton: {
padding: '8px',
marginRight: '2px',
flex: '0 0 auto',
},
commandPaletteReplacement: {
flex: 1,
Expand All @@ -38,9 +49,16 @@ const useStyles = makeStyles(() => {
fontSize: '18px',
fontWeight: 500,
fontFamily: 'Roboto,Helvetica,Arial,sans-serif',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
maxWidth: '36vw',
'&:hover': {
cursor: 'pointer',
},
[theme.breakpoints.down('sm')]: {
display: 'none',
},
},
})
})
Expand All @@ -49,6 +67,7 @@ const PORTAL_SETTING_PATH = '/Root/System/Settings/Portal.settings'

export const DesktopAppBar: React.FunctionComponent<{ openDrawer?: () => void }> = (props) => {
const personalSettings = useContext(ResponsivePersonalSettings)
const device = useContext(ResponsiveContext)
const classes = useStyles()
const globalClasses = useGlobalStyles()
const repository = useRepository()
Expand Down Expand Up @@ -110,8 +129,9 @@ export const DesktopAppBar: React.FunctionComponent<{ openDrawer?: () => void }>
<Link to="/" className={`${globalClasses.centeredVertical} ${classes.logo}`}>
<img src={logo} alt="logo" data-test="sensenet-logo" width="29" height="32" />
</Link>
{personalSettings.drawer.type === 'temporary' ? (
{personalSettings.drawer.enabled && (personalSettings.drawer.type === 'temporary' || device === 'mobile') ? (
<IconButton
className={classes.drawerButton}
onClick={() => {
props.openDrawer && props.openDrawer()
}}>
Expand Down
34 changes: 25 additions & 9 deletions apps/sensenet/src/components/appbar/desktop-nav-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,24 @@ const useStyles = makeStyles((theme: Theme) =>
cursor: 'pointer',
marginRight: '16px',
padding: '7px',
[theme.breakpoints.down('sm')]: {
marginRight: '6px',
},
},
navMenu: {
height: '100%',
width: '140px',
background: theme.palette.background.default,
flex: '0 0 auto',
[theme.breakpoints.down('sm')]: {
width: '112px',
},
},
navMenuCompact: {
width: '76px',
[theme.breakpoints.down('sm')]: {
width: '70px',
},
},
paper: {
marginRight: theme.spacing(2),
Expand Down Expand Up @@ -77,6 +90,7 @@ const useStyles = makeStyles((theme: Theme) =>
)

export const DesktopNavMenu: FunctionComponent = () => {
const isViewOptionsMenuDisabled = process.env.DISABLE_VIEW_OPTIONS_MENU === 'true'
const personalSettings = usePersonalSettings()
const injector = useInjector()
const classes = useStyles()
Expand Down Expand Up @@ -134,15 +148,17 @@ export const DesktopNavMenu: FunctionComponent = () => {
}

return (
<div className={clsx(globalClasses.centered, classes.navMenu)}>
<div className={clsx(globalClasses.centered, classes.navMenu, isViewOptionsMenuDisabled && classes.navMenuCompact)}>
<>
<IconButton
aria-label={localization.topMenu.openViewOptions}
aria-controls={openViewOptions ? 'menu-list-grow' : undefined}
className={classes.viewOptions}
onClick={() => handleToggle(setOpenViewOptions)}>
<TuneOutlined />
</IconButton>
{!isViewOptionsMenuDisabled ? (
<IconButton
aria-label={localization.topMenu.openViewOptions}
aria-controls={openViewOptions ? 'menu-list-grow' : undefined}
className={classes.viewOptions}
onClick={() => handleToggle(setOpenViewOptions)}>
<TuneOutlined />
</IconButton>
) : null}
<UserAvatar
user={user!}
repositoryUrl={repo.configuration.repositoryUrl}
Expand Down Expand Up @@ -231,7 +247,7 @@ export const DesktopNavMenu: FunctionComponent = () => {
</div>
</Paper>
) : null}
{openViewOptions ? (
{!isViewOptionsMenuDisabled && openViewOptions ? (
<Paper className={classes.popperViewWrapper}>
<div className={classes.popper}>
<ClickAwayListener onClickAway={() => handleClose(setOpenViewOptions)}>
Expand Down
Loading
Loading